摘要:回溯法是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇并不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法。代碼請點這里這里有一個示例,展示下用回溯法怎么找到這些形狀的。
說明
canvas元素標簽強大之處在于可以直接在HTML上進行圖形操作,具有極大的應用價值。
canvas 可以實現對圖像的像素操作,這就要說到 getImageData() 方法了。
解釋CanvasRenderingContext2D.getImageData() 返回一個 ImageData 對象,用來描述 canvas 區域隱含的像素數據,這個區域通過矩形表示,起始點為(sx, sy)、寬為sw、高為sh。
語法ctx.getImageData(sx, sy, sw, sh);
參數sx:將要被提取的圖像數據矩形區域的左上角 x 坐標。
sy:將要被提取的圖像數據矩形區域的左上角 y 坐標。
sw:將要被提取的圖像數據矩形區域的寬度。
sh:將要被提取的圖像數據矩形區域的高度。
返回值一個 ImageData 對象,包含 canvas 給定的矩形圖像數據。
ImageData 對象會有三個屬性,height、width 和 data。
ImageData.height
使用像素描述 ImageData 的實際高度,這個值其實等于 getImageData() 方法中的參數 sh
ImageData.width
使用像素描述 ImageData 的實際寬度。這個值其實等于 getImageData() 方法中的參數 sw
ImageData.data
一個一維數組,包含以 RGBA 順序的數據,數據使用 0 至 255(包含)的整數表示。
如果高度(sh)或者寬度(sw)變量為0,則會拋出錯誤。
示例以上是需要知道的基本知識,下來看幾個例子吧!
顏色選擇器效果圖
實現思路
1、先把圖片畫到 canvas 上,
2、獲取鼠標移動時的坐標并通過 getImageData() 方法,獲取這一個點的像素,
3、得到像素信息后,拼接出 rgba 的字符串,再設置下面的小正方形的背景是這個顏色。
代碼請點這里
圖片灰度效果圖
實現思路
1、先在 canvas 上畫出圖片,
2、通過 getImageData() 方法,獲取整個 canvas 上的像素信息,
3、點擊按鈕時,遍歷獲取到的像素信息的每個像素的 紅色值、綠色值 和 藍色值,相加求出平均值,再把平均值賦值給紅色、綠色和藍色,這么做是為了求出每個像素的灰度,
4、然后把改變后的像素信息,通過 putImageData() 方法重新添加到 canvas中,就實現了圖片灰度的效果。
代碼請點這里
除了圖片可以實現灰度的效果外,因為 canvas 中也可以放視頻,對于視頻也可以實現灰度的效果,原理都是一樣的,操作其實也一樣,其實視頻做灰度效果,可以理解為給很多張圖片做灰度效果。
效果圖
代碼請點這里
文字粒子效果圖
實現思路
我們先不說,怎么實現最后的動畫效果,我們先來想怎么獲取文字所有像素在 canvas 上的坐標,
1、先獲取文字在canvas上的像素信息
1.1 先在 canvas 上填充一個白色矩形
1.2 用紅色,在 canvas 上寫文字
1.3 獲取 canvas 的像素信息 ImageData
1.4 清除整個 canvas
1.5 在 ImageData 中找出是紅色的像素,記錄他們的 x 和 y 坐標,找出的每個像素的坐標都保存在一個對象(Dot)中,所有的對象又都保存在一個數組(dotList)中,
計算機的速度是很快的,所以用戶是看不到紅色文字的,如果你覺得這種方式不好,也可以在用一個 canvas 專門來獲取文字像素,這個canvas 不要讓用戶看到就好了。
我們知道文字的像素信息,知道每個像素的坐標,就能實現各種效果,像示例中的效果,僅僅只是改變一個 x 坐標的值而已。
2、遍歷保存文字像素的數組(dotList),每個像素(Dot)對象還有一個 nowX 屬性,初始值是0,每次畫最后的圓點的時候,都是用這個屬性作為圓的 x 坐標,nowX 屬性不斷的增加,直到最后等于像素(Dot)對象的 x 屬性值就停止。
代碼請點這里
這種效果我也是在 Canvas基礎-粒子動畫Part3 這篇文章中看到的,作者寫的很好,推薦看看。
在github上也有一個不錯的項目 shape-shifter,可以了解一下。
問題
平面上有若干個不特定的形狀,如下圖所示。請寫程序求出物體的個數,以及每個不同物體的面積。
效果圖
實現思路
1、創建存儲圖片像素點的二維數組(coordinates ),圖中只有兩種顏色,空白區域一種顏色,形狀區域一種顏色,空白區域的像素標記為0,形狀區域標記為1,類似下面這樣
0,0,0,0,0,0,0,0,0,0,0,0 0,0,1,1,1,0,0,0,0,0,0,0 0,1,1,1,1,0,0,0,0,0,0,0 0,1,1,1,0,0,0,1,1,1,1,0 0,0,0,0,0,0,1,1,1,0,0,0 0,0,0,0,0,0,1,1,1,0,0,0 0,0,0,0,0,0,0,0,0,0,0,0
2、計算有多少個形狀,就是看二維數組中有多少個連續為1的塊,計算形狀的面積,就是算一個連續為1的塊,有多少個1。
這就要通過 遞歸回溯算法 來計算了。
回溯算法實際上一個類似枚舉的搜索嘗試過程,主要是在搜索嘗試過程中尋找問題的解,當發現已不滿足求解條件時,就“回溯”返回,嘗試別的路徑。
回溯法是一種選優搜索法,按選優條件向前搜索,以達到目標。但當探索到某一步時,發現原先選擇并不優或達不到目標,就退回一步重新選擇,這種走不通就退回再走的技術為回溯法。
代碼請點這里
這里有一個示例,展示下用回溯法怎么找到這些形狀的。
這個例子出自 前端面試的一道算法題(使用canvas解答)這篇文章,文章講的也很好,推薦看看
總結用 getImageData() 方法 要考慮兩個問題
1、跨域問題
getImageData() 方法不允許操作非此域名外的圖片資源,所以如果想本地試試文章中的例子,直接寫圖片路徑就會報錯,
不過可以將圖片轉換成base64編碼,直接把base64編碼賦值給圖片的src屬性就可以簡單的解決這個問題了。這種方式僅僅適用于圖片,如果是視頻的話,還是需要服務器端的配合。
具體可以看看這篇文章 解決canvas圖片getImageData,toDataURL跨域問題
2、性能問題
getImageData() 方法一般獲取的像素信息是很多的,所以這就要考慮性能的問題,至于怎么優化也是要看具體場景了,比如在文中的文字粒子效果的示例中,可以先用 measureText() 方法計算文字寬度,結合 fontSize 就能知道 文字在哪塊區域,只通過這個塊區域獲取文字的像素就好了。
getImageData() 方法,一句話總結就是獲取 canvas 上的像素信息,文中實現的各種效果不管是簡單的還是復雜的,都是在操作像素。
通過getImageData() 方法,能做的事情還有很多,遠不止文章中提到的這些,比如實現其他的濾鏡效果,文中只是說了一個灰度,我們還可以去實現反相,模糊,浮雕等,文中實現了文字粒子效果,其實圖片也可以實現粒子效果,除此之外還有很多好玩的事情,但是本人才疏學淺,好多我也不知道。
最后,如果文中有不足或者錯誤的地方,還請小伙伴們指出,萬分感謝。
Canvas基礎-粒子動畫Part3
前端面試的一道算法題(使用canvas解答)
leetcode題解(遞歸和回溯法)
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/97858.html
摘要:在中任意從本地選擇一張圖片,然后通過鼠標移動或者移動端就能實現圓形分裂的效果。個人習慣在構造函數最后加上方法,方法里做一些準備工作,完成前的一些必要的事情。繪制第一個,也是最大的一個圓形。 在看D3.js的時候,無意間看到了一個例子,覺得很有趣,像是會分裂的圓形馬賽克。看了下代碼,使用svg完成的,但是具體實現方式使得在手機端無法把玩,于是就自己實現了一個canvas版本的。代碼很簡單...
摘要:在中任意從本地選擇一張圖片,然后通過鼠標移動或者移動端就能實現圓形分裂的效果。個人習慣在構造函數最后加上方法,方法里做一些準備工作,完成前的一些必要的事情。繪制第一個,也是最大的一個圓形。 在看D3.js的時候,無意間看到了一個例子,覺得很有趣,像是會分裂的圓形馬賽克。看了下代碼,使用svg完成的,但是具體實現方式使得在手機端無法把玩,于是就自己實現了一個canvas版本的。代碼很簡單...
摘要:萬圣節到了,寫一個小例子了解一下畫圖方法,可以實現一些有趣的效果,動畫實現。移動路徑方法把路徑移動到畫布中指定點,不創建線條。實現初始畫布顯示文字萬圣節快樂閃電打雷反轉畫布重置畫布總結萬圣節快樂 萬圣節到了,寫一個小例子了解一下canvas畫圖方法,canvas可以實現一些有趣的效果,動畫實現。以一個簡單的頁面實現了解一下基礎的畫圖方法。原文鏈接 canvas可以實現一些有趣的效果,動...
摘要:前言本文是接續系列教程的,主要是介紹顏色系統在中的應用。本來是與一起成文的,因為莫名其妙的字數限制只能分割放送了。提供可以獲取畫布上任何一個像素,并可以自由的操作他們。繪制指定的位置繪制對象的內容。 前言 本文是接續系列教程的extra1,主要是介紹顏色系統在canvas中的應用。 本來是與extra1一起成文的,因為segmentfault莫名其妙的字數限制bug只能分割放送了。 ...
摘要:前言本文是接續系列教程的,主要是介紹顏色系統在中的應用。本來是與一起成文的,因為莫名其妙的字數限制只能分割放送了。提供可以獲取畫布上任何一個像素,并可以自由的操作他們。繪制指定的位置繪制對象的內容。 前言 本文是接續系列教程的extra1,主要是介紹顏色系統在canvas中的應用。 本來是與extra1一起成文的,因為segmentfault莫名其妙的字數限制bug只能分割放送了。 ...
閱讀 3308·2021-09-30 09:54
閱讀 3804·2021-09-22 15:01
閱讀 3110·2021-08-27 16:19
閱讀 2578·2019-08-29 18:39
閱讀 2164·2019-08-29 14:09
閱讀 634·2019-08-26 10:23
閱讀 1343·2019-08-23 12:01
閱讀 1873·2019-08-22 13:57