摘要:我們需要使用到的方法有第一步繪制一個小球畫布的寬畫布的高定義圓心坐標定義圓心坐標定義半徑清除畫布開始繪制畫圓圓的填充顏色閉合路徑填充在線預覽第二步讓小球動起來讓小球動起來的原理就是,不斷地改變小球的坐標位置并進行重繪。
我們需要使用到Canvas的方法有:
context.arc(x, y, r, sAngle, eAngle, counterclockwise);第一步:繪制一個小球
var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), w = canvas.width, //canvas畫布的寬 h = canvas.height,// canvas畫布的高 posX = 20,//定義圓心X坐標 posY = 20,//定義圓心Y坐標 radius = 20;//定義半徑 ctx.clearRect(0, 0, w, h);//清除畫布 ctx.beginPath();//開始繪制 ctx.arc(posX,posY,radius,0,2*Math.PI);//畫圓 ctx.fillStyle = "red";//圓的填充顏色 ctx.closePath();//閉合路徑 ctx.fill();//填充
在線預覽:https://codepen.io/jianxiujiu...
第二步:讓小球動起來讓小球動起來的原理就是,不斷地改變小球的坐標位置并進行重繪。
重繪可以用setInterval、setTimeout或requestanimationframe。關于它們的區別此處不做詳解,具體可以參考我好基友的一篇文章:setTimeout 和 requestAnimationFrame
window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), w = canvas.width, h = canvas.height, posX = 20, //小球出現的X軸位置 posY = 20, //小球出現的Y軸位置 speedX = 3,//小球X軸速度 speedY = 3,//小球Y軸速度 radius = 20;//小球半徑 function ani(){ ctx.clearRect(0, 0, canvas.width, canvas.height); posX += speedX; posY += speedY; ctx.beginPath(); ctx.arc(posX,posY,radius,0,2*Math.PI); ctx.fillStyle = "red"; ctx.closePath(); ctx.fill(); if(posY < h - radius){ requestAnimFrame(ani) //如果Y軸位置不超過容器高度則一直移動 } } ani();
在線預覽:https://codepen.io/jianxiujiu...
第三步:一個小球的碰撞動畫接下來我們讓小球動起來,并在畫布四周進行碰撞運動。
window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), w = canvas.width, h = canvas.height, posX = 20, posY = 20, speedX = 2,//小球X軸速度 speedY = 2,//小球Y軸速度 startSpeedX = 2,//小球X軸初始速度 startSpeedY = 2,//小球Y軸初始速度 radius = 20;//小球半徑 function ani(){ ctx.clearRect(0, 0, canvas.width, canvas.height); posX += speedX; posY += speedY; //小球碰壁反彈 if(posY > h - radius){ speedY*=-1; } if(posX > w - radius){ speedX*=-1; } if(posY < radius){ speedY = startSpeedY; posY = radius; } if(posX < radius){ speedX = startSpeedX; posX = radius; } ctx.beginPath(); ctx.arc(posX,posY,radius,0,2*Math.PI); ctx.fillStyle = "red"; ctx.closePath(); ctx.fill(); requestAnimFrame(ani); } ani();
在線預覽:https://codepen.io/jianxiujiu...
第四步:多個小球的碰撞動畫window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), w = canvas.width, h = canvas.height, posX, posY, speedX, speedY, radius; function randomNum(m,n) { //隨機函數 return Math.floor(Math.random() * (n - m + 1) + m); } var balls = [] //建立小球數組 function getBall(){ for( n = 0; n < 20;n++){ //小球的數量 radius = randomNum (10,20), //半徑隨機10-20px posX = randomNum(radius,w-radius), //X軸位置隨機 posY = randomNum(radius,h-radius), //Y軸位置隨機 speedX = randomNum(3,6), //X軸速度隨機 speedY = randomNum(1,2), //Y軸速度隨機 startSpeedX = startSpeedX,//記錄X軸起始速度 startSpeedY = startSpeedY;//記錄X軸起始速度 fillColor = "rgb(" + randomNum(0,255) + "," + randomNum(0,255) + "," + randomNum(0,255) + ")";//小球顏色隨機 var ball = { radius : radius, posX : posX, posY : posY, speedX : speedX, speedY : speedY, startSpeedX : startSpeedX, startSpeedY : startSpeedX, fillColor : fillColor } balls.push(ball) //將生成的小球存到數組里 } } getBall(); function draw(){ ctx.clearRect(0, 0, canvas.width, canvas.height); var l = balls.length; for(var i = 0;ih - ballCur.radius){ ballCur.speedY*=-1; } if(ballCur.posX > w - ballCur.radius){ ballCur.speedX*=-1; } if(ballCur.posY < ballCur.radius){ ballCur.speedY = startSpeedY; ballCur.posY = ballCur.radius; } if(ballCur.posX < ballCur.radius){ ballCur.speedX = startSpeedX; ballCur.posX = ballCur.radius; } ctx.arc(ballCur.posX,ballCur.posY,ballCur.radius,0,2*Math.PI); ctx.fillStyle = ballCur.fillColor; ctx.closePath(); ctx.fill(); } requestAnimFrame(draw); } draw();
在線預覽:https://codepen.io/jianxiujiu...
第五步:小球為自定義圖片的動畫小球動起來之后,如果希望小球為圖片,則需要用到Canvas另外一個方法:
context.drawImage(image, x, y); //在畫布上定位圖像: context.drawImage(image, x, y, width, height);//在畫布上定位圖像,并規定圖像的寬度和高度 context.drawImage(image, sourceX, sourceY, sourceWidth, sourceHeight,destX, destY, destWidth, destHeight);//剪切圖像,并在畫布上定位被剪切的部分
和繪制普通小球不一樣,繪制圖片球的時候,我們需要把之前動畫的代碼在加載完圖片之后再執行。并且碰撞的位置也需要進行調整。
window.requestAnimFrame = (function(){ return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback){ window.setTimeout(callback, 1000 / 60); }; })(); var canvas = document.getElementById("canvas"), ctx = canvas.getContext("2d"), w = canvas.width, h = canvas.height, ballWidth = 60, //圖片球寬度 posX, posY, speedX, speedY; var img = new Image(); img.src = "img/ball.png"; img.onload = function(){ getBall(); draw(); } function randomNum(m,n) { return Math.floor(Math.random() * (n - m + 1) + m); } var balls = [] function getBall(){ for( n = 0; n < 20;n++){ posX = randomNum(ballWidth,w - ballWidth), posY = randomNum(ballWidth,h - ballWidth), speedX = randomNum(3,7), speedY = randomNum(4,8), startSpeedX = speedX, startSpeedY = speedY; ballPicPos = randomNum(0,4)*60; //小球圖片位置隨機 var ball = { posX : posX, posY : posY, speedX : speedX, speedY : speedY, startSpeedX : startSpeedX, startSpeedY : startSpeedX, ballPicPos : ballPicPos } balls.push(ball); } } function draw(){ ctx.clearRect(0, 0, canvas.width, canvas.height); var l = balls.length; for(var i = 0;ih - ballWidth){ ballCur.speedY*=-1; } if(ballCur.posX > w - ballWidth){ ballCur.speedX*=-1; } if(ballCur.posY < 0){ ballCur.speedY = startSpeedY; ballCur.posY = 0; } if(ballCur.posX < 0){ ballCur.speedX = startSpeedX; ballCur.posX = 0; } ctx.beginPath(); ctx.fillStyle = ctx.drawImage(img,0,ballCur.ballPicPos,ballWidth,ballWidth,ballCur.posX,ballCur.posY,ballWidth,ballWidth); ctx.fill(); ctx.closePath(); ctx.restore(); } requestAnimFrame(draw); }
線上預覽:https://codepen.io/jianxiujiu...
PS:小球的圖片位置如果取值大于圖片本身的位置,則IE11下顯示圖片會有BUG。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/87324.html
摘要:嘗試實現畫出一個彈射的小球很簡單,那怎么用多個小球實現這樣的效果呢。 本文首發于我的博客,這是我的github,歡迎star。 ??這篇博客是模仿nest.js實現一個demo,由簡單到復雜,來一步步的實現它。這里是效果預覽。我的github里邊還有很多別的前端的demo,喜歡的話可以點個star,你的支持就是我的動力。 從一道面試題開始 實現一個半徑10px的小球在500px*5...
摘要:每周一點動畫代碼文件在上一節我們介紹了高級的坐標旋轉方法,我們只需要知道物體的位置,通過設定每一幀需要旋轉的角速度通過公式就可以計算出做圓周運動時物體的下一個坐標位置。思路有了,我們需要把它轉化成平面來做角度反彈。 每周一點canvas動畫代碼文件 在上一節我們介紹了高級的坐標旋轉方法,我們只需要知道物體的位置,通過設定每一幀需要旋轉的角速度,通過公式 newX = x*cos - y...
閱讀 876·2021-11-22 09:34
閱讀 1011·2021-10-08 10:16
閱讀 1822·2021-07-25 21:42
閱讀 1794·2019-08-30 15:53
閱讀 3526·2019-08-30 13:08
閱讀 2185·2019-08-29 17:30
閱讀 3348·2019-08-29 17:22
閱讀 2180·2019-08-29 15:35