canvas动画3:交互
canvas動畫3
時隔很久,本人終于又寫博客了(重度拖延癥),把之前留下的canvas交互動畫講一講。
電腦上的交互,指的是鼠標(biāo)和鍵盤,我們今天主要用的是鼠標(biāo)。
既然是鼠標(biāo)的話,就要獲取鼠標(biāo)的各種事件,這次以mousemove做示例。
我們先定義一個鼠標(biāo)對象,然后添加mousemove事件:
var mouse = {x: undefined,y: undefined } //這樣的話控制臺就會跟隨我們的鼠標(biāo)移動輸出相應(yīng)的坐標(biāo) window.addEventListener("mousemove",function (event) {mouse.x = event.x;mouse.y = event.y;console.log(mouse); });我們聲明一個初始化函數(shù)init(),用于把制造圓的過程封裝:
function init() {circleArray = []for (var i = 0; i < 800; i++) {var x = Math.random()*window.innerWidth;var y = Math.random()*window.innerHeight;var dx = (Math.random()-0.5)*2;var dy = (Math.random()-0.5)*2;var radius = Math.random()*3 +1;circleArray.push(new Circle(x, y, dx, dy, radius));} } init();這樣的話,按照上一篇文章的做法,我們的canvas會出現(xiàn)一些問題。所以,需要給Circle對象update()里的屬性都加上this:
function Circle(x, y, dx, dy, radius) {this.x = x;this.y = y;this.dx = dx;this.dy = dy;this.radius = radius;this.draw = function() {ctx.beginPath();ctx.strokeStyle = "#000";ctx.arc(this.x,this.y,this.radius,Math.PI/180*0,Math.PI/180*360,false);ctx.stroke();ctx.fill();}this.update = function() {//圓觸碰邊界時反彈,偏移值為負(fù)if (this.x + this.radius > innerWidth || this.x - this.radius < 0 ) {this.dx = -this.dx;}if (this.y + this.radius > innerHeight || this.y - this.radius < 0 ) {this.dy = -this.dy;}//刷新繪制時圓的偏移運動this.x += this.dx;this.y += this.dy;//根據(jù)更新的值進行繪制this.draw();} }接下來我們就要用mousemove于動畫進行交互了,我們假定圓心在鼠標(biāo)坐標(biāo)周圍50px以內(nèi)的時候圓會增大,這段代碼應(yīng)該寫在update()里:
if (mouse.x - this.x < 50 && mouse.x - this.x >-50 && mouse.y - this.y < 50 && mouse.y - this.y >-50) {// if (this.radius < maxRadius) {this.radius += 1;// } }我們設(shè)置了10個圓,把鼠標(biāo)移上去的時候會看到在控制范圍內(nèi)的圓會不斷變大,不會停下來,所以我在前面就設(shè)置了一個圓半徑的最大值,以免它一直增大,然后把注釋的內(nèi)容去掉,圓就不會無限增大了:
但是有一個問題,圓放大了以后不會縮小,那么我們就讓它在離開圓50px半徑范圍后縮小:
if (mouse.x - this.x < 50 && mouse.x - this.x >-50 && mouse.y - this.y < 50 && mouse.y - this.y >-50) {if (this.radius < maxRadius) {this.radius += 1;} //其他的所有圓半徑不斷減小 }else{this.radius -= 1; }這時候又有新問題產(chǎn)生了,畫面一片空白,因為圓心不在鼠標(biāo)固定范圍內(nèi)的圓全都變小了,甚至半徑為負(fù)!顯然簡單的else是不成立的,還是得加個條件:
if (mouse.x - this.x < 50 && mouse.x - this.x >-50 && mouse.y - this.y < 50 && mouse.y - this.y >-50) {if (this.radius < maxRadius) {this.radius += 1;} //其他的所有圓半徑減小到最小值 }else if (this.radius > this.minRadius) {this.radius -= 1; }這里出現(xiàn)了一個新值:minRadius,我加在了Circle對象里this.minRadius = radius;,以原本的初始值作為它的最小值。好了,現(xiàn)在基本效果已經(jīng)成型了:
接下來就是顏色的問題了,只要懂得canvas的基本api,修改顏色完全就是小兒科。我們設(shè)置一個數(shù)組,用于存放顏色值。
var colorArray = ['#58D68D','#E67F22','#3598DB','#E84C3D','#9A59B5','#27AE61','#D25400','#BEC3C7','#297FB8' ]然后在Circle對象里加上一個bg屬性:this.bg = colorArray[Math.floor(Math.random()*colorArray.length)];,再往Circle的繪制函數(shù)添上一句ctx.fillStyle = this.bg;,然后ctx.fill();,多彩運動的圓圈canvas就做完了。
這是一個運用mousemove事件做的canvas交互動畫,有興趣的可以嘗試其他事件(制作游戲用的鍵盤事件以及其他鼠標(biāo)事件),或者思考如何給球加重力,如何檢測碰撞事件,canvas的世界并不只有這么一點,相關(guān)資料的話,給大家推薦本書《canvas開發(fā)詳解》。
本文的最終js代碼如下:
/*** * @authors dkplus (dkplus@qq.com)* @date 2017-10-01 20:37:26* @version $1.0$*/ /*** 獲取canvas對象,設(shè)置寬度高度自適應(yīng)* @type {[type]}*/ var canvas = document.querySelector("#canvas"); canvas.width = window.innerWidth; canvas.height = window.innerHeight;var ctx = canvas.getContext("2d"); /*** 屏幕鼠標(biāo)坐標(biāo)* @type {Object}*/ var mouse = {x: undefined,y: undefined } /*** @param {鼠標(biāo)移動事件,回調(diào)函數(shù),賦值給鼠標(biāo)坐標(biāo)}* @return {[type]}*/ window.addEventListener("mousemove",function (event) {mouse.x = event.x;mouse.y = event.y;// console.log(mouse); }); /*** @param {重新設(shè)置窗口大小,使canvas寬高自適應(yīng)屏幕}* @return {[type]}*/ window.addEventListener("resize",function () {canvas.width = window.innerWidth;canvas.height = window.innerHeight;//初始化canvasinit(); }) //繪制圓的最大半徑 var maxRadius = 40; // var minRadius = 2;//圓的顏色數(shù)組 var colorArray = ['#58D68D','#E67F22','#3598DB','#E84C3D','#9A59B5','#27AE61','#D25400','#BEC3C7','#297FB8' ] /*** @param {x圓中心的x坐標(biāo)}* @param {y圓中心的y坐標(biāo)}* @param {dx圓運動的x偏移量}* @param {dy圓運動的y偏移量}* @param {radius圓的半徑}* minRadius圓的最小半徑* bg圓的背景顏色* draw繪制函數(shù)* update圓運動偏移*/ function Circle(x, y, dx, dy, radius) {this.x = x;this.y = y;this.dx = dx;this.dy = dy;this.radius = radius;this.minRadius = radius;this.bg = colorArray[Math.floor(Math.random()*colorArray.length)];this.draw = function() {ctx.beginPath();ctx.strokeStyle = "#777";ctx.fillStyle = this.bg;ctx.arc(this.x,this.y,this.radius,Math.PI/180*0,Math.PI/180*360,false);// ctx.stroke();ctx.fill();}this.update = function() {//圓觸碰邊界時反彈,偏移值為負(fù)if (this.x + this.radius > innerWidth || this.x - this.radius < 0 ) {this.dx = -this.dx;}if (this.y + this.radius > innerHeight || this.y - this.radius < 0 ) {this.dy = -this.dy;}//刷新繪制時圓的偏移運動this.x += this.dx;this.y += this.dy;//鼠標(biāo)半徑50像素范圍內(nèi)的圓,它們的半徑逐步增加到最大值if (mouse.x - this.x < 50 && mouse.x - this.x >-50 && mouse.y - this.y < 50 && mouse.y - this.y >-50) {if (this.radius < maxRadius) {this.radius += 1;}//其他的所有圓半徑減小到最小值}else if (this.radius > this.minRadius) {this.radius -= 1;}//根據(jù)更新的值進行繪制this.draw();} } //圓的對象數(shù)組 var circleArray = []; /*** 初始化函數(shù),制造800個隨機坐標(biāo)、偏移速度和半徑的圓,加入到對象數(shù)組* @return {[type]}*/ function init() {circleArray = []for (var i = 0; i < 800; i++) {var x = Math.random()*window.innerWidth;var y = Math.random()*window.innerHeight;var dx = (Math.random()-0.5)*2;var dy = (Math.random()-0.5)*2;var radius = Math.random()*3 +1;circleArray.push(new Circle(x, y, dx, dy, radius));} } init(); /*** 動畫函數(shù)* @return {[type]}*/ function animate() {//更新前清楚畫布ctx.clearRect(0,0,window.innerWidth,window.innerHeight);requestAnimationFrame(animate);//每個圓都調(diào)用update()方法for (var i = 0; i < circleArray.length; i++) {circleArray[i].update();}} animate();轉(zhuǎn)載于:https://www.cnblogs.com/dkplus/p/7887482.html
總結(jié)
以上是生活随笔為你收集整理的canvas动画3:交互的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 地方养老账户本金是什么意思
- 下一篇: js-ajax-04