摘要:運動坐標變量坐標變量繪制方法畫布渲染清除畫布位置變化繪制繼續渲染動起來的多點多線動的是點,畫的是線給對象添加運動變量和兩個值表示點在軸和軸的運動量此處為在之間運動。
Canvas 點線動畫案例
arc(x, y, r, start, stop)
moveTo(x, y) 定義線條開始坐標lineTo(x, y) 定義線條結束坐標
fill()
stroke()1、畫一個點
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext("2d");
// 坐標(x, y)、半徑、開始角度、結束角度、順時針(逆時針) ctx.arc(70, 80, 30, 0, Math.PI * 2, false);2、畫很多點
//生成點 for (let i = 0; i < dotsNum; i ++) { x = Math.random() * canvas.width; y = Math.random() * canvas.height; r = Math.random() * 4; // 隨機生成 <4 的半徑值 ctx.beginPath(); ctx.arc(x, y, r, 0, 2 * Math.PI); ctx.fillStyle = "rgba(0,0,0,.8)"; ctx.fill(); ctx.closePath(); }3、畫兩點一線
確定兩個點的坐標 + lineTo 、moveTo
for (let i = 0; i < 2; i++) { ctx.beginPath() // 設置原點位置為(100,100),半徑為10 ctx.arc(100 + i * 150, 100 + i * 250, 10, 0, Math.PI * 2, false) // 兩個點進行畫線 ctx.moveTo(100, 100) ctx.lineTo(100 + i * 150, 100 + i * 250) // 設置線的寬度,單位是像素 ctx.lineWidth = 2 ctx.stroke() // 實心圓 - 填充顏色,默認是黑色 // 實心圓 - 畫實心圓 ctx.fill() ctx.closePath() }4、畫多點多線
當點很多、元素很多的時候再進行畫線操作會很繁瑣,對于多元素的情況,創建實例對象,把變量存儲在實例對象上。
var Dots = function () { // 畫布 this.canvas; this.ctx; // 畫點 this.x; this.y; this.r; };
Dots.prototype = { // 初始化點的方法 init: function (canvas) { this.canvas = canvas; this.ctx = this.canvas.getContext("2d"); this.x = Math.random() * this.canvas.width; this.y = Math.random() * this.canvas.height; this.r = Math.random() * 4; // 隨機生成 <4 的半徑值 this.ctx.beginPath(); this.ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI); this.ctx.fillStyle = "black"; this.ctx.fill(); this.ctx.closePath(); } };
// 繪制連線 for (var i = 0; i < dotsNum; i ++) { for (var j = i + 1; j < dotsNum; j ++) { var tx = dotsArr[i].x - dotsArr[j].x, ty = dotsArr[i].y - dotsArr[j].y, // 三角形斜邊長 s = Math.sqrt(Math.pow(tx, 2) + Math.pow(ty, 2)); if (s < dotsDistance) { ctx.beginPath(); ctx.moveTo(dotsArr[i].x, dotsArr[i].y); ctx.lineTo(dotsArr[j].x, dotsArr[j].y); ctx.strokeStyle = "rgba(0,0,0,"+(dotsDistance-s)/dotsDistance+")"; ctx.strokeWidth = 1; ctx.stroke(); ctx.closePath(); } } }
點與點之間連線
優化點:
限定點與點的連線距離(優化:根據點之間的距離添加連線顏色透明度)
Canvas 畫布的工作原理和顯示器工作原理一樣,都是通過不斷的刷新繪制。瀏覽器的刷新是實時的,而 Canvas 的刷新是手動觸發的,如果我們只想在 Canvas 上實現靜態的效果,就沒必不斷刷新。
requestAnimationFrame是瀏覽器用于定時循環操作的一個接口,類似于setTimeout,主要用途是按幀對網頁進行重繪。requestAnimationFrame不是自己指定回調函數運行的時間,而是跟著瀏覽器內建的刷新頻率來執行回調。
瀏覽器可以優化并行的動畫動作,更合理的重新排列動作序列,并把能夠合并的動作放在一個渲染周期內完成,從而呈現出更流暢的動畫效果,一旦頁面不處于瀏覽器的當前標簽,就會自動停止刷新。
持續調用 requestAnimFrame清除動畫調用 cancelAnimationFrame
var canvas = document.querySelector("canvas"); var context = canvas.getContext("2d"); // 畫布渲染 var render = function () { // 清除畫布 context.clearRect(0, 0, canvas.width, canvas.height); // 繪制(在canvas畫布上繪制圖形的代碼) draw(); // 繼續渲染 requestAnimationFrame(render); }; render();
上面的draw()就是在 canvas 畫布上繪制圖形的代碼,但是如果僅僅有上面代碼還不夠,如果是同一個位置不斷刷新,我們看到的還是靜止不動的效果,所以還需要一個運動變量。
var canvas = document.querySelector("canvas"); var context = canvas.getContext("2d"); // 坐標變量 var x = 0; // 繪制方法 var draw = function () { ball.x = x; }; // 畫布渲染 var render = function () { // 清除畫布 context.clearRect(0, 0, canvas.width, canvas.height); // 位置變化 x++; // 繪制 draw(); // 繼續渲染 requestAnimationFrame(render); }; render();6、動起來的多點多線
動的是點,畫的是線
let Dots = function () { // 畫布 this.canvas; this.ctx; // 畫點 this.x; this.y; this.r; // 移動 // 隨機確定點的移動速度與方向 速度值在 [-2, 2) 之間 提高數值可加快速度 //(Math.random() 隨機返回[0,1)的數) this.sx = Math.random() * 4 - 2; this.sy = Math.random() * 4 - 2; };
// 更新點位置 update: function () { this.x = this.x + this.sx; this.y = this.y + this.sy; // 點超出 canvas 范圍時重新初始化 if (this.x < 0 || this.x > this.canvas.width) { this.init(this.canvas); } if (this.y < 0 || this.y > this.canvas.height) { this.init(this.canvas); } this.ctx.beginPath(); this.ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI); this.ctx.fillStyle = "rgba(0,0,0,.6)"; this.ctx.fill(); this.ctx.closePath(); }
兼容 requestAnimationFrame
let requestAnimFrame = requestAnimationFrame || webkitRequestAnimationFrame || oRequestAnimationFrame || msRequestAnimationFrame; requestAnimFrame(animateUpdate); // 兼容不同瀏覽器的 requestAnimationFrame
或者使用 setTimeout 向下兼容:
// requestAnimationFrame的向下兼容處理 if (!window.requestAnimationFrame) { window.requestAnimationFrame = function(fn) { setTimeout(fn, 17); }; }
由于點的位置不斷變換,因此需要將畫線的操作放在動畫內執行,點的位置 update 一次就執行一次連線。
function animateUpdate() { ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空canvas中原有的內容 for (let i = 0; i < dotsNum; i ++) { dotsArr[i].update(); } // 繪制連線 for (let i = 0; i < dotsNum; i ++) { for (let j = i + 1; j < dotsNum; j ++) { let tx = dotsArr[i].x - dotsArr[j].x, ty = dotsArr[i].y - dotsArr[j].y, // 三角形斜邊長 s = Math.sqrt(Math.pow(tx, 2) + Math.pow(ty, 2)); if (s < dotsDistance) { ctx.beginPath(); ctx.moveTo(dotsArr[i].x, dotsArr[i].y); ctx.lineTo(dotsArr[j].x, dotsArr[j].y); ctx.strokeStyle = "rgba(0,0,0,"+(dotsDistance-s)/dotsDistance+")"; ctx.strokeWidth = 1; ctx.stroke(); ctx.closePath(); } } } // 繼續渲染 requestAnimFrame(animateUpdate); }類似的例子
星空效果、下雨效果等
你可能不知道的點不要在style里指定 Canvas 的寬度,Canvas 畫布的尺寸的大小和顯示的大小是有很大的區別的,在 canvas 里面設置的是才是 Canvas 本身的大小。
如果不給設置 width、height 屬性時,則默認 width 為 300、height 為 150, 單位都是 px。也可以使用 css 屬性來設置寬高,但是如寬高屬性和初始比例不一致,他會出現扭曲。所以,建議永遠不要使用css屬性來設置的寬高。
畫新元素前記得要 beginPath()
不管用 moveTo 把畫筆移動到哪里,只要不調用beginPath(),一直都是在畫一條路徑
fillRect 與 strokeRect 這種直接畫出獨立區域的函數,也不會打斷當前的path
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/117514.html
摘要:在數學上,遞推關系,也就是差分方程,是一種遞推地定義一個序列的方程式序列的每一項目是定義為前一項的函數。 《每周一點canvas動畫》——差分函數的妙用 每周一點canvas動畫代碼文件 好像上次更新還是十一前,這唰唰唰的就過去大半個月了,現在才更新實在不好意思。這次我們不涉及canvas 3D的內容,主要分享一個比較炫的動畫效果,可以算是上一篇文章《每周一點canvas動畫》——3D...
摘要:在數學上,遞推關系,也就是差分方程,是一種遞推地定義一個序列的方程式序列的每一項目是定義為前一項的函數。某些簡單定義的遞推關系式可能會表現出非常復雜的混沌的性質,他們屬于數學中的非線性分析領域。 每周一點canvas動畫代碼文件 好像上次更新還是十一前,這唰唰唰的就過去大半個月了,現在更新我也沒什么不好意思的。這次我們不涉及canvas 3D的內容,主要分享一個比較炫的動畫效果,可以算...
摘要:模擬飛機航班線路動畫一款基于的飛機航班線路模擬動畫,它模擬了許多航班在不同目的地的起飛降落數量。跳動加載動畫可調節參數這是一款基于的跳動加載動畫,它的另一個特點是可以動態調節動畫參數。 showImg(https://segmentfault.com/img/bVblze6?w=900&h=383); HTML5 動畫在Canvas 上得到了充分的發揮,我們 VIP 視頻也分享過很多相...
閱讀 2545·2023-04-26 01:44
閱讀 2557·2021-09-10 10:50
閱讀 1411·2019-08-30 15:56
閱讀 2250·2019-08-30 15:44
閱讀 512·2019-08-29 11:14
閱讀 3416·2019-08-26 11:56
閱讀 3018·2019-08-26 11:52
閱讀 908·2019-08-26 10:27