国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > HTML5 > 正文

canvas簡單連線動畫的實現代碼

2024-09-05 07:23:15
字體:
來源:轉載
供稿:網友

前言:canvas動畫入門系列之簡單連線動畫。雖然簡單,但連線動畫應用場景還挺多,因此做了個小demo,一通百通。

step1:繪制點

首先創建個標簽<canvas id="canvas"></canvas>
設置幾個點的坐標

   const points = [        [200, 100], //上        [300, 200], //右        [100, 200], //左        [200, 100], //上        [200, 300], //下        [100, 200], //左        [300, 200], //右        [200, 300]      ];      const canvas = document.querySelector("canvas");      const ctx = canvas.getContext("2d");

然后把點給畫出來

points.forEach(([x, y]) => {          drawDot(x, y);        });function drawDot(x1, y1, r) {          ctx.save();          ctx.beginPath(); //不寫會和線連起來          ctx.fillStyle = "red";          //繪制成矩形          ctx.arc(x1, y1, r ? r : 2, 0, 2 * Math.PI);          ctx.fill();          ctx.restore();        }

step2:繪制線條

我們封裝一個方法,傳入起點終點,繪制一根線條

function drawLine(x1, y1, x2, y2) {          ctx.save();          ctx.beginPath(); //不寫每次都會重繪上次的線          ctx.lineCap = "round";          ctx.lineJoin = "round";          var grd = ctx.createLinearGradient(x1, y1, x2, y2);          ctx.moveTo(x1, y1);          ctx.lineTo(x2, y2);          ctx.closePath();          ctx.strokeStyle = "rgba(255,255,255,1)";          ctx.stroke();          ctx.restore();        }

step3:線條動畫

這里面需要計算兩點之間的斜率,然后x坐標每次挪動±1單位,已知斜率和x偏移,即可計算出y的偏移。值得注意的是,這個坐標系和數學中的xy坐標系有點不一樣,y軸是反的。然后可以引入額外的參數speed控制速度

function lineMove(points) {          if (points.length < 2) {                          return;          }          const [[x1, y1], [x2, y2]] = points;          let dx = x2 - x1;          let dy = y2 - y1;          if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {            points = points.slice(1);            lineMove(points);            return;          }          let x = x1,            y = y1; //線條繪制過程中的終點          if (dx === 0) {            (x = x2), (y += (speed * dy) / Math.abs(dy));          } else if (dy === 0) {            x += (speed * dx) / Math.abs(dx);            y = y2;          } else if (Math.abs(dx) >= 1) {            let rate = dy / dx;            x += (speed * dx) / Math.abs(dx);            y += (speed * rate * dx) / Math.abs(dx);          }          drawLine(x1, y1, x, y);          points[0] = [x, y];          window.requestAnimationFrame(function() {            lineMove(points);          });        }

主要代碼就這么多,先看效果

完整代碼

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8" />  <meta name="viewport" content="width=device-width, initial-scale=1.0" />  <meta http-equiv="X-UA-Compatible" content="ie=edge" />  <title>canvas-連線動畫</title></head><body>  <canvas id="canvas" width="400" height="400"></canvas>  <script>    //起點:10,20 終點:150,200    const points = [      [200, 100], //上      [300, 200], //右      [100, 200], //左      [200, 100], //上      [200, 300], //下      [100, 200], //左      [300, 200], //右      [200, 300]    ];    const canvas = document.querySelector("canvas");    const ctx = canvas.getContext("2d");    // const img = new Image();    const speed = 10; //速度    // img.onload = function() {    // canvas.width = img.width;    // canvas.height = img.height;    animate(ctx);    // };    // img.src = "./imgs/demo.png";    function animate(ctx) {      // ctx.drawImage(img, 0, 0);      ctx.fillRect(0, 0, canvas.width, canvas.height);      points.forEach(([x, y]) => {        drawDot(x, y);      });      lineMove(points);    }    function lineMove(points) {      if (points.length < 2) {        return;      }      const [[x1, y1], [x2, y2]] = points;      let dx = x2 - x1;      let dy = y2 - y1;      if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {        points = points.slice(1);        lineMove(points);        return;      }      let x = x1,        y = y1; //線條繪制過程中的終點      if (dx === 0) {        (x = x2), (y += (speed * dy) / Math.abs(dy));      } else if (dy === 0) {        x += (speed * dx) / Math.abs(dx);        y = y2;      } else if (Math.abs(dx) >= 1) {        let rate = dy / dx;        x += (speed * dx) / Math.abs(dx);        y += (speed * rate * dx) / Math.abs(dx);      }      drawLine(x1, y1, x, y);      points[0] = [x, y];      window.requestAnimationFrame(function () {        lineMove(points);      });    }    function drawLine(x1, y1, x2, y2) {      ctx.save();      ctx.beginPath(); //不寫每次都會重繪上次的線      ctx.lineCap = "round";      ctx.lineJoin = "round";      var grd = ctx.createLinearGradient(x1, y1, x2, y2);      ctx.moveTo(x1, y1);      ctx.lineTo(x2, y2);      ctx.closePath();      ctx.strokeStyle = "rgba(255,255,255,1)";      ctx.stroke();      ctx.restore();    }    function drawDot(x1, y1, r) {      ctx.save();      ctx.beginPath(); //不寫會和線連起來      ctx.fillStyle = "red";      //繪制成矩形      ctx.arc(x1, y1, r ? r : 2, 0, 2 * Math.PI);      ctx.fill();      ctx.restore();    }  </script></body></html>

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 赤水市| 即墨市| 建德市| 靖西县| 荆州市| 荥阳市| 洞头县| 色达县| 科尔| 土默特右旗| 台东市| 杨浦区| 合川市| 安乡县| 弋阳县| 吴江市| 吉林市| 荆州市| 东海县| 平乐县| 东乡县| 鄯善县| 济阳县| 南丰县| 松溪县| 平利县| 龙胜| 高邑县| 白朗县| 独山县| 南澳县| 乌拉特后旗| 凤城市| 平顶山市| 清涧县| 康乐县| 昌平区| 上高县| 怀宁县| 天镇县| 安义县|