成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

《每周一點(diǎn)canvas動畫》—— 文字粒子

Riddler / 2303人閱讀

摘要:代碼文件每周一點(diǎn)動畫系列文章目前已經(jīng)更新了篇,今天給大家發(fā)個(gè)福利。粒子的位置為,我們作為參數(shù)傳入。粒子切換粒子切換的代碼在中,很簡單,就是綁定了兩個(gè)事件。

代碼文件

每周一點(diǎn)canvas動畫系列文章目前已經(jīng)更新了12篇,今天給大家發(fā)個(gè)福利。我們使用canvas來制作一個(gè)小的效果。這個(gè)小效果是我從codePen上看到的,我對其做了些修改增強(qiáng),添加了一些新的功能。UI界面就如下圖中看到的樣子。我們要實(shí)現(xiàn)的效果就如我在圖中操作的那樣,在輸入框中輸入文字(不管中文,還是英文,還是各種表情也好)都可以在canvas畫布中通過眾多的粒子組成,在側(cè)邊欄中還有很多控件,它們可以控制粒子的各方面屬性,以此來形成各種不同的絢麗效果。

1.目錄結(jié)構(gòu)

2.UI界面

UI界面的組成很簡單,主要有側(cè)邊欄控制臺canvas畫布兩部分組成


...

在側(cè)邊欄中有一系列的控制條,他們控制著粒子的各種屬性,包括文字輸入框:

 

控制條

粒子選擇

圓形 方塊

在這我就不一一列舉了!CSS樣式文件主要是對UI界面的布局和樣式處理,具體請查看代碼文件。

3.側(cè)邊欄滑動

當(dāng)點(diǎn)擊菜單按鈕時(shí),側(cè)邊欄滑出,再次點(diǎn)擊縮回。采用classList來切換滑出和縮回的class,在sidebar.js

var btn = document.getElementById("btn");
var control = document.getElementById("control");

btn.addEventListener("click", function(e){
    control.classList.toggle("slide");
}, false)

這樣我們的基礎(chǔ)界面就搭建完成。下面就到了我們這個(gè)動畫的核心思想

4.準(zhǔn)備工作

首先,我們在我們的index.js文件中定義我們需要的一些變量

var canvas = document.getElementById("canvas");
    context = canvas.getContext("2d");
    W = canvas.width = window.innerWidth;
     H = canvas.height = window.innerHeight;
    gridY = 7, gridX = 7;
    type = "ball";

var message = document.getElementById("message"),
    gravity = document.getElementById("gra"),
    duration = document.getElementById("dur"),
    speed = document.getElementById("speed"),
    radius = document.getElementById("rad"),
    resolution = document.getElementById("res");

   graVal = parseFloat(gravity.value);
   durVal = parseFloat(duration.value);
   spdVal = parseFloat(speed.value);
   radVal = parseFloat(radius.value);
   resVal = parseFloat(resolution.value);      

colors = [
  "#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5",
  "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4CAF50",
  "#8BC34A", "#CDDC39", "#FFEB3B", "#FFC107", "#FF9800",
  "#FF5722"
  ];

function change(){
      。。。
}

function changeV() {
     。。。
}


(function drawFrame(){
    window.requestAnimationFrame(drawFrame, canvas);
    context.clearRect(0, 0, W, H);

    。。。
}())

注意這里的的context, W, H等我們定義的是全局變量。
這里有兩個(gè)變量可能你不知道他是干什么的gridXgridY,之后我會詳細(xì)介紹。

5.shape.js 文件

這個(gè)文件是我們整個(gè)動畫效果的核心,只有理解了它,你才能了解這個(gè)效果的實(shí)現(xiàn)原理。因?yàn)椴皇呛荛L,這里我把文件全部列出:

function Shape(x, y, texte){
        this.x = x;
        this.y = y;
        this.size = 200;
        this.text = texte;
        this.placement = [];
    }
