亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

canvas 繪制雙線技巧

王軍 / 697人閱讀

摘要:只有源圖像外的目標(biāo)圖像部分會被顯示,源圖像是透明的。繪制了線路的圖像是目標(biāo)圖像,線路是源圖像。

楔子

最近一個項目,需要繪制雙線的效果,雙線效果表示的是軌道(類似鐵軌之類的),如下圖所示:

負(fù)責(zé)這塊功能開發(fā)的小伙,姑且稱之為L吧,最開始是通過數(shù)學(xué)計算的方式來實現(xiàn)這種雙線,也就是在原來的路徑的基礎(chǔ)上,計算出兩條路徑。但是這個過程的計算算挺復(fù)雜,而是最終實現(xiàn)的效果很耗性能,性能損耗估計主要在于路徑的計算上。

優(yōu)化技巧

后來他找到我來看這個問題,我在分析了項目背景的情況下,給予了一個簡單的繪制技巧,就是先用較粗的線條繪制路徑,然后再用較細(xì)的線條繪制路徑,較細(xì)線條的顏色正好是背景顏色。
之所以能夠使用這個技巧,是因為該項目的繪制背景是純色的,而不是漸變色或者圖片。
示例代碼如下:

               ctx.beginPath();
               ctx.fillStyle = "blue";
               ctx.rect(10,10,1000,1000);
               ctx.fill();

              ctx.save();
              ctx.strokeStyle = "red";
              ctx.lineWidth = 10;
              ctx.lineCap = "round";
              ctx.beginPath();
              ctx.moveTo(200,100);  //起始點
              ctx.lineTo(400,100);
              ctx.quadraticCurveTo(500,100,500,200);   
              ctx.lineTo(500,400);
              ctx.quadraticCurveTo(500,500,400,500);   
              ctx.lineTo(200,500);
              ctx.quadraticCurveTo(100,500,100,400);   
              ctx.lineTo(100,200);
              ctx.quadraticCurveTo(100,100,200,100);   
              ctx.stroke();

              ctx.strokeStyle= "blue"
              ctx.lineWidth = 4;
              ctx.stroke();
              ctx.restore();
              

代碼的思路是,首先使用純色blue繪制了一個背景,然后使用線條顏色red繪制一條線,然后使用較小的線寬,并把線條顏色改成背景顏色blue,繪制另外一個條線段。最終的繪制效果如下:

到此,項目的這個技術(shù)難點問題,算是被解決了。這種解決方法,不僅算法簡單,不用構(gòu)思數(shù)學(xué)方法來構(gòu)造雙線,而且輕量,不會有性能負(fù)擔(dān)。

背景不是純色情況

前面說到:之所以能夠使用這個技巧,是因為該項目的繪制背景是純色的,而不是漸變色或者圖片。
那如果背景是圖片或者漸變顏色情況下,用這種技巧,肯定就是失效的了。

之所以會思考這個問題,是得益于公司的技術(shù)分享會。我會要求員工定期組織分享會,分享一些經(jīng)驗。在此打個小廣告,可以看出我們公司的技術(shù)氛圍是很好的,所以有興趣的小伙伴可以抓緊時間投簡歷。怎么投簡歷呢,關(guān)注微信號ITman彪叔。
過程中,當(dāng)時小伙伴L也分享了前面提到這種思路。在分享的過程中,我提出了進一步的問題,如果背景不是純色,而是漸變色或者圖片怎么辦?并且靈感乍現(xiàn),想到了一個解決方法,就是使用ctx.globalCompositeOperation。

有關(guān)globalCompositeOperation的說明,可以參考如下鏈接的說明:
https://developer.mozilla.org...
http://www.w3school.com.cn/ta...

globalCompositeOperation的定義和用法

globalCompositeOperation 屬性設(shè)置或返回如何將一個源(新的)圖像繪制到目標(biāo)(已有)的圖像上。其中:

源圖像 = 您打算放置到畫布上的繪圖。

目標(biāo)圖像 = 您已經(jīng)放置在畫布上的繪圖

