整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          使用 HTML5 Canvas 和 JavaScript 開發動畫氣泡:分步教程


          家好! 歡迎來到本教程,我們將深入了解使用 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();
          };


          使用 requestAnimationFrame 方法移動圓圈

          現在我們有了圓圈,讓我們讓它們移動,因為……

          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>


          主站蜘蛛池模板: 波多野结衣一区二区免费视频| 91视频国产一区| 日韩一区二区三区免费体验| 伊人无码精品久久一区二区| 亚洲Av无码一区二区二三区| 国产精品久久久久久麻豆一区 | 免费看AV毛片一区二区三区| 日本一区二区三区精品视频| 亚洲AⅤ无码一区二区三区在线| 国产亚洲一区二区三区在线不卡| 亚洲AV综合色区无码一区爱AV | 亚洲AV无码一区二区三区在线观看| 国产精品乱码一区二区三区| 国产内射999视频一区| 波多野结衣一区二区| 一区二区三区四区无限乱码| 国产精品伦一区二区三级视频| 亚洲AV无码一区二区三区性色 | 精品一区二区三区在线播放视频| 亚洲AV无码一区二区三区牲色| 一区二区三区电影网| 亚洲国产一区在线观看| 北岛玲在线一区二区| 色窝窝无码一区二区三区色欲 | 一区二区三区在线|日本| 无码人妻精品一区二区| 国产无吗一区二区三区在线欢| 国产亚洲3p无码一区二区| 国产SUV精品一区二区四| 熟妇人妻一区二区三区四区| 亚洲av无码成人影院一区| 国产美女精品一区二区三区| 日韩美女在线观看一区| 精品久久一区二区| 福利一区二区三区视频午夜观看| 久久亚洲一区二区| 东京热无码一区二区三区av| 亚洲AV无码一区二区三区电影 | 日韩av无码一区二区三区| 日韩一区二区三区在线观看| 国产日本一区二区三区|