Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
canvas 兩種拖尾效果實現煙花:視覺盛宴的代碼藝術
**引言**
在Web前端開發領域,HTML5 Canvas以其強大的圖形渲染能力,為開發者提供了無限可能。本文將聚焦于如何利用Canvas API創建出絢麗奪目的煙花特效,并重點解析兩種不同風格的煙花拖尾效果實現方式。通過詳細的代碼示例和解析,你將學會如何打造一場屬于自己的線上煙火晚會,讓觀眾沉浸在美輪美奐的視覺盛宴之中。
## **一、基礎概念與準備工作**
### **1. 創建Canvas元素**
首先,在HTML中設置一個`canvas`元素作為畫布:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Canvas煙花特效</title>
<style>
canvas {
display: block;
margin: auto;
background-color: #000;
}
</style>
</head>
<body>
<canvas id="fireworksCanvas" width="800" height="600"></canvas>
<script src="fireworks.js"></script>
</body>
</html>
```
### **2. 獲取Canvas上下文**
在JavaScript文件(如上例中的`fireworks.js`)中獲取Canvas上下文:
```javascript
const canvas=document.getElementById('fireworksCanvas');
const ctx=canvas.getContext('2d');
```
## **二、基于點陣的煙花拖尾效果**
### **原理**
本方法采用點陣形式模擬煙花爆炸后的粒子軌跡,每個粒子隨著時間推移逐漸消散或淡出。
```javascript
class Particle {
constructor(x, y, speed, color) {
this.x=x;
this.y=y;
this.speed=speed;
this.color=color;
// 其他屬性...
}
update() {
// 更新粒子位置
this.y -=this.speed;
// 淡出處理...
}
draw(ctx) {
ctx.fillStyle=this.color;
ctx.beginPath();
ctx.arc(this.x, this.y, 1, 0, Math.PI * 2);
ctx.fill();
}
}
// 煙花類,包含多個粒子對象
class FireworkWithDotsTrail {
// 初始化、更新、繪制方法...
}
```
### **實現過程**
1. 在煙花發射時生成一組隨機位置、速度和顏色的粒子。
2. 每幀更新所有粒子的位置和透明度,并繪制到畫布上。
3. 當粒子超出屏幕或者透明度達到一定程度時,重新生成新的粒子以維持煙花的持續效果。
## **三、基于線條追蹤的煙花拖尾效果**
### **原理**
此方法通過連續記錄煙花移動路徑上的關鍵點,并連接這些點形成一條平滑的線條來展現拖尾效果。
```javascript
class FireworkWithLineTrail {
constructor(startX, startY, endX, endY, color) {
this.startX=startX;
this.startY=startY;
this.endX=endX;
this.endY=endY;
this.color=color;
this.trailPoints=[[startX, startY]];
}
update(position) {
this.endX=position.x;
this.endY=position.y;
this.trailPoints.push([this.endX, this.endY]);
// 清理過舊的軌跡點...
}
draw(ctx) {
ctx.beginPath();
ctx.strokeStyle=this.color;
for (let i=0; i < this.trailPoints.length - 1; i++) {
const [x1, y1]=this.trailPoints[i];
const [x2, y2]=this.trailPoints[i + 1];
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
}
ctx.stroke();
}
}
```
### **實現過程**
1. 初始化煙花發射位置和目標方向,創建一個包含起點坐標的軌跡點數組。
2. 每次煙花移動時,添加新的坐標點至軌跡點數組,并清理超出指定數量的舊軌跡點。
3. 繪制時,遍歷軌跡點數組并連線,形成拖尾效果。
## **四、完整示例及動畫循環**
為了實現動態效果,我們需要使用`requestAnimationFrame`進行動畫循環:
```javascript
function animate() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
fireworks.forEach((firework)=> firework.updateAndDraw());
requestAnimationFrame(animate);
}
// 初始化若干煙花實例并開始動畫循環
const fireworks=[/*...*/];
animate();
```
**結語**
通過以上介紹,我們成功地展示了如何利用Canvas技術在網頁上實現兩種不同的煙花拖尾效果。無論是點陣式的粒子軌跡,還是線條追蹤形成的連貫軌跡,都能帶給用戶強烈的視覺沖擊力。理解并掌握這兩種實現方式,無疑會讓你在Web前端設計與開發領域更加游刃有余,能夠創造出更多驚艷的交互式視覺體驗。而實際應用中,根據具體需求,還可以進一步優化細節,例如增加色彩漸變、粒子形狀變化等特性,使煙花特效更為豐富多樣。不斷探索Canvas的無窮魅力,你將在Web世界中描繪出屬于自己的璀璨星空!
教程
目錄:
1. 繪制靜態粒子圖形效果
2. 添加靜態粒子動畫效果
3. 添加粒子碰撞動畫效果
4. 添加粒子四面碰撞效果
基礎要求:
1. 了解基礎HTML標簽,例如canvas標簽
2. 了解Javascript的基礎知識
第一步: 生成靜態粒子圖形
生成靜態粒子圖形,我們將會使用到Canvas的如下相關方法:
context.fillRect(x, y, width, height);
context.arc(x, y, r, sAngle, eAngle, counterclockwise);
其中,使用fillRect方法生成了整個動畫場景,布滿了畫布全部區域,再使用arc方法來生成一個圓形,arc方法本身用來生成圓弧,但是如果生成一個360度的圓弧的話,就自然生成了圓形,完整代碼如下:
var canvas=document.getElementById('gbcanvas'),
context=canvas.getContext('2d');
var posX=30, //定義圓心X坐標
posY=30, //定義圓心Y坐標
particleRadius=30; //定義半徑
context.fillStyle='#E4E4E4';
context.fillRect(0,0,canvas.width,canvas.height); //生成畫布背景色
context.beginPath;
context.fillStyle='#dd4814';
context.arc(posX, posY, particleRadius, 0 , Math.PI*2, true);
context.closePath;
context.fill;
在線演示&調試地址
http://www.igeekbar.com/igclass/code/5392196c-400d-466c-b0cb-647bbc3469cc.htm
第二步: 生成粒子運行效果
動畫效果原理:
HTML5 畫布動畫生成原理,本質來說實現方式就是每隔固定時間段重新繪制畫布內的圖形,如下是代碼:
var canvas=document.getElementById('gbcanvas'),
context=canvas.getContext('2d'),
posX=30,
posY=30,
particleRadius=30;
//定義setInterval來隔特定時間生成粒子,如下
setInterval(function{
//為了能夠生成粒子移動效果,我們需要在每次繪制粒子之前清楚界面里的繪圖
context.fillStyle='#E4E4E4';
context.fillRect(0,0,canvas.width,canvas.height); //使用背景色填充
posX+=2;
posY+=1;
context.arc(posX, posY, particleRadius, 0, Math.PI*2, true);
}, 10);
以上代碼我們使用fillRect方法來先將整個背景色重新填充,再使用arc方法重新繪制圓形,來生成移動的效果
在線演示&調試地址
http://www.igeekbar.com/igclass/code/d2ff678f-23f1-4cab-9eba-9898d4393017.htm
第三步: 生成粒子碰撞效果
使用HTML5畫布生成一個粒子碰撞地面效果,并且同時添加相關重力加速度效果。
首先定義粒子x軸和y軸的運動速度及重力加速度,如下:
speedX=10, //定義一個X軸方向的速度
speedY=10, //定義一個Y軸方向的速度
gravity=1; //定義一個重力的參數,即重力加速度
然后,設置粒子運動速度,即每次繪制粒子圓心坐標的變化,如下:
//以下代碼設置運動速度
posX+=speedX;
posY+=speedY;
同時,保證Y軸擁有一個加速度效果,如下:
//添加重力加速度效果
speedY+=gravity;
最后,我們添加一個地面碰撞效果,判斷當粒子的中心Y軸低于canvas的高度減去粒子半徑,即粒子部分區域低于畫布最低端的時候,重新定義粒子的位置,如下:
//接下來我們添加地面反彈效果,只需要判斷當粒子運動到近畫布底端的時候,粒子Y軸坐標反向
if(posY > canvas.height - particleRadius){
speedY*=-0.5; //這里設置粒子速度為負值,修改此數值可以修改粒子Y軸運動速度損耗量
speedX*=0.5; //這里設置粒子X軸速度的損耗量
posY=canvas.height - particleRadius; //這里當粒子低于畫布最低端的時候,設置保證其不消失
}
在線演示&調試地址
http://www.igeekbar.com/igclass/code/8a3cfeb7-b052-4bf7-b3b1-8ec4e59584af.htm
第四步: 生成四面碰壁粒子效果
上面我們生成了粒子碰撞地面效果,本節我們添加粒子四面碰壁效果,基本代碼如下:
//判斷粒子位于畫布右側可顯示區域外
if(posX > canvas.width - particleRadius){
speedX*=-1;
posX=canvas.width - particleRadius;
}
//判斷粒子位于畫布左側可顯示區域外
if(posX < particleRadius){
speedX*=-1;
posX=particleRadius;
}
//最后添加頂端的反彈效果
if(posY < particleRadius){
speedY*=-1;
posY=particleRadius;
}
大家可以看到,代碼基本和碰撞地面效果類似,只不過判斷粒子中心所處的坐標位置來修改粒子運動的方向。
在線演示&調試地址
http://www.igeekbar.com/igclass/code/87784219-f527-4f52-bfb2-62cd82bbc07d.htm
Done!以上就是幾個HTML5實現粒子物理碰撞的例子, 希望大家能夠覺得有用, 有任何問題,請給我留言哈
沒有Canvas的年代,繪圖只能借助Flash,頁面不得不用JavaScript和Flash進行交互,而現在可以直接用Html5的canvas元素使用JavaScript在網頁上繪制圖形。
Canvas指定了尺寸,可以在這個范圍內任意繪制。
Canvas擁有多種繪制路徑、矩形、圓形、字符以及添加圖形的方法。
由于瀏覽器對HTML5標準支持不一致,所以通常在<canvas>的內部添加一些說明性HTML代碼,如果不支持將顯示其內部的HTML。
<canvas width="100" height="100" id="canva"> <p>您的瀏覽器版本暫不支持Canvas,請進行升級</p> </canvas>
var canvas=document.getElementById('canva'); if (canvas.getContext){ var ctx=canvas.getContext('2d'); // drawing code here } else { // canvas-unsupported code here }
Canvas的坐標系統以左上角為原點,水平向右為X軸,垂直向下為Y軸,以像素為單位,所以每個點都是非負整數。
?
Canvas只支持一種原生圖形的繪制:矩形。
所有其他圖形都至少需要生成一種路徑。
Canvas提供了幾種方式繪制矩形:
描述方法參數創建矩形rect(x,y,width,height)x:矩形左上角X坐標
y:矩形左上角的Y坐標
width:矩形的寬度,以像素計
height:矩形的高度,以像素計
繪制一個填充顏色的矩形,默認黑色fillRect(x,y,width,height)x:矩形左上角X坐標
y:矩形左上角的Y坐標
width:矩形的寬度,以像素計
height:矩形的高度,以像素計
繪制一個矩形邊框,默認黑色strokeRect(x,y,width,height)x:矩形左上角X坐標
y:矩形左上角的Y坐標
width:矩形的寬度,以像素計
height:矩形的高度,以像素計
在給定的矩形內清除指定的像素,然后這塊區域變完全透明clearRect(x,y,width,height)x:要清除的矩形左上角X坐標
y:要清除的矩形矩形左上角的Y坐標
width:要清除的矩形矩形的寬度,以像素計
height:要清除的矩形矩形的高度,以像素計
例如:
?
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>1.繪制矩形</title> <style> #canvas{ width: 500px; height: 200px; border: 1px solid red; } </style> </head> <body> <canvas id="canvas"></canvas> <script> window.onload=function () { var canvas=document.getElementById('canvas'); if (!canvas.getContext) return; var context=canvas.getContext('2d'); context.strokeRect(20,20,100,100); context.fillRect(30,30,80,80); context.clearRect(40,40,60,60); } </script> </body> </html>
圖形的基本元素是路徑。
路徑通過不同顏色和寬度的線段、曲線相連形成不同形狀的點集合。
一個路徑,甚至一個子路徑,都是閉合的。
步驟:
1. 創建路徑起始點 -- beginPath()
2. 使用畫圖命令畫出路徑 -- moveTo()等
3. 路徑封閉 -- closePath()
4. 一旦路徑生成即可通過描邊或填充路徑來渲染圖形 -- fill()
描述方法參數填充當前繪圖fill()
繪制已定義的路徑stroke()
起始一條路徑,或重置當前當前路徑beginPath()
把路徑以定到畫布指定點moveTo(x,y)x:路徑的目標位置的X坐標
y:路徑的目標位置的Y坐標
創建從當前點到起始點的路徑closePath()
添加一個新點,然后再畫布中創建從該點到最后指定點的線條lineTo(x,y)x:路徑的目標位置的X坐標
y:路徑的目標位置的Y坐標
從原始畫布剪切任意形狀和尺寸的區域clip()
創建二次貝賽爾曲線quadraticCurveTo(cpx,cpy,x,y)cpx:貝塞爾控制點的X坐標
cpy:貝塞爾控制點的Y坐標
x:結束點的X坐標
y:結束點的Y坐標
創建三次貝塞爾曲線bezierCurveTo(cp1x,cp1y,cp2x,cp2y,x,y)cp1x:第一個貝塞爾控制點的 x 坐標
cp1y:第一個貝塞爾控制點的 y 坐標
cp2x:第二個貝塞爾控制點的 x 坐標
cp2y:第二個貝塞爾控制點的 y坐標
x:結束點的 x 坐標
y:結束點的 y 坐標
創建弧、曲線(用于創建圓形或部分圓)arc(x,y,r,sAngle,eAngle,counterclockwise)x:圓的中心的 x 坐標
y:圓的中心的 y 坐標
r:圓的半徑
sAngle:起始角,以弧度計。(弧的圓形的三點鐘位置是 0 度)
eAngle:結束角,以弧度計
counterclockwise:可選,規定在逆時針還是在順時針繪圖,False=順時針,true=逆時針
創建兩切線之間的弧、曲線arcTo(x1,y1,x2,y2,r)x1:弧的起點的 x 坐標
y1:弧的起點的 y 坐標
x2:弧的終點的 x 坐標
y2:弧的終點的 y 坐標
r:弧的半徑
如果指定的點位于當前路徑中,則返回true,否則返回falseisPointInPath(x,y)x:測試的 x 坐標
y:測試的 y 坐標
延伸:
一次貝塞爾曲線
?
二次貝塞爾曲線
轉存失敗
重新上傳
取消
?
三次貝塞爾曲線
?
描述方法參數用于填充繪畫的顏色、漸變或模式fillStylecolor|gradient|pattern
color:css顏色值
gradient:用于填充繪圖的漸變對象(線性或放射性)
pattern:用于填充繪圖的 pattern 對象
用于筆觸的顏色、漸變或模式strokeStylecolor|gradient|pattern
color:css顏色值
gradient:用于填充繪圖的漸變對象(線性或放射性)
pattern:用于填充繪圖的 pattern 對象
用于陰影的顏色shadowColorcolor:css顏色值用于陰影的模糊級別shadowBlurnumber:模糊級別數陰影距形狀的水平距離shadowOffsetXnumber:正值或負值,定義陰影與形狀的水平距離陰影距形狀的垂直距離shadowOffsetYnumber:正值或負值,定義陰影與形狀的垂直距離
創建線性漸變createLinearGradient(x0,y0,x1,y1)x0:漸變開始點的 x 坐標 y0:漸變開始點的 y 坐標 x1:漸變結束點的 x 坐標 y1:漸變結束點的 y 坐標
在指定方向上重復指定的元素(元素可以是圖片、視頻,或者其他 <canvas> 元素)cratePattern(image,"repeat|repeat-x|repeat-y|no-repeat")image:規定要使用的圖片、畫布或視頻元素 "repeat:默認。該模式在水平和垂直方向重復 repeat-x:該模式只在水平方向重復 repeat-y:該模式只在垂直方向重復 no-repeat:該模式只顯示一次(不重復) "
創建放射狀、環形的漸變createRadialGradient(x0,y0,r0,x1,y1,r1)x0:漸變的開始圓的 x 坐標 y0:漸變的開始圓的 y 坐標 r0:開始圓的半徑 x1:漸變的結束圓的 x 坐標 y1:漸變的結束圓的 y 坐標 r1:結束圓的半徑
規定漸變對象中的顏色和停止位置addColorStop(stop,color)stop:介于 0.0 與 1.0 之間的值,表示漸變中開始與結束之間的位置
color: css 顏色值
線條的結束端點樣式lineCap"butt|round|square"
"
butt:默認。向線條的每個末端添加平直的邊緣
round:向線條的每個末端添加圓形線帽
square:向線條的每個末端添加正方形線帽
"
兩條線相交時,所創建的拐角類型lineJoin"bevel|round|miter"
"
bevel:創建斜角
round:創建圓角
miter:默認。創建尖角
"
當前的線條寬度lineWidthnumber:當前線條的寬度,以像素計
最大的斜接長度miterLimitnumber:正數。規定最大斜接長度。
如果斜接長度超過 miterLimit 的值,邊角會以 lineJoin 的 "bevel" 類型來顯示
描述方法參數當前字體屬性font
當前對齊方式textAlign
當前文本基線textBaseline
在畫布上繪制被填充的文本fillText()
在畫布上繪制未被填充的文本strokeText()
返回包含指定文本寬度的對象measureText()
描述方法參數在畫布上繪制圖像、畫布或視頻drawImageimg:規定要使用的圖形、畫布或視頻
sx:可選,開始剪切的X坐標位置
sy:可選,開始剪切的Y坐標位置
swidth:可選,被剪切圖形的寬度
sheight:可選,被剪切圖形的高度
x:在畫布上放置圖形的X坐標位置
y:在畫布上放置圖形的Y坐標位置
width:可選,要使用的圖形的寬度(伸展或縮小圖像)
height:可選,要使用的圖形的高度(伸展或縮小圖像)
返回ImageData對象的寬度width
返回ImageData對象的高度height
返回一個對象,其包含指定的ImageData對象的圖像數據data
創建新的、空白的ImageData對象crateImageData()
返回ImageData對象,該對象為畫布上指定的矩形復制像素數據getImageData()
把圖像數據(從指定的ImageData對象)放回畫布上putImageData()
描述方法參數重新映射畫布上的(0,0)位置translate()x:左右偏移量
y:上下偏移量
移動中心是坐標原點。
縮放當前繪圖至更大或更小scale()scaleWIdth:縮放當前繪圖寬度(1=100% 2=200%)
scaleHeight:縮放當前繪圖高度(1=100% 2=200%)
旋轉當前繪圖rotate()angel:旋轉角度,以弧度計,如需將角度轉換為弧度,以degrees * Matn.PI/180公式計算。順時針方向旋轉,旋轉中心是坐標原點。替換繪圖的當前轉換矩陣transform()a:水平縮放繪圖
b:水平傾斜繪圖
c:垂直傾斜繪圖
d:垂直縮放繪圖
e:水平移動繪圖
f:垂直移動繪圖
將當前轉換重置為單位矩陣,然后運行transform()setTransform()a:水平旋轉繪圖
b:水平傾斜繪圖
c:垂直傾斜繪圖
d:垂直縮放繪圖
e:水平移動繪圖
f:垂直移動繪圖
延伸:
1.translate:
?
2.rotate
轉存失敗
重新上傳
取消
?
描述方法參數設置或返回繪圖當前alpha或透明值globalAlphanumber:透明值,必須介于0.0-1.0之間設置或返回心圖形如何繪制到已有的圖像上globalCompositeOperation等多個屬性操作,略。。
描述方法參數保存當前環境的狀態save()
返回之前報錯過的路徑狀態和屬性restore()
createEvent()
getContext()
toDataURL()
基本步驟:
1. 在繪制每一幀動畫之前,需要清空所有canvas -- clearRect()
2. 保存canvas狀態
3. 繪制動畫圖形
4. 恢復canvas狀態
*請認真填寫需求信息,我們會在24小時內與您取得聯系。