下圖顯示了globalCompositeOperation的不同的值的解釋:

要實現(xiàn)雙線的繪制,就要求用同樣的路徑,不同的線寬繪制兩條線路
(我們稱之為目標(biāo)線路和源線路)。并要達(dá)到一條線路摳出另外一條線路的效果。
結(jié)合上圖,我們可以看出destination-out,source-out,xor可以達(dá)到效果。下面以destination-out舉例說明。

destination-out繪制原理說明

比如首先通過 css 設(shè)置背景圖,并去掉繪制背景顏色,代碼如下:

 

然后繪制代碼如下:

  ctx.save();
              ctx.strokeStyle = "red";
              ctx.lineWidth = 10;
              ctx.lineCap = "round";
              ctx.beginPath();
              ctx.moveTo(200,100);  //起始點
              ctx.lineTo(400,100);
              ctx.quadraticCurveTo(500,100,500,200);   
              ctx.lineTo(500,400);
              ctx.quadraticCurveTo(500,500,400,500);   
              ctx.lineTo(200,500);
              ctx.quadraticCurveTo(100,500,100,400);   
              ctx.lineTo(100,200);
              ctx.quadraticCurveTo(100,100,200,100);   
              ctx.stroke();

              
              ctx.globalCompositeOperation = "destination-out";
              ctx.lineWidth = 4;
              ctx.stroke();
              ctx.restore();

首先設(shè)置路徑,然后設(shè)置線寬為10,調(diào)用stroke方法繪制一條線寬為10的路線A。
之后設(shè)置globalCompositeOperation為 "destination-out",調(diào)整線寬為4,調(diào)用stroke方法繪制一條線寬為4的路線B。
看下destination-out的解釋:

在源圖像外顯示目標(biāo)圖像。只有源圖像外的目標(biāo)圖像部分會被顯示,源圖像是透明的。

繪制了線路A的canvas圖像是目標(biāo)圖像,線路B是源圖像。根據(jù)上面解釋,只有源圖像之外的目標(biāo)圖像能夠被顯示。最終繪制的效果如下:

xor 和 source-out

把上面的代碼的globalCompositeOperation修改成xor,發(fā)現(xiàn)效果也是可以的,xor的解釋如下:

使用異或操作對源圖像與目標(biāo)圖像進行組合。 英文解釋如下:
Shapes are made transparent where both overlap and drawn normal everywhere else.

意思源和目標(biāo)的像素重疊(overlap)的部分會被變成透明像素,其他部分正常繪制。 所以上面示例中,線條A和線條B重疊的部分會被變成透明。繪制的效果也是線條A的被挖空。

對于source-out,其效果正好和destination-out的效果相反:

在目標(biāo)圖像之外顯示源圖像。只會顯示目標(biāo)圖像之外源圖像部分,目標(biāo)圖像是透明的。

應(yīng)此只需要取反操作即可,先用寬度4繪制線條A,然后用寬度10繪制線條B,其結(jié)果也是一樣的。

背景不是純色情況2

前面的背景是通過css的方式設(shè)置上去的,如果是通過canvas的drawImage直接繪制上去,效果就不一樣了。還是以destination-out為例說明,首先繪制了image,然后繪制線路A,此時的目標(biāo)圖像不在是線路A組成的圖形,而是image和線路A組合成的圖形,此時用destination-out的方式繪制線路B,不僅會挖空線路A,背景也會被挖空,如下圖所示:

應(yīng)此要想達(dá)到真正的雙線效果,要么背景只能是用css設(shè)置,要么用兩個canvas疊加,一個繪制背景圖片,一個繪制路徑。
當(dāng)然還有一種方式,就是繪制雙線總是在一個臨時的canvas上面進行,然后把這個臨時的canvas繪制結(jié)果再次繪制到工作canvas上面,相關(guān)實踐留給讀者自己進行。

后記