Shape.prototype.getValue = function(){
         context.textAlign = "center";
         context.font =  this.size + "px arial";
         context.fillText(this.text, this.x, this.y);

         var idata = context.getImageData(0, 0, W, H);
         var buffer32 = new Uint32Array(idata.data.buffer);

         for(var j=0; j < H; j += gridY){
             for(var i=0 ; i < W; i += gridX){
                 if(buffer32[j * W + i]){
                     var particle = new Particle(i, j, type);
                     this.placement.push(particle);
                 }
             }
         }
         
         context.clearRect(0, 0, W, H);
}

接下來,我就詳細(xì)的解一下該文件的代碼!首先我們新建了一個(gè)構(gòu)造函數(shù)Shape,該構(gòu)造函數(shù)有3個(gè)參數(shù):

x , y: 要繪制的文字的位置

texte: 要繪制的文字

我們設(shè)置了文字的大小為200px, 并且定義了一個(gè)屬性placement,這個(gè)屬性是一個(gè)數(shù)組。so wired!它是干什么的呢?別急,繼續(xù)往下走。

接下來我們在原型對象上定義了一個(gè)方法getValue.這幾行代碼:

 context.textAlign = "center";
 context.font =  this.size + "px arial";
 context.fillText(this.text, this.x, this.y);

很簡單,設(shè)置文字對其方式,字體大小,并且通過fillText()在canvas上繪制文字。如果此時(shí)在控制欄中輸入文字,在index.js中新建一個(gè)shape對象,并把文字傳入,再調(diào)用getValue方法就可以看到你已經(jīng)把輸入的文字繪制到了canvas中,當(dāng)然這時(shí)候忽略下面的代碼啊!

回到正題,接下來我們調(diào)用了context.getImageData(),它是canvas繪制圖片的API接口,通過它我們可以得到需要繪制的圖片的數(shù)據(jù)內(nèi)容。也許你會問,它是用來獲取canvas上繪制的圖片的數(shù)據(jù)內(nèi)容,可是我們這并沒有繪制圖片啊?

其實(shí),該方法的作用并不只是局限于獲取圖片的內(nèi)容。只要canvas上有內(nèi)容,不管是繪制的文字,還是圖形它都能獲取,甚至是空白的canvas它也能獲取,只不過此時(shí)的數(shù)據(jù)都是0。

那么通過該API獲取的內(nèi)容是什么樣的呢?首先,我們嘗試獲取一張空canvas的內(nèi)容

var canvas = document.getElementById("canvas"),
    context = canvas.getContext("2d");
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
    console.log(imgData); 

結(jié)果如下:

我們看到,這里的imgData是一個(gè)對象,該對象的第一個(gè)屬性就是data,是一個(gè)8位無符號整數(shù)的類型化數(shù)組Uint8ClampedArray。打開data看看都有什么,這里我隨便打開其中的一個(gè)看看。

因?yàn)閏anvas為空,所以數(shù)據(jù)都為零?,F(xiàn)在我們換一下,在canvas中畫一個(gè)藍(lán)色的矩形。

context.fillStyle = "#49f";
context.fillRect(0, 0, canvas.width,canvas.height);
var imgData = context.getImageData(0, 0, canvas.width, canvas.height);
console.log(imgData);

看看,我們的的數(shù)據(jù)是不是不為零了!OK! 原理我在這解釋的都差不多了,我們回到正題,看下一行代碼。

 var buffer32 = new Uint32Array(idata.data.buffer);

idata.data.buffer ,在這里我們調(diào)用Uint8ClampedArray對象的buffer屬性,獲取此數(shù)組引用的 ArrayBuffer。然后將它傳入U(xiǎn)int32Array對象(32位無符號整數(shù)值的類型化數(shù)組)。此時(shí),我們看看上面繪制藍(lán)色矩形的數(shù)據(jù)變成什么樣了,首先數(shù)組長度變?yōu)閇160000],剛好是上面的8位的四分之一

內(nèi)容變?yōu)?/p>

相當(dāng)于我們把一張圖片的分辨率縮小了,以前有640000個(gè)數(shù)據(jù), 現(xiàn)在只有160000個(gè)數(shù)據(jù)。當(dāng)然,在本文中數(shù)據(jù)的內(nèi)容不是我們所關(guān)心的。我們所關(guān)心的是在哪有數(shù)據(jù)。

