摘要:好看漂亮的網頁特效學習筆記猜猜下一個顏色是什么分步詳細解釋第一步很簡單的初始化函數。繪制新的火焰紅色的圓以及火花之前元素,即新的火焰紅色的圓以及火花的生命周期未完的話,就繼續更新它,否則就刪除它第五步以火焰為粒子。
效果:
逼真的火焰跟隨鼠標,還冒出火花,照亮背景文字
使用canvas繪制
使用javascript,但并無復雜邏輯。上手程度:簡單
歡迎來我的博客看此文章: https://clatterrr.com/archive...
源碼:演示地址:https://clatterrr.github.io/f...
源碼已在下方給出,或者訪問github代碼倉庫https://github.com/clatterrr/...
學習筆記: google字體在上一篇中已講過。好看漂亮的html5網頁特效學習筆記(3)_猜猜下一個顏色是什么?
javascript分步詳細解釋
很簡單的初始化函數。
var oCanvas;
init = function()
{
oCanvas = new Fire();
oCanvas.run();
}
window.onload = init;
第二步:
初始化canvas,定義各種基礎的東西,以及為鼠標添加事件監測。addEventListener第三個參數的意思是,若為false,則為事件處理順序為先進先處理,為true則為先進后處理。具體請看https://www.runoob.com/jsref/...
var Fire = function(){
this.canvas = document.getElementById("fire");
this.ctx = this.canvas.getContext("2d");
this.canvas.height = window.innerHeight;
this.canvas.width = window.innerWidth;
this.aFires = [];
this.aSpark = [];
this.aSpark2 = [];
this.mouse = {
x : this.canvas.width * .5,
y : this.canvas.height * .75,
}
//一旦鼠標移動,就更新this.mouse.x和this.mouse.y,因為設置了false,所以先進來的事件先處理
this.canvas.addEventListener("mousemove", this.updateMouse.bind( this ), false);
}
Fire.prototype.updateMouse = function( e ){
this.mouse.x = e.clientX;
this.mouse.y = e.clientY;
}
第三步:
使用requestAnimationFrame使下一幀重新運行一遍run函數。為什么不用setInterval呢?因為內在運行機制會讓它運行速度隨機器性能變化而變化,導致時間控制不精確。而requestAnimationFrame使用系統時間,保證每秒執行60次。參考:https://www.cnblogs.com/xiaoh...
并用bind()方法創建一個新的函數,在bind()被調用時,這個新函數的this被bind的第一個參數指定,其余的參數將作為新函數的參數供調用時使用。參考:https://developer.mozilla.org...
Fire.prototype.run = function(){
//重新新繪制火焰和火花
this.update();
this.draw();
//穩定重繪畫面
requestAnimationFrame( this.run.bind( this ) );
}
第四步:
重新繪制一個火焰(實際上是紅色的圓)和兩個火花(實際上是小長方形)。若有火焰或火花的生命周期完了,那么就用刪除它。否則繼續更新它。
注意火焰火花原本被存儲在數組里,所以刪除用slice就好了。
Fire.prototype.update = function(){
//繪制新的火焰(紅色的圓)以及火花
this.aFires.push( new Flame( this.mouse ) );
this.aSpark.push( new Spark( this.mouse ) );
this.aSpark2.push( new Spark( this.mouse ) );
//之前元素,即新的火焰(紅色的圓)以及火花的生命周期未完的話,就繼續更新它,否則就刪除它
for (var i = this.aFires.length - 1; i >= 0; i--) {
if( this.aFires[i].alive )
this.aFires[i].update();
else
this.aFires.splice( i, 1 );
}
for (var i = this.aSpark.length - 1; i >= 0; i--) {
if( this.aSpark[i].alive )
this.aSpark[i].update();
else
this.aSpark.splice( i, 1 );
}
for (var i = this.aSpark2.length - 1; i >= 0; i--) {
if( this.aSpark2[i].alive )
this.aSpark2[i].update();
else
this.aSpark2.splice( i, 1 );
}
}
第五步:
以火焰為粒子。部分注釋在代碼中。先使用構造函數確定火焰的各項參數。若火焰被更新,那么就更新它的坐標,生命周期,以及用生命周期計算顏色。這里的顏色使用的是HSLA顏色,參考:http://caibaojian.com/css3/va...。
火花的構造參數和更新參數也是一樣的。
var Flame = function( mouse ){
//鼠標坐標
this.cx = mouse.x;
this.cy = mouse.y;
//隨機在鼠標周圍產生
this.x = rand( this.cx - 25, this.cx + 25);
this.y = rand( this.cy - 5, this.cy + 5);
//隨機變量,橫軸縱軸以及半徑的變化
this.vy = rand( 1, 3 );
this.vx = rand( -1, 1 );
this.r = rand( 20, 30 );
//生命周期
this.life = rand( 3, 6 );
this.alive = true;
//用于繪制火焰顏色
this.c = {
h : Math.floor( rand( 2, 40) ),
s : 100,
l : rand( 80, 100 ),
a : 0,
ta : rand( 0.8, 0.9 )
}
}
Flame.prototype.update = function()
{
//y坐標變化
this.y -= this.vy;
this.vy += 0.05;
//x坐標變化
this.x += this.vx;
if( this.x < this.cx )
this.vx += 0.1;
else
this.vx -= 0.1;
//半徑變化
if( this.r > 0 )
this.r -= 0.1;
if( this.r <= 0 )
this.r = 0;
//計算生命周期,根據生命周期計算火焰顏色
this.life -= 0.15;
if( this.life <= 0 ){
this.c.a -= 0.05;
if( this.c.a <= 0 )
this.alive = false;
}else if( this.life > 0 && this.c.a < this.c.ta ){
this.c.a += .08;
}
}
第六步:
canvas的主場,繪制背景,包括黑色背景,文字FIRE,以及一個跟隨在火焰后的暗紅色大圓。這個大圓大圓,更像是墻壁的上的投影,需要仔細一點才能發現。canvas參考https://www.w3school.com.cn/t...,自己一個函數一個函數慢慢去查才能加深印象。
注意globalCompositeOperation的參數soft-light和color-dodge似乎國內網站都沒找到解釋,只在英文mdn上看到了樣例。參考:
https://developer.mozilla.org...
Fire.prototype.draw = function(){
//繪制背景
this.ctx.globalCompositeOperation = "source-over";
this.ctx.fillStyle = "rgba( 15, 5, 2, 1 )";
this.ctx.fillRect( 0, 0, window.innerWidth, window.innerHeight );
//定義漸變顏色樣式
this.grd = this.ctx.createRadialGradient( this.mouse.x, this.mouse.y - 200,200,this.mouse.x, this.mouse.y - 100,0 );
this.grd.addColorStop(0,"rgb( 15, 5, 2 )");
this.grd.addColorStop(1,"rgb( 30, 10, 2 )");
//繪制一個圓形,并使用顏色漸變樣式。這個圓是一個暗紅色的大圓
//跟隨在火焰后的大圓,更像是墻壁的上的投影,需要仔細一點才能發現
this.ctx.beginPath();
this.ctx.arc( this.mouse.x, this.mouse.y - 100, 200, 0, 2*Math.PI );
this.ctx.fillStyle= this.grd;
this.ctx.fill();
//繪制文字Fire
this.ctx.font = "15em Amatic SC";
this.ctx.textAlign = "center";
this.ctx.strokeStyle = "rgb(50, 20, 0)";
this.ctx.fillStyle = "rgb(120, 10, 0)";
this.ctx.lineWidth = 2;
this.ctx.strokeText("Fire",this.canvas.width/2, this.canvas.height * .72 );
this.ctx.fillText("Fire",this.canvas.width/2, this.canvas.height * .72 );
//繪制火焰
this.ctx.globalCompositeOperation = "overlay";
for (var i = this.aFires.length - 1; i >= 0; i--)this.aFires[i].draw( this.ctx );
//繪制粒子
this.ctx.globalCompositeOperation = "soft-light";
for (var i = this.aSpark.length - 1; i >= 0; i--)
if( ( i % 2 ) === 0 )
this.aSpark[i].draw( this.ctx );
//繪制粒子2
this.ctx.globalCompositeOperation = "color-dodge";
for (var i = this.aSpark2.length - 1; i >= 0; i--) this.aSpark2[i].draw( this.ctx );
}
最后一步:
最關鍵但也很簡單的地方,就是真正的繪制火焰和火花啦。beginpath(),arc(),fillstyle()和fill()都是canvas的方法。慢慢查找資料吧。只是注意這兒的顏色用的是hsla顏色而不是rgba顏色哦。
Flame.prototype.draw = function( ctx ){
ctx.beginPath();
ctx.arc( this.x, this.y, this.r * 3, 0, 2*Math.PI );
ctx.fillStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + (this.c.a/20) + ")";
ctx.fill();
ctx.beginPath();
ctx.arc( this.x, this.y, this.r, 0, 2*Math.PI );
ctx.fillStyle = "hsla( " + this.c.h + ", " + this.c.s + "%, " + this.c.l + "%, " + this.c.a + ")";
ctx.fill();
}
完整源碼:
Canvas實現火焰跟隨鼠標動畫
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.hztianpu.com/yun/116336.html
摘要:對于來說,表示元素,除了優先級更高之外,與選擇器相同。從父元素繼承顏色漸變背景漂亮的深藍淺藍效果就是這個的作用。媒體查詢,簡單來說就是可以讓網頁自動適應不同的設備屏幕尺寸。具體請看貝塞爾曲線,用來生成水墨效果的關鍵。 showImg(https://segmentfault.com/img/bVbwNaj); 效果 鼠標觸碰按鈕,出現水墨風格動畫 屏幕自適應 一份html文件,一份c...
摘要:對于來說,表示元素,除了優先級更高之外,與選擇器相同。從父元素繼承顏色漸變背景漂亮的深藍淺藍效果就是這個的作用。媒體查詢,簡單來說就是可以讓網頁自動適應不同的設備屏幕尺寸。具體請看貝塞爾曲線,用來生成水墨效果的關鍵。 showImg(https://segmentfault.com/img/bVbwNaj); 效果 鼠標觸碰按鈕,出現水墨風格動畫 屏幕自適應 一份html文件,一份c...
摘要:定義標準的文本。然后看看函數的定義自啟動來按下按鈕的時差不能超過最大持續時間重新繪制菜單項的位置先用確定按下按鈕的時間,儲存在中。如果到了規定時間的話,就執行。然后再把取下的第一個當成第十三個接在最后面,又成了新的菜單排列。 showImg(https://segmentfault.com/img/bVbw1zV?w=818&h=479); 效果: 弧形菜單,文字按規則變形以及變換透...
摘要:表情繪制使用純代碼繪制。其它表情請看源代碼。當評分改變,這個高度很大的元素就向上移動,把需要的表情顯示出來。源碼不同投票不同表情 showImg(https://segmentfault.com/img/bVbwOQe?w=254&h=198); 特點: 根據不同評分顯示不同表情,并且這些表情看起來像是在一個傳送帶上可以滾動 使用純代碼(svg)繪制表情以及用于評分的星星 html+...
摘要:表情繪制使用純代碼繪制。其它表情請看源代碼。當評分改變,這個高度很大的元素就向上移動,把需要的表情顯示出來。源碼不同投票不同表情 showImg(https://segmentfault.com/img/bVbwOQe?w=254&h=198); 特點: 根據不同評分顯示不同表情,并且這些表情看起來像是在一個傳送帶上可以滾動 使用純代碼(svg)繪制表情以及用于評分的星星 html+...
閱讀 1862·2023-04-25 19:51
閱讀 2073·2019-08-30 15:55
閱讀 2081·2019-08-30 15:44
閱讀 2831·2019-08-30 13:58
閱讀 2835·2019-08-29 16:37
閱讀 1213·2019-08-29 15:34
閱讀 4334·2019-08-29 11:05
閱讀 2802·2019-08-28 17:51