canvas結(jié)合三角函數(shù)實現(xiàn)一個視頻直播效果

canvas可以說是html5其中的一大亮點,有了它,我們可以基于canvas畫布實現(xiàn)很多之前只有flash和視頻才能實現(xiàn)的效果。廢話少說,先上效果。

canvas結(jié)合三角函數(shù)實現(xiàn)一個視頻直播效果

* {

margin: 0;

padding: 0;

}

html,

body {

font-size: 0;

height: 100%;

}

canvas {

background: #000;

}

(function (document) {

class Point {

constructor(option) {

this.x = option.context.canvas.width / 1.5;//對象的X坐標(biāo)

this.y = Math.random() * option.context.canvas.height/2 + option.context.canvas.height / 2 ;//對象的Y坐標(biāo)

this.defaultX = this.x;

this.defaultY = this.y;

this.img = option.img;

this.angle = Math.random()*360 | 0;

this.context = option.context;

this.width = this.context.canvas.width;

this.height = this.context.canvas.height;

this.speedX = 0;//元素在x軸上的速度,下面要通過三角函數(shù)來實現(xiàn)。

this.speedY = -4* Math.random() - 8;

this.alpha = 1;

this.render();

}

render() {

var {

context,

img,

x,

y

} = this;

context.save();

context.globalAlpha = this.alpha ;

context.drawImage(img, x, y,img.width/2,img.height/2);

context.restore();

}

animate() {

this.angle +=3;

this.angle %= 360;

this.speedX = 4* Math.sin(this.angle/180*Math.PI*2);

this.x += this.speedX;

this.y += this.speedY;

var {width,height} = this;

this.alpha = this.y / height / 2 + .2;

if (Math.abs(this.y <= height / 2)) {

this.y = height;

this.angle = Math.random() * 360 | 0;

this.alpha = 1;

this.x = this.defaultX;

}

this.render();

}

}

var zmitiUtil = {

viewW: window.innerWidth,

viewH: window.innerHeight,

init() {

this.setSize();

this.createParticals();

this.animate();

},

setSize() {

this.canvas = document.querySelector('#canvas');

this.context = this.canvas.getContext('2d');

this.canvas.width = this.viewW;

this.canvas.height = this.viewH;

},

createParticals(){

this.particals = [];

var img = new Image();

var self = this;

img.onload = function(){

var _this = this;//這里面this指向的是img對象

for (var i = 0; i < 30; i++) {

self.particals.push(new Point({

img: _this,

context: self.context

}))

}

}

img.src = './images/heart.png';

},

animate(){

var _this = this;

(function render(){//這里面this 發(fā)生了變化,請注意哦,因為出現(xiàn)了function 哦

requestAnimationFrame(render);

_this.context.clearRect(0,0,_this.viewW,_this.viewH);

_this.particals.forEach(partical => {

partical.animate();

})

})();

}

};

zmitiUtil.init();

})(document);

技術(shù)總結(jié):

先來簡單回顧下高中的正弦曲線

我們會發(fā)現(xiàn),圖中的曲線和我們的效果是反著來的,所以我們要把x,y對應(yīng)的調(diào)換下位置即可,運動起來就會在X軸的速度上體現(xiàn)出來了。具體可參考下源代碼。

簡單的解釋下 this.speedX = 4* Math.sin(this.angle/180*Math.PI); this.angle為當(dāng)前的角度,取值范圍為:[0,360],js提供的三角函數(shù)是要接收一下弧度的,所以我們需要轉(zhuǎn)一下。

解釋 this.angle = Math.random() * 360 | 0; // 有的可能不太知道后面的 ”| 0“是什么意思,本屌之前也不知道是什么意思,自己試,多試幾次,于是就知道了,這個是去掉了小數(shù)的部分,相當(dāng)于 Math.floor() , 但要問這是什么原理,好像是二進(jìn)制的算法,其實我也不知道,但我知道這個用法就行了。

注意下這個代碼里在的有幾個地方涉及到了this的指向問題哦。我在代碼中已有注釋。

像這種粒子動畫的實現(xiàn)原理,先實現(xiàn)一個粒子的動畫,然后循環(huán)生成一堆,把所有的push到一個數(shù)組中去。然后用動畫函數(shù)遍歷數(shù)組,執(zhí)行數(shù)組中的每一個對象的運動函數(shù)。

html5 canvas 畫布一是無狀態(tài)的機制。像類似 context 的 globalAlpha,translate,rotate等一些屬性在操作之前需要加上context.save();在后面再context.restore();代碼中也有體現(xiàn)。如果我們不加上context.save()那么,會給所有的粒子都設(shè)置了相同的透明試,這可不是我想要的。

ES6的類的創(chuàng)建,解構(gòu)賦值。

寫在最后:

我們可以看到很漂亮的數(shù)學(xué)曲線,應(yīng)用到web頁面上,充分體現(xiàn)出了數(shù)學(xué)之美。希望大家在學(xué)習(xí)上遇到一些自己不懂的寫法,一定要自己先去嘗試,一定要自己嘗試,還要要想盡辦法應(yīng)該到你們的項目中,這樣我們印象才深刻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容