欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JavaScript利用canvas實(shí)現(xiàn)炫酷的碎片切圖效果

 更新時(shí)間:2022年10月24日 10:39:51   作者:南玖  
這篇文章主要和大家分享一個(gè)炫酷的碎片式切圖效果,本文主要利用canvas來(lái)實(shí)現(xiàn),代碼量不多,但有些地方還是需要花點(diǎn)時(shí)間去理解的,感興趣的可以學(xué)習(xí)一下

前言

今天分享一個(gè)炫酷的碎片式切圖效果,這個(gè)其實(shí)在自己的之前的博客上有實(shí)現(xiàn)過(guò),本人覺(jué)得這個(gè)效果還是挺炫酷的,這次還是用我們的canvas來(lái)實(shí)現(xiàn),代碼量不多,但有些地方還是需要花點(diǎn)時(shí)間去理解的,需要點(diǎn)數(shù)學(xué)幾何理解能力,老規(guī)矩,我們還是先看效果再來(lái)看實(shí)現(xiàn)步驟。

需求分析

從上面我們看到圖片在切換的時(shí)候其實(shí)是一個(gè)一個(gè)的小碎片慢慢從點(diǎn)擊位置往外擴(kuò)散開(kāi)來(lái),這一個(gè)個(gè)小碎片,在頁(yè)面中其實(shí)就是一個(gè)個(gè)的小方塊。這里的難點(diǎn)在于如何將一張完整的圖片切割成一個(gè)一個(gè)的小方塊分別進(jìn)行渲染,還有就是這個(gè)棱形圖案的位置確定。

  • 切割:這里我們可以以坐標(biāo)系的形式來(lái)進(jìn)行切割,每一個(gè)方塊都對(duì)應(yīng)著它們自己在坐標(biāo)系中的位置(x, y)
  • 繪制:這里的重點(diǎn)在于drawImage方法
  • 棱形擴(kuò)散:這里需要點(diǎn)數(shù)學(xué)幾何理解能力,后面作圖理解

實(shí)現(xiàn)過(guò)程

坐標(biāo)系

在實(shí)現(xiàn)之前,我們先來(lái)理解一個(gè)概念:「坐標(biāo)系」

注意:這里所說(shuō)的坐標(biāo)系不是我們數(shù)學(xué)中的坐標(biāo)系,但兩者又有些類似,不同點(diǎn)在于兩者的原點(diǎn)位置以及y軸的方向不同。

切割

這一步主要是為了確定每一個(gè)單元格的大小,單元格的長(zhǎng)寬最好不要是最大公約數(shù)或最小公約數(shù),因?yàn)檫^(guò)大效果不夠炫,過(guò)小性能會(huì)有壓力。

我這里畫板長(zhǎng)寬為 800 * 530 ,選取 16 * 15 為單元尺寸,即整個(gè)畫布由 50 * 35 共 1750 個(gè)單元格組成。切割分完單元格之后我們需要先計(jì)算一些基本的參數(shù)備用。

this.imgW?=?800;?//?圖片原始寬
this.imgH?=?530;?//?圖片原始高

this.conW?=?800;?//?畫布寬
this.conH?=?530;?//??畫布高

this.dw?=?16;?//?單元格寬
this.dh?=?15;?//?單元格高

this.I?=?this.conH?/?this.dh;?//單元行數(shù)
this.J?=?this.conW?/?this.dw;?//?單元列數(shù)

this.DW?=?this.imgW?/?this.J;?//?原圖單元寬
this.DH?=?this.imgH?/?this.I;?//?原圖單元高

「行數(shù) = 畫布高度 / 單元格高度;列數(shù) = 畫面寬度 / 單元格寬度」

繪制

本次繪制的重點(diǎn)在于drawImage這個(gè)方法,我們可以先來(lái)了解一下這個(gè)方法的參數(shù)及功能

drawImage

drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

