家好! 歡迎來到本教程,我們將深入了解使用 HTML 畫布和 JavaScript 在代碼中創建有趣的氣泡的世界。 最好的部分? 我們將只使用一點 HTML 和所有 JavaScript,而不是 CSS 來實現所有這一切。
今天,我們要掌握以下幾個概念:
使用畫布上下文的 arc 方法創建圓。
利用 requestAnimationFrame 函數實現平滑的圓形動畫。
利用 JavaScript 類的強大功能來創建多個圓圈,而無需重復代碼。
向我們的圓圈添加描邊樣式和填充樣式以獲得 3D 氣泡效果。
你可以跟著我一起看,或者如果你想看源代碼,可以使用最終的codepen
首先,我們需要一個 HTML5 Canvas 元素。 Canvas 是創建形狀、圖像和圖形的強大元素。 這就是氣泡將產生的地方。 讓我們來設置一下 -
<canvas id="canvas"></canvas>
為了使用畫布做任何有意義的事情,我們需要訪問它的上下文。 Context 提供了在畫布上渲染對象和繪制形狀的接口。
讓我們訪問畫布及其上下文。
const canvas = document.getElementById('canvas');
const context = canvas.getContext('2d');
我們將設置畫布以使用整個窗口的高度和寬度 -
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
讓我們通過添加一些 css 為畫布提供一個漂亮的舒緩淺藍色背景。 這是我們要使用的唯一 CSS。 如果您愿意,也可以使用 JavaScript 來完成此操作。
#canvas {
background: #00b4ff;
}
讓我們進入有趣的部分。 我們將通過單擊畫布來創建氣泡。 為了實現這一點,我們首先創建一個點擊事件處理程序:
canvas.addEventListener('click', handleDrawCircle);
由于我們需要知道在畫布上單擊的位置,因此我們將在句柄 DrawCircle 函數中跟蹤它并使用事件的坐標 -
//We are adding x and y here because we will need it later.
let x, y
const handleDrawCircle = (event) => {
x = event.pageX;
y = event.pageY;
// Draw a bubble!
drawCircle(x, y);
};
為了創建圓圈,我們將利用畫布上下文中可用的 arc 方法。 Arc 方法接受 x 和 y - 圓心、半徑、起始角和結束角,對于我們來說,這將是 0 和 2* Math.PI,因為我們正在創建一個完整的圓。
const drawCircle = (x, y) => {
context.beginPath();
context.arc(x, y, 50, 0, 2 * Math.PI);
context.strokeStyle = 'white';
context.stroke();
};
現在我們有了圓圈,讓我們讓它們移動,因為……
GIF
請記住,當我們創建圓時,我們使用了 arc 方法,它接受 x 和 y 坐標 - 圓的中心。 如果我們快速移動圓的 x 和 y 坐標,就會給人一種圓在移動的印象。 讓我們試試吧!
//Define a speed by which to increment to the x and y coordinates
const dx = Math.random() * 3;
const dy = Math.random() * 7;//Increment the center of the circle with this speed
x = x + dx;
y = y - dy;
我們可以將其移至函數內 -
let x, y;
const move = () => {
const dx = Math.random() * 3;
const dy = Math.random() * 7; x = x + dx;
y = y - dy;
};
為了讓我們的圓圈無縫移動,我們將創建一個動畫函數并使用瀏覽器的 requestAnimationFrame 方法來創建一個移動的圓圈。
const animate = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
move();
drawCircle(x,y); requestAnimationFrame(animate);
};//Don't forget to call animate at the bottom
animate();
現在我們已經創建了一個圓圈,是時候創建多個圓圈了!
但在我們創建多個圓圈之前,讓我們準備一下我們的代碼。為了避免重復我們的代碼,我們將使用類并引入 Particle 類。 粒子是我們動態藝術作品和動畫的構建塊。 每個氣泡都是一個粒子,具有自己的位置、大小、運動和顏色屬性。 讓我們定義一個 Particle 類來封裝這些屬性:
class Particle {
constructor(x = 0, y = 0) {}
draw() {
// Drawing the particle as a colored circle
// ...
} move() {
// Implementing particle movement
// ...
}
}
讓我們將一些已設置的常量移至 Particle 類 -
class Particle {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
this.radius = Math.random() * 50;
this.dx = Math.random() * 3;
this.dy = Math.random() * 7;
}
draw() {
// Drawing the particle as a colored circle
// ...
} move() {
// Implementing particle movement
// ...
}
}
draw 方法將負責在畫布上渲染粒子。 我們已經在drawCircle中實現了這個功能,所以讓我們將它移動到我們的類中并將變量更新為類變量
class Particle {
constructor(x = 0, y = 0) {
this.x = x;
this.y = y;
this.radius = Math.random() * 50;
this.dx = Math.random() * 3;
this.dy = Math.random() * 7;
this.color = 'white';
}
draw() {
context.beginPath();
context.arc(this.x, this.y, this.radius, 0, 2 * Math.PI);
context.strokeStyle = this.color;
context.stroke(); context.fillStyle = this.color;
context.fill();
} move() {}
}
同樣,讓我們在類中移動 move 函數 -
move() {
this.x = this.x + this.dx;
this.y = this.y - this.dy;
}
現在,我們需要確保在事件處理程序中調用 Particle 類。
const handleDrawCircle = (event) => {
const x = event.pageX;
const y = event.pageY;
const particle = new Particle(x, y);
};canvas.addEventListener('click', handleDrawCircle);
由于我們需要在 animate 函數中訪問該粒子,以便調用其 move 方法,因此我們將該粒子存儲在一個名為 molecularArray 的數組中。 當創建大量粒子時,這個數組也會很有幫助。 這是反映這一點的更新代碼 -
const particleArray = [];
const handleDrawCircle = (event) => {
const x = event.pageX;
const y = event.pageY; const particle = new Particle(x, y);
particleArray.push(particle);
};canvas.addEventListener('click', handleDrawCircle);
記得也要更新動畫功能 -
此時,您將在屏幕上看到這個粒子 -
驚人的! 現在,到了有趣的部分! 讓我們創建很多圓圈并設計它們的樣式,使它們看起來像氣泡。
為了創建大量氣泡,我們將使用 for 循環創建粒子并將它們添加到我們在此處創建的粒子數組中。
const handleDrawCircle = (event) => {
const x = event.pageX;
const y = event.pageY;
for (let i = 0; i < 50; i++) {
const particle = new Particle(x, y);
particleArray.push(particle);
}
};canvas.addEventListener('click', handleDrawCircle);
在動畫函數中,我們將通過清除畫布并在新位置重新繪制粒子來不斷更新畫布。 這會給人一種圓圈在移動的錯覺。
const animate = () => {
context.clearRect(0, 0, canvas.width, canvas.height);
particleArray.forEach((particle) => {
particle?.move();
particle?.draw();
}); requestAnimationFrame(animate);
};animate();
現在我們有了移動的氣泡,是時候給它們添加顏色,使它們看起來像氣泡了!
我們將通過向氣泡添加漸變填充來實現此目的。 這可以使用 context.createRadialGradient 方法來完成。
const gradient = context.createRadialGradient(
this.x,
this.y,
1,
this.x + 0.5,
this.y + 0.5,
this.radius
);
gradient.addColorStop(0.3, 'rgba(255, 255, 255, 0.3)');
gradient.addColorStop(0.95, '#e7feff');context.fillStyle = gradient;
恭喜! 您剛剛僅使用 HTML Canvas 和 JavaScript 創建了一些超級有趣的東西。 您已經學習了如何使用 arc 方法、利用 requestAnimationFrame、利用 JavaScript 類的強大功能以及使用漸變設計氣泡以實現 3D 氣泡效果。
請隨意嘗試顏色、速度和大小,使您的動畫真正獨一無二。
請隨意嘗試顏色、速度和大小,使您的動畫真正獨一無二。
我希望您在學習本教程時能像我在創建它時一樣獲得樂趣。 現在,輪到你進行實驗了。 我很想看看你是否嘗試過這個以及你創造了什么。 與我分享您的代碼鏈接,我很樂意查看。
說明:
======
1.1 環境:python3.8+matplotlib3.2+微軟編輯器vscode。
1.2 圓、sin和cos的關系:屬于基礎性知識,在數學可視化教學和計算機編程中廣泛被使用。
1.3 看起來簡單,但是提高思維,很重要。
1.4 熟悉matplotlib作圖和python編程基礎性知識,講解清楚,小白秒懂,適合普通人、數學愛好者和編程愛好者。
2 效果:
3 代碼講解:
========
3.1 第1步:導入模塊
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
3.2 第2步:初始化畫布和參數
#整體風格設置:深黑色背景顏色,這種設置比較方便
#注意應該放在最前面
plt.style.use('dark_background')
#畫布定義和大小設置:8,4=800和400
fig, ax= plt.subplots(1,1,figsize=(8,4))
plt.axis('equal') # 保證長寬相等
#x和y坐標刻度范圍
ax.set_xlim([0, 2*np.pi])
ax.set_ylim([-2.5, 2.5])
#sin和cos的x和y點坐標
x = np.linspace(0, 2*np.pi, 100)
ys = np.sin(x)
yc = np.cos(x)
3.3 第3步:圓和sin、cos的線條與圓點設置
#3-1 直線
#過圓心的水平x線
ax.plot(3*x - 3, 0*ys, linewidth=1, color='pink')
#圓心垂直y線
ax.plot(0*x, 2.5*ys, linewidth=1, color='pink')
#運動三個點的起始垂直y線
ax.plot(0*x+1, 2.5*ys, linewidth=1, color='blue')
#右側終點垂直y線
ax.plot(0*x+7.3, 2.5*ys, linewidth=1, color='blue')
#3-2 圓
#初始化圓的線條
ax.plot(np.cos(x), np.sin(x), linewidth=1,color='white')
#運動后的圓的再次覆蓋的圓線
circleLine, = ax.plot([], [],linewidth=4,color='green',label='circle')
#運動的圓的圓點
circleDot, = ax.plot([], [], 'o', color='yellow')
#3-3 sin
#初始化sin的線條
ax.plot(x + 1, np.sin(x), linewidth=1,color='yellow')
#sin運動后再次覆蓋的線條
sineLine, = ax.plot([], [], linewidth=4,color='red', label='sin')
#sin的運動的圓點
sineDot, = ax.plot([], [], 'o', color='blue')
#3-4 cos
#初始化cos的線條
ax.plot(x + 1, np.cos(x)-1, linewidth=1,color='green')
#cos運動后再次覆蓋的線條
cosLine, = ax.plot([], [], linewidth=4,color='pink',label='cos')
#cos的運動的圓點
cosDot, = ax.plot([], [], 'o', color='red')
3.4 第4步:動畫anim設置
def moveAnim(i):
# sin anim
sineLine.set_data(x[:i] + 1,ys[:i])
sineDot.set_data(x[i] + 1, ys[i])
# cos anim
cosLine.set_data(x[:i] + 1,yc[:i]-1)
cosDot.set_data(x[i] + 1, yc[i]-1)
# circle anim
circleLine.set_data(np.cos(x[:i]), np.sin(x[:i]))
circleDot.set_data(np.cos(x[i]), np.sin(x[i]))
3.5 第5步:動畫掛起和plt基本設置
#動畫掛起
anim = animation.FuncAnimation(fig, moveAnim, frames=len(x), interval=50)
#標題名
plt.title('circle-sin-cos-moving')
#plt.grid() #顯示網格
#保存
#HTML(anim.to_html5_video())
#anim.save('sine-py-effect.mp4', writer='ffmpeg')
plt.legend() #圖例默認展示
plt.show() #展示
4 附注:matplotlib版本查詢
====================
4.1 代碼:
import matplotlib
a=matplotlib.__version__
print(a)
4.2 效果圖:
5 畫圓的意義:
==========
5.1 鐘表的設置。
5.2 傅里葉級數變換。
5.3 數學教學的可視化。
5.4 等等。
滿滿的干貨,請收藏。
anvas畫了一個圓
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>canvas-3圓的繪制</title>
</head>
<body>
<canvas id="canvas1" width="600" height="600" style="border:1px solid #000000"></canvas>
<script type="text/javascript">
var canvas1 = document.querySelector("#canvas1") // 1.找到畫布對象
var ctx = canvas1.getContext("2d") // 2.上下文對象(畫筆)
// (圓心x:300, 圓心y:300, 半徑r:100, 開始角度:0 , 結束角度:360度, 默認為false(可不寫)是順時針,true為逆時針)
ctx.arc(300, 300, 100, 0, 2*Math.PI)
ctx.stroke()
</script>
</body>
</html>
*請認真填寫需求信息,我們會在24小時內與您取得聯系。