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