這個(gè)方法一共有9個(gè)參數(shù),作用是在畫布上繪制圖像??吹竭@么多參數(shù)是不是已經(jīng)被勸退了,哈哈

  • 「image」:繪制到上下文的元素。允許任何的畫布圖像源,例如:HTMLImageElement、SVGImageElement、HTMLVideoElement、HTMLCanvasElement、ImageBitmap、OffscreenCanvas或 VideoFrame 。
  • 「sx」:(可選)需要繪制到目標(biāo)上下文中的,image 的矩形(裁剪)選擇框的左上角 X 軸坐標(biāo)??梢允褂?3 參數(shù)或 5 參數(shù)語(yǔ)法來(lái)省略這個(gè)參數(shù)。
  • 「s y」:(可選)需要繪制到目標(biāo)上下文中的,image 的矩形(裁剪)選擇框的左上角 Y 軸坐標(biāo)??梢允褂?3 參數(shù)或 5 參數(shù)語(yǔ)法來(lái)省略這個(gè)參數(shù)。
  • 「sWidth」:(可選)需要繪制到目標(biāo)上下文中的,image 的矩形(裁剪)選擇框的寬度。如果不說(shuō)明,整個(gè)矩形(裁剪)從坐標(biāo)的 sx 和 sy 開(kāi)始,到 image 的右下角結(jié)束??梢允褂?3 參數(shù)或 5 參數(shù)語(yǔ)法來(lái)省略這個(gè)參數(shù)。使用負(fù)值將翻轉(zhuǎn)這個(gè)圖像。
  • 「sHeight」:(可選)需要繪制到目標(biāo)上下文中的,image的矩形(裁剪)選擇框的高度。使用負(fù)值將翻轉(zhuǎn)這個(gè)圖像。
  • 「dx」image 的左上角在目標(biāo)畫布上 X 軸坐標(biāo)。
  • 「dy」image 的左上角在目標(biāo)畫布上 Y 軸坐標(biāo)。
  • 「dWidth」image 在目標(biāo)畫布上繪制的寬度。允許對(duì)繪制的 image 進(jìn)行縮放。如果不說(shuō)明,在繪制時(shí) image 寬度不會(huì)縮放。注意,這個(gè)參數(shù)不包含在 3 參數(shù)語(yǔ)法中。
  • 「dHeight」image 在目標(biāo)畫布上繪制的高度。允許對(duì)繪制的 image 進(jìn)行縮放。如果不說(shuō)明,在繪制時(shí) image 高度不會(huì)縮放。注意,這個(gè)參數(shù)不包含在 3 參數(shù)語(yǔ)法中。

這9個(gè)參數(shù)我們可以這樣來(lái)記憶,第一個(gè)參數(shù)是圖像源,接下來(lái)的四個(gè)參數(shù)指的是原圖,最后四個(gè)參數(shù)指的是畫布

切割&渲染

這里我們主要是將一張圖片切割成一個(gè)個(gè)的小碎片,是這些碎片拼起來(lái)就是一張完整的圖片。

class?ChipBanner?{
??constructor()?{
????this.cvs?=?document.querySelector("#chip");
????this.ctx?=?this.cvs.getContext("2d");
????this.imgList?=?document.querySelectorAll(".bg");
????this.imgIndex?=?0;
????this.isAnimating?=?false;

????this.imgW?=?800;?//圖片原始寬/高
????this.imgH?=?530;

????this.conW?=?800;?//畫布寬/高
????this.conH?=?530;

????this.dw?=?16;?//畫布單元寬/高
????this.dh?=?15;

????this.I?=?this.conH?/?this.dh;?//單元行/列數(shù)
????this.J?=?this.conW?/?this.dw;

????this.DW?=?this.imgW?/?this.J;?//原圖單元寬/高
????this.DH?=?this.imgH?/?this.I;
??}

??init()?{
????this.ctx.beginPath();

????for?(let?i?=?0;?i?<?this.I;?i++)?{
??????for?(let?j?=?0;?j?<?this.J;?j++)?{
????????this.chipDraw(this.imgList[this.imgIndex],?i,?j);
??????}
????}

????this.ctx.closePath();
????this.ctx.stroke();
??}
??drawText()?{
????this.ctx.font?=?"150px?serif";
????this.ctx.strokeStyle?=?"white";
????this.ctx.strokeText("1024",?500,?500);
??}

??chipDraw(img,?i,?j)?{
????this.drawText();
????//負(fù)責(zé)繪制,i:?單元行號(hào);j:?單元列號(hào)
????this.ctx.drawImage(
??????img,
??????this.DW?*?j,
??????this.DH?*?i,
??????this.DW,
??????this.DH,
??????this.dw?*?j,
??????this.dh?*?i,
??????this.dw,
??????this.dh
????);
??}
}

這里正確拼出來(lái)看到的和正常圖片沒(méi)有任何區(qū)別

再來(lái)看一張拼錯(cuò)的圖

剛開(kāi)始幾何坐標(biāo)那里沒(méi)寫對(duì),拼出來(lái)就成這樣了,哈哈,看著就像動(dòng)畫幀卡住的樣子。

動(dòng)畫

這里主要是要找出某個(gè)點(diǎn)周圍棱形范圍內(nèi)的所有點(diǎn)的坐標(biāo),然后在清除這些坐標(biāo)圖案的同時(shí),開(kāi)始繪制下一張圖片。

「菱形線上的點(diǎn)與坐標(biāo)的 行號(hào)差值的絕對(duì)值 + 列號(hào)差值的絕對(duì)值 = 距離」

找出坐標(biāo)棱形范圍內(nèi)所有的點(diǎn)

countAround(i,?j,?dst)?{
????let?arr?=?[];
????for?(let?m?=?i?-?dst;?m?<=?i?+?dst;?m++)?{
??????for?(let?n?=?j?-?dst;?n?<=?j?+?dst;?n++)?{
????????if?(
??????????Math.abs(m?-?i)?+?Math.abs(n?-?j)?==?dst?&&
??????????m?>=?0?&&
??????????n?>=?0?&&
??????????m?<=?this.I?-?1?&&
??????????n?<=?this.J?-?1
????????)?{
??????????arr.push({?x:?m,?y:?n?});
????????}
??????}
????}
????return?arr;
??}

