摘要:根據(jù)項(xiàng)目要求,要實(shí)現(xiàn)這樣一個(gè)儀表盤的效果拿到圖之后首先做一個(gè)拆分,分成幾個(gè)小模塊。其中是圓心角度數(shù),是半徑,是圓心角弧長(zhǎng)。
根據(jù)項(xiàng)目要求,要實(shí)現(xiàn)這樣一個(gè)儀表盤的效果:
拿到圖之后首先做一個(gè)拆分,分成幾個(gè)小模塊。從里往外看,首先需要一個(gè)內(nèi)環(huán)的刻度條,這個(gè)內(nèi)環(huán)刻度條由若干個(gè)點(diǎn)構(gòu)成,所以我的實(shí)現(xiàn)方式為:先畫一根線,通過循環(huán),旋轉(zhuǎn)得到一個(gè)圓形的刻度條
//innerLineNums 為刻度數(shù)量 ctx.save(); for (var i = 0; i <= $this.innerLineNums; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(80, 0); ctx.stroke(); //每個(gè)點(diǎn)的弧度,360°弧度為2π,即旋轉(zhuǎn)弧度為 2π / 75 ctx.rotate(2*Math.PI / $this.innerLineNums); } ctx.restore();
其次再是里面的長(zhǎng)刻度線,以及數(shù)字標(biāo)志,還有中間的文字
// 內(nèi)環(huán)刻度線 ctx.save(); for (var i = 0; i < 6; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(78, 0); ctx.stroke(); //每10個(gè)點(diǎn)分一個(gè)刻度,共5個(gè)刻度,旋轉(zhuǎn)角度為deg1 * 10 ctx.rotate(deg1 * 10); } ctx.restore(); //內(nèi)環(huán)刻度上面數(shù)字 ctx.save(); ctx.rotate(Math.PI / 2); for (i = 0; i < 6; i++) { ctx.fillStyle = "rgba(165,180,198, .4)"; ctx.font = "10px Microsoft yahei"; ctx.textAlign = "center"; ctx.fillText(20 * i, 0, -65); ctx.rotate(deg1 * 10); } ctx.restore(); //內(nèi)環(huán)文字 ctx.save(); ctx.rotate(210 * Math.PI / 180); ctx.fillStyle = "#000"; ctx.font = "44px Microsoft yahei"; ctx.textAlign = "center"; ctx.textBaseLine = "top"; ctx.fillText(process, 0, 10); var width = ctx.measureText(process).width; ctx.fillStyle = "#000"; ctx.font = "20px Microsoft yahei"; ctx.fillText("分", width / 2 + 10, 10);
好了,此時(shí)內(nèi)環(huán)的效果已經(jīng)有了,可以看到如下效果:
再來看外環(huán)的刻度條,外環(huán)刻度條有一個(gè)缺口,目測(cè)估算一下,算缺口為1/3,即外環(huán)的刻度線需要畫120-360°,我們這里分?jǐn)?shù)滿分為100分,從0開始,為了方便計(jì)算就給他畫50根刻度線,那么每根刻度線的角度deg1的算法為:
//弧長(zhǎng)計(jì)算公式是一個(gè)數(shù)學(xué)公式,為L(zhǎng)=n(圓心角度數(shù))× π(1)× r(半徑)/180(角度制),L=α(弧度)× r(半徑) (弧度制)。其中n是圓心角度數(shù),r是半徑,L是圓心角弧長(zhǎng)。 //整個(gè)運(yùn)動(dòng)的角度是(360-120)度,轉(zhuǎn)換成弧度就是12π/9,一共分成了50個(gè)分?jǐn)?shù)段,那么每一個(gè)分?jǐn)?shù)段就是12π/450 = 2π / 75 //如需旋轉(zhuǎn) 5 度,可規(guī)定下面的公式:5*Math.PI/180。 deg1() { return (Math.PI * 12) / (9 * this.lineNums) }
從這里我們知道了外環(huán)2/3個(gè)圓的刻度線為50根,那么內(nèi)環(huán)整個(gè)圓的刻度線innerLineNums = 50 * 3 / 2 = 75根。好了,知道角度之后還是按照之前的方法,畫一根線,然后循環(huán),在旋轉(zhuǎn),跳躍畫出灰色的外環(huán)刻度線:
// 細(xì)分內(nèi)環(huán)刻度線 ctx.save(); for (var i = 0; i <= $this.innerLineNums; i++) { ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = "rgba(155,157,183,1)"; ctx.moveTo(82, 0); ctx.lineTo(80, 0); ctx.stroke(); //每個(gè)點(diǎn)的弧度,360°弧度為2π,即旋轉(zhuǎn)弧度為 2π / 75 ctx.rotate(2 * Math.PI / $this.innerLineNums); } ctx.restore();
這個(gè)時(shí)候效果是這樣的:
還差外環(huán)的漸變線,以及線上面的那個(gè)點(diǎn),那根線是根據(jù)分?jǐn)?shù)動(dòng)態(tài)畫的,所以長(zhǎng)度需要計(jì)算,我打算用一個(gè)圓弧來實(shí)現(xiàn),上面說過每個(gè)線之間的旋轉(zhuǎn)弧度為deg1,那圓弧的長(zhǎng)度就等于score * deg1 / 2,根據(jù)公式畫出線如下:
//色彩段數(shù)與彩色刻度條保持一致,線條無間隔,所以段數(shù) * 2 var gradient = ctx.createLinearGradient(0, 0, $this.colorLineNums * 2, 0); gradient.addColorStop("0", "rgba(252,3,44,.6)"); gradient.addColorStop("0.5", "rgba(134,37,168,.6)"); gradient.addColorStop("1.0", "rgba(54,63,255,.6)"); //外環(huán)漸變線 ctx.save(); ctx.beginPath(); ctx.lineWidth = 2; ctx.strokeStyle = gradient; ctx.arc(0, 0, radius, 0, angle, false); ctx.stroke(); ctx.restore();
此時(shí)效果是這樣的:
還有圓外環(huán)彩線上面的圓點(diǎn),可以用一個(gè)小圓實(shí)現(xiàn),然后改變他的x,y坐標(biāo)即可實(shí)現(xiàn):
ctx.save(); ctx.beginPath(); ctx.fillStyle = "rgba(255, 255, 255, 1)"; ctx.arc(this.x, this.y, 5, 0, Math.PI * 2, false); ctx.fill(); ctx.lineWidth = 1; ctx.strokeStyle = "rgba(246, 5, 51, 1)"; ctx.stroke(); ctx.restore(); ctx.save(); ctx.beginPath(); ctx.fillStyle = "rgba(246, 5, 51, 1)"; ctx.arc(this.x, this.y, 3, 0, Math.PI * 2, false); ctx.fill(); ctx.restore();
此時(shí),還差個(gè)彩色的線,效果如下,額,這個(gè)彩色的線如何實(shí)現(xiàn)呢,剛開始也是不知如何下手,經(jīng)過高人指點(diǎn)后,得出結(jié)局方案:把漸變色切割,多少根彩線就分割成多少份,然后感謝 嗑瓜子兒gf-顏色漸變的JS代碼 寫的博客,提供了算法
最終效果出來了:
預(yù)覽組件
第一次寫canvas組件,此代碼僅供參考,最后感謝[masqli-canvas仿芝麻信用分儀表盤
][3],參考了前面兩位博主的代碼才能實(shí)現(xiàn)我項(xiàng)目的需求,所謂前人栽樹,后人乘涼,今天把我寫的也分享給大家,能幫到大家就更好,對(duì)我自己也算做個(gè)筆記了,在此再次感謝兩位博主
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/99343.html
摘要:先上效果圖這種圖形大家應(yīng)該都見過,俗稱儀表盤,當(dāng)然,上圖只是個(gè)最基本的儀表盤架子,可能在實(shí)際場(chǎng)景中還會(huì)其他很多花里胡哨的點(diǎn)綴,那些暫且不管,不是關(guān)鍵,這東西經(jīng)常見到,但還沒親自上手在代碼層面實(shí)現(xiàn)過,最近做的一個(gè)需求恰好有這個(gè)場(chǎng)景,這里歸先上效果圖: showImg(https://user-gold-cdn.xitu.io/2019/5/23/16ae28a94cb51d3e); 這種圖形大...
摘要:先上效果圖這種圖形大家應(yīng)該都見過,俗稱儀表盤,當(dāng)然,上圖只是個(gè)最基本的儀表盤架子,可能在實(shí)際場(chǎng)景中還會(huì)其他很多花里胡哨的點(diǎn)綴,那些暫且不管,不是關(guān)鍵,這東西經(jīng)常見到,但還沒親自上手在代碼層面實(shí)現(xiàn)過,最近做的一個(gè)需求恰好有這個(gè)場(chǎng)景,這里歸先上效果圖: showImg(https://user-gold-cdn.xitu.io/2019/5/23/16ae28a94cb51d3e); 這種圖形大...
摘要:,這是一個(gè)仿支付寶芝麻信用分的一個(gè),其實(shí)就是一個(gè)動(dòng)畫儀表盤。首先,上原圖這個(gè)是在下支付寶上的截圖,分低各位見笑了。 hi,這是一個(gè)仿支付寶芝麻信用分的一個(gè)canvas,其實(shí)就是一個(gè)動(dòng)畫儀表盤。 首先, 上原圖: showImg(https://segmentfault.com/img/bVbn3D6?w=750&h=1334); 這個(gè)是在下支付寶上的截圖,分低各位見笑了。然后看下我用c...
摘要:繪制表盤指針對(duì)指針的繪制,首先以原點(diǎn)為中心繪制一個(gè)圓,對(duì)延伸出來的指針?biāo)伎剂藘煞N繪制方法第一種以軸左半邊為例,點(diǎn)為起始點(diǎn),以為控制點(diǎn),為終點(diǎn)繪制三次貝塞爾曲線第二種以軸右半邊為例,直接從點(diǎn)繪制直線到。 不知道大家童年時(shí)候有沒有在手上畫手表的經(jīng)歷,恰好最近在看 canvas ,于是就誕生了這個(gè)高仿表盤。 showImg(https://segmentfault.com/img/bV7y...
閱讀 2339·2023-04-25 14:29
閱讀 1464·2021-11-22 09:34
閱讀 2707·2021-11-22 09:34
閱讀 3394·2021-11-11 10:59
閱讀 1856·2021-09-26 09:46
閱讀 2227·2021-09-22 16:03
閱讀 1925·2019-08-30 12:56
閱讀 482·2019-08-30 11:12