avaScript運(yùn)行網(wǎng)絡(luò)。您可以在瀏覽器中使用它,也可以在服務(wù)器上使用它,并且可以將其用于移動應(yīng)用程序。
當(dāng)今的生態(tài)系統(tǒng)充滿了強(qiáng)大的庫和框架,可幫助工程師為任何平臺構(gòu)建功能強(qiáng)大,以用戶為中心的應(yīng)用程序。
甚至在Covid-19大流行之前,數(shù)據(jù)可視化就成為當(dāng)今世界上最熱門的話題之一。公司擁有大量數(shù)據(jù),需要找到分析,解釋和可視化數(shù)據(jù)的方法。
無論你是數(shù)據(jù)科學(xué)家還是必須處理數(shù)據(jù)可視化的程序員,今天分享7個(gè)非常棒的JavaScript框架可幫助你創(chuàng)建出色的解決方案。
地址:https://github.com/d3/d3
D3目前在GitHub上擁有90,000個(gè)star,使其成為可用的最受歡迎的JavaScript庫之一。這是一個(gè)了不起的庫,用于使用Web標(biāo)準(zhǔn)(SVG,Canvas,HTML)使用JavaScript可視化數(shù)據(jù)。它結(jié)合了強(qiáng)大的交互和可視化技術(shù),以數(shù)據(jù)驅(qū)動的方式來操作DOM。
它允許將任意數(shù)據(jù)綁定到DOM,然后將其轉(zhuǎn)換應(yīng)用于文檔。
主要特征:
地址:https://github.com/mrdoob/three.js
three.js是另一個(gè)用于數(shù)據(jù)可視化的很棒的JavaScript庫,目前有大約60,000個(gè)GitHub star。它希望使用默認(rèn)的WebGL渲染器創(chuàng)建一個(gè)易于使用,簡單且輕巧的3D庫。
主要特征:
Chart.js是面向設(shè)計(jì)人員和開發(fā)人員的簡單但靈活的JavaScript圖表庫,目前在GitHub上擁有約50,000 star。它具有出色的文檔,并且很容易入門。
主要特征:
Paper.js是一個(gè)運(yùn)行在HTML5 Canvas頂部的開源矢量圖形腳本框架。它提供了許多強(qiáng)大的功能來創(chuàng)建和使用貝塞爾曲線和矢量圖形。它基于Scriptographer,這是Adobe Illustrator的腳本環(huán)境。Paper.js對于初學(xué)者來說很容易學(xué)習(xí),但對于高級用戶也有很多高級功能。
主要特征:
Fabric.js是一個(gè)很棒的JavaScript框架,可輕松使用HTML canvas元素。它在canvas元素的頂部有一個(gè)交互式對象模型,還有一個(gè)SVG到畫布的解析器。
使用Fabric,您可以使用JavaScript輕松創(chuàng)建簡單的形狀,例如圓形,三角形,矩形或其他多邊形。
主要特征:
ECharts是一個(gè)功能強(qiáng)大的JavaScript可視化和圖表庫,它提供了向應(yīng)用程序添加交互式,直觀且高度可自定義的圖表的簡便方法,目前在GitHub上約有40,000星。它基于ZRender并用純JavaScript編寫。
主要特征:
Two.js是在現(xiàn)代瀏覽器中用于二維繪圖的小型API。它與渲染器無關(guān),可使用相同的API在多個(gè)上下文(例如WebGL,Canvas2D或SVG)中進(jìn)行渲染。
主要特征:
最后送福利了,自己是從事了五年的前端工程師,整理了一份最全面前端學(xué)習(xí)資料,只要私信:“前端"等3秒后即可獲取地址,里面概括應(yīng)用網(wǎng)站開發(fā),css,html,JavaScript,jQuery,Vue、Ajax,node,angular等。等多個(gè)知識點(diǎn)高級進(jìn)階干貨的相關(guān)視頻資料,等你來拿
我真的希望您喜歡這些庫,并且可以在您的一個(gè)項(xiàng)目中使用它們!
上回我們說到如何使用JavaScript配合Canvas技術(shù)實(shí)現(xiàn)交互功能,本片文章我們要來講講Canvas技術(shù)中的線條。由于它的英文名稱叫做Path,所以更準(zhǔn)確地應(yīng)該叫做路徑,不過其實(shí)就是線條。
Canvas技術(shù)能繪制的路徑主要由直線、弧線和貝塞爾曲線構(gòu)成。在畫路徑之前,需要調(diào)用上下文對象的beginPath()方法,結(jié)束路徑的繪制需要調(diào)用上下文對象的closePath()方法,否則調(diào)用clearRect()方法時(shí),這條路徑將不會被刪除。所有的畫路徑的操作都需要在這兩行代碼之中。從beginPath()到closePath()繪制的圖形稱為一條路徑。
I. 直線
調(diào)用上下文對象的moveTo()方法,將畫筆移動到該坐標(biāo),lineTo()將以直線方式設(shè)置線條的第二個(gè)點(diǎn),上下文對象的stroke()方法,將會把該條路徑中所有的點(diǎn)都按指定的方式來連接,例如以下代碼就是先將畫筆移動到(0,0)坐標(biāo)處,然后按直線方式設(shè)置接下來的一個(gè)點(diǎn)(30,30),其次把這兩個(gè)點(diǎn)按直線方式連接起來,所以最終效果就是繪制一條斜著的直線:
我們可以修改我們上回程序中的代碼,看看這些代碼的效果。
通過設(shè)置上下文對象的strokeStyle和lineWidth屬性可以設(shè)置線條的顏色和寬度,例如:
這段代碼就設(shè)置了線條顏色為橘色、線條寬度為5像素。
通過直線,我們可以畫出三角形、矩形和多邊形。這里以三角形為例,我們只要指定三個(gè)能夠成三角形的頂點(diǎn),然后按直線方式連接起來即可,例如:
我們從(0,0)開始,繪制直線到(30,30),然后繪制直線到(30,0),然后在繪制直線回到起點(diǎn),這就構(gòu)成了一個(gè)三角形,這個(gè)三角形構(gòu)成了一個(gè)封閉圖形,構(gòu)成封閉圖形的路徑可以使用上下文對象的fill()方法來對圖形的內(nèi)部進(jìn)行填充,例如:
II. 弧線
弧線最大的用處莫過于畫圓、扇形和圓角矩形了。首先,我們來介紹一下上下文對象的arc()函數(shù)。該函數(shù)用于畫弧線,它有六個(gè)參數(shù),第一、二、三個(gè)參數(shù)分別是該弧線所在圓的x、y左邊和半徑,第四和第五個(gè)參數(shù)是這個(gè)圓的起始角和結(jié)束角,單位為弧度,PI是180度,第六個(gè)參數(shù)是可選參數(shù),指定是逆時(shí)針還是順時(shí)針繪制,false代表順時(shí)針繪制,true代表逆時(shí)針繪制,默認(rèn)是順時(shí)針繪制,不過如果畫圓的話,順時(shí)針和逆時(shí)針的效果其實(shí)差不多,因?yàn)閳A無論怎么看都是一樣的。
我們知道,圓的起始角是0,結(jié)束角是2PI,所以我們可以這樣畫圓:
畫扇形,我們可以使用弧線和直線的組合,例如:
繪制圓角矩形,就要用到arcTo()函數(shù)了,它也是上下文對象的一個(gè)方法,它有五個(gè)參數(shù)分別是弧線的起點(diǎn)(兩條線的延長線的交點(diǎn))的x坐標(biāo)、y坐標(biāo),弧線的終點(diǎn)的x、y坐標(biāo)和弧線的半徑,例如以下就畫了一個(gè)圓角矩形的兩條邊和一個(gè)圓角:
再添加一些代碼,那么就可以畫出一個(gè)圓角矩形了,例如下述代碼:
III.文本
在制作文字冒險(xiǎn)類游戲或者RPG游戲的時(shí)候,總會有這樣一種需求:在圓角矩形中輸出文本,上面我們說了如何畫圓角矩形,那么如何輸出文本呢?我們可以使用上下文對象的strokeText()方法或者fillText()方法。區(qū)別就是前者繪制的是只有輪廓的文本,后者繪制的是填充的文本,例如:
就繪制了一個(gè)只有輪廓的文本,它的第一個(gè)參數(shù)是要繪制的文本,后兩個(gè)參數(shù)是這個(gè)文本左下角的x、y坐標(biāo)。和直線、弧線不同,strokeText()方法不需要放在beginPath()和closePath()之間。又如:
就繪制了一個(gè)填充文本,它的參數(shù)和strokeText()的參數(shù)是一樣的。
通過設(shè)置上下文對象的fillStyle屬性可以指定填充文本的顏色,設(shè)置strokeStyle屬性可以設(shè)置輪廓文本的顏色。通過設(shè)置上下文對象的font屬性可以設(shè)置文本的大小和字體,例如:
就設(shè)置了文本的大小為20px,字體為Arial。
關(guān)于貝塞爾曲線,敬請期待本系列的下下篇。下篇將會講述如何使用Canvas技術(shù)畫一個(gè)倒福。
盤是一個(gè)好的習(xí)慣
pointer-events:none;
https://www.runoob.com/php/php-tutorial.html
<?php echo mb_strlen($userInfo['nickname'],'utf-8') > 8 ? '...':'';?>2、最多顯示8個(gè)長度名字 <?php echo mb_substr($userInfo['nickname'],0,8,'utf-8')?>3、if循環(huán)格式 <?php if ($question['answer_num']=='6') {?> AI之星 <?php }elseif ($question['answer_num'] >='3' && $question['answer_num'] <='5') {?> AI勇士 <?php }else{?> AI學(xué)者 <?php }?>
<?php echo mb_substr($userInfo['nickname'],0,8,'utf-8')?>
<input type="hidden" name="nowtime" value="<?php echo time() ?>" >
<?php if ($question['num']=='6') {?>
明星
<?php }elseif ($question['num'] >='3' && $question['num'] <='5') {?>
勇士
<?php }else{?>
學(xué)者
<?php }?>
<?php if ($question_list) {?>
<?php foreach ($question_list as $key=> $m): ?>
<div class="swiper-slide item">
<section class="question-box" data-id="<?=$m['id']?>">
<div class="q-title"><?=$m['question']?>
</div>
<?php if ($m['answerList']) {?>
<?php foreach ($m['answerList'] as $answer_key=> $answer): ?>
<label class="radio-label">
<input type="radio" data-type="single_choice" name="<?=$m['id']?>" value="<?=$answer_key?>">
<?=$answer?>
</label>
<?php endforeach; ?>
<?php }?>
</section>
</div>
<?php endforeach; ?>
<?php }?>
//例子2
<select name="column_id" value="<?=isset($show_info['column_id']) ? $show_info['column_id'] : '0'?>">
<?php foreach($column_tree as $key=> $col) {?>
<option value="<?=$key?>" <?=($show_info['column_id']==$key) ? 'selected="selected"' : ''?>><?=$col?></option>
<?php }?>
</select>
//倒序排列
{{ loop.revindex }}
//
//微信網(wǎng)頁開發(fā)分享監(jiān)聽
<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script type="text/javascript" src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
var param=<?=$param ?>;
(function () {
wx.config({
appId: '<?=$appid ?>',
timestamp: param.timestamp,
nonceStr: param.noncestr,
signature: param.signature,
jsApiList: [
'onMenuShareTimeline',
'onMenuShareAppMessage',
'onMenuShareQQ',
'onMenuShareWeibo',
'onMenuShareQZone'
]
});
var shareContent={
"title": "title文案",
"link": "<?=site_url('knowledge/index?share_id='.$share_id);?>",
"imgUrl": "<?=site_url('/static/img/ai.png');?>",
"desc": "文案~~~"
},
$jShareWrap=$('.js_share-wrap'),
$slActiveWrap=$('.sl-active_toast-wrap'),
$questionPage=$('#question_page'),
$inviteMask=$('.invite-mask'),
succFnActive=function () {
$.ajax({
url: '/knowledge/share_ins_count',
type: 'get',
success: function (r) {
r=JSON.parse(r);
console.log(r.ret);
$jShareWrap.removeClass('show');
$slActiveWrap.text(r.msg).show();
if(r.ret==0){
$('.result-page .again-replay').removeClass('js_share_get_count');
var hreflink=$('.result-page .again-replay').attr('data-type');
console.log(hreflink);
$('.result-page .again-replay').attr('href',hreflink);
}
setTimeout(function(){
$slActiveWrap.text('').hide();
// if(r.ret==0){
// window.location.reload();
// }
},2000);
},
error: function () {
}
});
};
wx.ready(function () {
wx.onMenuShareTimeline({
title: shareContent.title,
link: shareContent.link,
imgUrl: shareContent.imgUrl,
desc: shareContent.desc,
success: function (res) {
console.log('pyq');
succFnActive();
},
cancel: function (res) {
}
});
wx.onMenuShareAppMessage({
title: shareContent.title,
link: shareContent.link,
imgUrl: shareContent.imgUrl,
desc: shareContent.desc,
success: function () {
console.log('py');
succFnActive();
}
});
wx.onMenuShareQQ({
title: shareContent.title,
link: shareContent.link,
imgUrl: shareContent.imgUrl,
desc: shareContent.desc,
success: function () {
// succFn();
}
});
wx.onMenuShareQZone({
title: shareContent.title,
link: shareContent.link,
imgUrl: shareContent.imgUrl,
desc: shareContent.desc,
success: function () {
// succFn();
}
});
});
})();
</script>
//遇見坑
1、如果生成的簽名param中的url與當(dāng)前鏈接不一致控制臺會報(bào)錯(cuò)。
2、shareContent中的圖片等保持同域名
<!-- 當(dāng)前時(shí)間戳 -->
<input type="hidden" name="nowtime" value="<?php echo time() ?>" >
//js 當(dāng)前時(shí)間大于活動結(jié)束時(shí)間
if (Number($('input[name="nowtime"]').val()) >=Math.round(new Date('2020-10-25 10:00:00').getTime()/1000)) {
$('.timeEndBox').text('活動已結(jié)束,感謝。').show();
return false;
};
html2canvas可以通過純JS對瀏覽器端進(jìn)行截屏,但截圖的精確度還有待提高,部分css不可識別,所以在canvas中不能完美呈現(xiàn)原畫面樣式
//實(shí)例
function convertToPoster() {
var $posterPageContent=$('#poster_page_content');
///這個(gè)地方只需要將useCORS設(shè)置成true,千萬不要加allowTaint:true這兩個(gè)不要同時(shí)加
html2canvas($posterPageContent[0], {useCORS: true})
.then(
function (canvas) {
var oImage=new Image();
// HTMLCanvasElement.toDataURL()
//語法:canvas.toDataURL(type, encoderOptions);
// type為圖片格式,默認(rèn)為 image/png;encoderOptions為圖片質(zhì)量,默認(rèn)為0.92
oImage.src=canvas.toDataURL('image/png', 1);
$(oImage)
.addClass('poster');
$posterPageContent
.after(oImage)
.hide();
}
);
};
<img class="copyImage" src="">
<a id="dl-hidden" style="display:none;"></a>
window.onload=function(){
var IMAGE_URL;
function takeScreenshot(){
var shareContent=document.getElementById('letter');//需要截圖的包裹的(原生的)DOM 對象
var width=shareContent.offsetWidth; //獲取dom 寬度
var height=shareContent.offsetHeight; //獲取dom 高度
var canvas=document.createElement("canvas"); //創(chuàng)建一個(gè)canvas節(jié)點(diǎn)
var scale=3; //定義任意放大倍數(shù) 支持小數(shù)
canvas.width=width * scale; //定義canvas 寬度 * 縮放
canvas.height=height * scale; //定義canvas高度 *縮放
canvas.getContext("2d").scale(scale,scale); //獲取context,設(shè)置scale
// var rect=shareContent.getBoundingClientRect();//獲取元素相對于視察的偏移量
// canvas.getContext("2d").translate(-rect.left,-rect.top);//設(shè)置context位置,值為相對于視窗的偏移量負(fù)值,讓圖片復(fù)位
var opts={
scale:scale, // 添加的scale 參數(shù)
canvas:canvas, //自定義 canvas
logging: true, //日志開關(guān)
width:width, //dom 原始寬度
height:height, //dom 原始高度
backgroundColor: 'transparent',
};
html2canvas(shareContent, opts).then(function (canvas) {
IMAGE_URL=canvas.toDataURL("image/png");
$('.copyImage').attr('src',IMAGE_URL);
})
}
function dataURLtoBlob(dataurl) {
var arr=dataurl.split(','),
mime=arr[0].match(/:(.*?);/)[1],
bstr=atob(arr[1]),
n=bstr.length,
u8arr=new Uint8Array(n)
while (n--) {
u8arr[n]=bstr.charCodeAt(n)
}
return new Blob([u8arr], { type: mime })
}
function downloadBase64(dataUrl, filename) {
var imageFile, href
// const downloadLink=document.createElement('a')
var downloadLink=document.getElementById('dl-hidden')
try {
var blob=dataURLtoBlob(dataUrl)
var href=window.URL.createObjectURL(blob)
downloadLink.download=filename
downloadLink.href=href
downloadLink.click()
} catch (err) {
} finally {
if (href) {
window.URL.revokeObjectURL(href)
}
// downloadLink.remove()
}
}
// $(".letter-title").text('木子芳小芳');
takeScreenshot();
$("#save-local").click(function(e){
downloadBase64(IMAGE_URL, 'zhengshu.png')
})
}
// 計(jì)時(shí)器
var time_share=0;
var timeStart=function () {
var hour=0;
var min=0;
var sen=0;
function showTime() {
time_share ++;
sen++;
if (sen >=60) {
min++;
sen=0;
}
if (min >=60) {
hour++;
min=0;
}
if (hour >=12) {
hour=0;
}
var dataStr="<span class='timespan'>" + (hour < 10 ? ("0" + hour) : hour) + "</span>:<span class='timespan'>" + (min < 10 ? ("0" + min) : min) + "</span>:<span class='timespan'>" + (sen < 10 ? ("0" + sen) : sen) + "</span>";
$(".vtimeShow").html(dataStr);
}
setInterval(showTime, 1000);
};
-->答題滑動的時(shí)候,執(zhí)行相關(guān)內(nèi)容可以放在一個(gè)一個(gè)方法里,尋找合適時(shí)機(jī)觸發(fā)
// 答題頁面的輪播交互
var knowledgeSwiper;
function handleStartDo() {
knowledgeSwiper=new Swiper('.js_knowledge-swiper', {
on: {
//題目滑動
slideChange: function () {
//slider的狀態(tài)判斷
if (knowledgeSwiper.isBeginning) {
$preSlider.addClass('disabled');
} else if (knowledgeSwiper.isEnd) {
$nextSlider.hide();
$submitPaper.show();
} else {
$preSlider.removeClass('disabled');
$submitPaper.hide();
$nextSlider.show();
};
$('#activeIndex').text(this.activeIndex + 1);
}
}
});
$('.js_pre-slider').off('click').on('click', function () {
knowledgeSwiper.slidePrev();
});
$('.js_next-slider').off('click').on('click', function () {
knowledgeSwiper.slideNext();
});
}; // 做題交互end
//第一步--每條數(shù)據(jù)渲染的格式
function listHtmlRender(data, orderNum) {
var htmlArr=[
'<li>',
'<span class="order">',
orderNum,
'</span>',
'<img src="' + data.headimgurl + '" class="avatar">',
'<span class="nickname">',
data.nickname,
'</span>',
'<span class="time">'
+ '用時(shí)' + data.time_share + 's' +
'</span>',
'</li>'
];
var htmlStr=htmlArr.join('');
return htmlStr;
};
//第二部ajax請求后的
for (var i=0; i < r.date.length; i++) {
orderNum++;
var listHtml=listHtmlRender(response.data[i], orderNum);
$listBoxUl.append($(listHtml));
}
*請認(rèn)真填寫需求信息,我們會在24小時(shí)內(nèi)與您取得聯(lián)系。