清除單元格畫布

chipClear(i,?j)?{
????this.ctx.clearRect(this.dw?*?j,?this.dh?*?i,?this.dw,?this.dh);
}

合并&動(dòng)畫

start(i,?j)?{
????if?(this.isAnimating)?return;

????this.isAnimating?=?true;

????this.imgIndex++;

????if?(this.imgIndex?>?this.imgList.length?-?1)?this.imgIndex?=?0;

????let?_this?=?this,
??????dst?=?0,
??????timer?=?setInterval(()?=>?{
????????let?resArr?=?_this.countAround(i,?j,?dst);

????????resArr.forEach((item)?=>?{
??????????_this.chipClear(item.x,?item.y);??//?清除單元格
??????????_this.chipDraw(_this.imgList[_this.imgIndex],?item.x,?item.y);?//?繪制下一張圖片
????????});

????????if?(!resArr.length)?{
??????????clearInterval(timer);
??????????_this.isAnimating?=?false;
????????}
????????dst++;
??????},?30);
??}

大功告成,這樣就實(shí)現(xiàn)了一個(gè)炫酷的碎片式切圖效果了~

到此這篇關(guān)于JavaScript利用canvas實(shí)現(xiàn)炫酷的碎片切圖效果的文章就介紹到這了,更多相關(guān)JavaScript canvas碎片切圖效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 每天一篇javascript學(xué)習(xí)小結(jié)(Date對(duì)象)

    每天一篇javascript學(xué)習(xí)小結(jié)(Date對(duì)象)

    這篇文章主要介紹了javascript中的Date對(duì)象知識(shí)點(diǎn),對(duì)Date對(duì)象的基本使用方法,以及各種方法進(jìn)行整理,感興趣的小伙伴們可以參考一下
    2015-11-11
  • Bootstrap基本樣式學(xué)習(xí)筆記之表單(3)

    Bootstrap基本樣式學(xué)習(xí)筆記之表單(3)

    這篇文章主要介紹了Bootstrap學(xué)習(xí)筆記之表單基本樣式的相關(guān)資料,為大家分享了三種表單樣式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • 微信小程序后臺(tái)持續(xù)定位功能使用詳解

    微信小程序后臺(tái)持續(xù)定位功能使用詳解

    這篇文章主要介紹了微信小程序后臺(tái)持續(xù)定位功能使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • IE瀏覽器兼容Firefox的JS腳本的代碼

    IE瀏覽器兼容Firefox的JS腳本的代碼

    對(duì)于經(jīng)常用js的朋友,有時(shí)候一段腳本并不是兩個(gè)瀏覽器都兼容的,下面一些對(duì)ie和firefox都兼容的一些代碼,大家可以學(xué)習(xí)下。
    2008-10-10
  • js 數(shù)據(jù)類型判斷的方法

    js 數(shù)據(jù)類型判斷的方法

    這篇文章主要介紹了js 數(shù)據(jù)類型判斷的方法,幫助大家更好的理解和使用JavaScript,感興趣的朋友可以了解下
    2020-12-12
  • IE中鼠標(biāo)經(jīng)過(guò)option觸發(fā)mouseout的解決方法

    IE中鼠標(biāo)經(jīng)過(guò)option觸發(fā)mouseout的解決方法

    這篇文章主要介紹了IE中鼠標(biāo)經(jīng)過(guò)option觸發(fā)mouseout的解決方法,分析了IE中鼠標(biāo)移到option時(shí)window.event.toElement返回值為null的原因及解決方法,需要的朋友可以參考下
    2015-01-01
  • JS中表單的使用小結(jié)

    JS中表單的使用小結(jié)

    本篇文章主要是對(duì)JS中表單的使用進(jìn)行了詳細(xì)的總結(jié)介紹,需要的朋友可以過(guò)來(lái)參考下,希望對(duì)大家有所幫助
    2014-01-01
  • JavaScript中的字符串與數(shù)字轉(zhuǎn)換的示例

    JavaScript中的字符串與數(shù)字轉(zhuǎn)換的示例

    在JavaScript編程中,掌握字符串與數(shù)字的轉(zhuǎn)換技巧對(duì)處理用戶輸入、數(shù)據(jù)計(jì)算及格式化輸出至關(guān)重要,本文詳細(xì)介紹了多種轉(zhuǎn)換方法,下面就一起來(lái)介紹一下
    2024-09-09
  • JS數(shù)據(jù)類型判斷的幾種常用方法

    JS數(shù)據(jù)類型判斷的幾種常用方法

    這篇文章主要介紹了JS判斷數(shù)據(jù)類型的幾種常用方法,文中示例代碼非常詳細(xì),幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • JavaScript 類的封裝操作示例詳解

    JavaScript 類的封裝操作示例詳解

    這篇文章主要介紹了JavaScript 類的封裝操作,結(jié)合實(shí)例形式分析了JavaScript 類的封裝基本原理、操作技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2020-05-05

最新評(píng)論