所以,接下來,就是在有數(shù)據(jù)的地方,放上我們的粒子

for(var j=0; j < H; j += gridY){
             for(var i=0 ; i < W; i += gridX){
                 if(buffer32[j * W + i]){
                     var particle = new Particle(i, j, type);
                     this.placement.push(particle);
                 }
             }
         }

 context.clearRect(0, 0, W, H); //清除所畫內(nèi)容

我們遍歷整個(gè)canvas, 通過buffer32[j * W + i]來判斷這個(gè)位置的數(shù)據(jù)是否為空,如果不為空,那么,在這繪制一個(gè)粒子。粒子的位置為(i,j)我們作為參數(shù)傳入。當(dāng)然你也可以在數(shù)據(jù)為空的地方放上粒子,看看會出現(xiàn)什么樣的效果。

這里用到了gridX和gridY,它們的作用是來判斷每個(gè)多少個(gè)距離取一次數(shù)據(jù)。學(xué)過信號抽樣的同學(xué)應(yīng)該很好理解,如果你間隔大,抽樣得到的數(shù)據(jù)就小,反之如果你設(shè)定的間隔小,那么抽到的數(shù)據(jù)就多。在我們的效果中,我們繪制的是文字,同樣的道理,間隔小獲取的數(shù)據(jù)就多,粒子就多,組成的文字就完整。間隔大獲取的就少。那么粒子組成的文字就不那么完整,這兩個(gè)變量的值,通過分辨率控件來綁定。思來想去還是上張圖吧!

6.particles.js 文件

該文件就是我們的粒子文件,我就不做過多解釋了,不懂得歡迎提問。

7.粒子切換

粒子切換的代碼在slide.js中,很簡單,就是綁定了兩個(gè)事件。

/粒子切換
var ball = document.getElementById("ball");
var rect = document.getElementById("rect");

function chose(particleName){
    particleName.addEventListener("click", function(e){
        this.style.backgroundColor = "orange";
        (particleName == ball ? rect : ball).style.backgroundColor = "rgba(0, 0, 0, 0)";
        type = (type === "ball" ? "rect" : "ball");
        change();
        
    }, false)
}

chose(ball);
chose(rect);

Ok!這個(gè)效果的關(guān)鍵點(diǎn),基本都已經(jīng)講完了,有興趣自己看看吧?。?!

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

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

相關(guān)文章

  • 周一點(diǎn)canvas動畫》——canvas特效插件

    摘要:很長時(shí)間沒有更新文章了,經(jīng)過幾個(gè)月的時(shí)間,事情終于忙完了。今天,在這里為大家分享款特效插件,與其說是分享,不如說是為了方便使用,對前面章節(jié)的一些效果的封裝。前面的文章在我修改完善后會逐漸上傳。 很長時(shí)間沒有更新文章了,經(jīng)過幾個(gè)月的時(shí)間,事情終于忙完了。今天,在這里為大家分享3款canvas特效插件,與其說是分享,不如說是為了方便使用,對前面章節(jié)的一些效果的封裝。 1. Martrix....

    Berwin 評論0 收藏0
  • Codepen 每周精選:展現(xiàn) WEB 魅力的 26 個(gè)頁面特效(2018-6-4)

    摘要:按下右側(cè)的點(diǎn)擊預(yù)覽按鈕可以在當(dāng)前頁面預(yù)覽,點(diǎn)擊鏈接可以打開原始頁面。 按下右側(cè)的點(diǎn)擊預(yù)覽按鈕可以在當(dāng)前頁面預(yù)覽,點(diǎn)擊鏈接可以打開原始頁面。 1. 一個(gè)正 20 面體的骰子https://codepen.io/chrisvfrit... 2. 純 css 寫的夜間景色的視差滾動效果https://codepen.io/danbhala/p... 3. 機(jī)器人喝油的動畫https://co...

    AlexTuan 評論0 收藏0

發(fā)表評論

0條評論

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