在網(wǎng)絡(luò)上面搜索canvas double line,搜索到stackoverflow上的一條結(jié)果如下:
https://stackoverflow.com/que...
其中的答案也是采用了globalCompositeOperation設(shè)置為destination-out的方式。

歡迎關(guān)注公眾號“ITman彪叔”。彪叔,擁有10多年開發(fā)經(jīng)驗,現(xiàn)任公司系統(tǒng)架構(gòu)師、技術(shù)總監(jiān)、技術(shù)培訓(xùn)師、職業(yè)規(guī)劃師。熟悉Java、JavaScript、Python語言,熟悉數(shù)據(jù)庫。熟悉java、nodejs應(yīng)用系統(tǒng)架構(gòu),大數(shù)據(jù)高并發(fā)、高可用、分布式架構(gòu)。在計算機圖形學(xué)、WebGL、前端可視化方面有深入研究。對程序員思維能力訓(xùn)練和培訓(xùn)、程序員職業(yè)規(guī)劃有濃厚興趣。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/100232.html

相關(guān)文章

  • canvas高效繪制10萬圖形,你必須知道的高效繪制技巧

    摘要:最近的一個客戶項目中,簡化的需求是繪制按照行列繪制很多個圓圈。等等,客戶要求繪制的極限是萬個,而且每次繪制不能卡頓。然后通過通過創(chuàng)建對象,并把的繪制上下文的指定為該對象。另外繪制的效果其實是沒有繪制的效果好的,鋸齒嚴(yán)重。 最近的一個客戶項目中,簡化的需求是繪制按照行列繪制很多個圓圈。需求看起來不難,上手就可以做,寫兩個for循環(huán)。 原始繪制方法 首先定義了很多Circle對象,在遍歷循...

    you_De 評論0 收藏0
  • canvas反向裁剪技巧

    摘要:效果如下圖所示如何實現(xiàn)反向裁剪呢筆者通過實踐,發(fā)現(xiàn)有以下幾種思路。使用合成模式通過設(shè)置的值,可以實現(xiàn)類似的反向裁剪的效果。示例代碼如下最終效果參考上面的圖形反向裁剪。 我們都知道在canvas 可以通過clip來實現(xiàn)剪裁功能,其步驟一般是先設(shè)置要裁剪的區(qū)域(路徑),然后通過ctx.clip()的實現(xiàn)裁剪,裁剪之后,后續(xù)的繪制只能在裁剪的區(qū)域顯示效果,比如如下一段代碼,實現(xiàn)了一個圓形裁剪...

    hqman 評論0 收藏0
  • 前端系列——canvas實現(xiàn)按住鼠標(biāo)移動繪制出軌跡

    摘要:鼠標(biāo)按住繪制軌跡需求在一塊畫布上,初始狀態(tài)畫布什么都沒有,現(xiàn)在,我想給畫布加一點鼠標(biāo)事件,用鼠標(biāo)在畫布上寫字。獲取當(dāng)前鼠標(biāo)相對于的坐標(biāo)。的解構(gòu)賦值繪制起點。但是由于瀏覽器會自動幫你判斷并且移交事件處理,所以完全不用擔(dān)心。 概要 工作以來,寫過vue、react、正則、算法、小程序等知識,唯獨沒有寫過canvas,因為實在不會??! 2018年,給自己設(shè)定一個小目標(biāo):學(xué)會canvas,達(dá)到...

    CloudDeveloper 評論0 收藏0
  • [譯][Tkinter 教程08] Canvas 圖形繪制

    摘要:已獲原作者授權(quán)原系列地址簡介為提供了繪圖功能其提供的圖形組件包括線形圓形圖片甚至其他控件控件為繪制圖形圖表編輯圖形自定義控件提供了可能在第一個例子里我們將演示如何畫一條直線方法用來繪制一條直線為以整形表示的四個坐標(biāo)參數(shù)這表示所要繪制的直線連 已獲原作者授權(quán). 原系列地址: Python Tkinter 簡介 Canvas 為 Tkinter 提供了繪圖功能. 其提供的圖形組件包括 線...

    ivydom 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<