canvas教程

JavaScript 雷达

字号+ 作者:H5之家 来源:H5之家 2017-02-04 17:00 我要评论( )

!DOCTYPEhtmlhtmlheadmetacharset=

<!DOCTYPE html> <html> <head> <meta charset="utf8"> <meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1"> <meta content="width=device-width, initial-scale=1.0"> <meta content="Orb trails"> <meta content="Orb trails"> <title>Orb trails</title> <style> body { background: black; color: #aaa; font: 12px/20px helvetica, arial, sans-serif; overflow: hidden; } #control-panel { position: absolute; padding: 10px; border: 1px dotted Cornsilk; border-radius: 10px; background-color: rgba(0,0,0,.5); } #control-panel button { margin: 5px 10px 5px 0; width: 60px; } #control-panel input { /* 添加这句后按钮和文字才会对齐 */ vertical-align:middle; } </style> </head> <body> <div> Click and drag to make more! <br/> <label>Direction: </label> <input type="radio" value="clockwise" checked/>Clockwise <input type="radio" value="counterclockwise">Counterclockwise <br/> <label>Angular Speed: </label> <input type="radio" value="same" checked />Same <input type="radio" value="random"/>Random <br/> <label>Trails: </label> <input type="checkbox" checked/> <br/> <button>Init</button> <button>Clear</button> <button>Pause</button> <br/> 我在残酷的现实中反复挣扎,<br/> 残酷的现实却让我无法自拔。 </div> <canvas>Your browser can not support canvas</canvas> <script> var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var halfPI = Math.PI / 2; var doublePI = Math.PI * 2; //天体线条笔帽 var lineCap = "round"; //用来制作天体尾巴的蒙版透明度(透明度越低,尾巴越长) var maskAlpha = 0.1; //初始化的天体个数 var initCount = 30; //每帧一次性更新和渲染的次数 var onceUpdateAndRenderTimes = 4; //为了防止粒子被添加的太多,这里设置只有x或y的差值大于该阀值才能被添加 var offsetThreshold = 5; //画布中心点坐标 var cx; var cy; //旋转方向[clockwise(顺时针), counterClockwise(逆时针)] var direction = "clockwise"; //角速度步长[same(相同角速度), random(随机角速度)] var stepType = "same"; //是否显示天体的尾巴 var isTrails = true; //是否暂停 var isPause = false; //天体粒子数组 var orbs = []; //在[min,max]中随机选取一个数 function randomAtRange(obj) { return Math.random() * (obj.max - obj.min) + obj.min; } //画线条 function strokeLine(x1, y1, x2, y2) { ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke(); } //天体粒子 var Orb = function(x, y) { //宽度范围 var widthRange = {min: 1, max: 3}; //等角速度的时候的步长 var sameRadianStep = 0.01; //随机角速度时候的步长 var randomRadianRange = {min: 0.005, max: 2 * sameRadianStep}; //上一次的位置 var lastX = x; var lastY = y; //与中心的距离(右下为正) var dx = x - cx; var dy = y - cy; //距画布中心的半径 var radius = Math.sqrt(dx * dx + dy * dy); //宽度 var width = randomAtRange(widthRange); //每帧步长 var step = 0; //Math.atan2(y,x)返回(-Math.PI,Math.PI], 返回(x,y)与0点钟方向的夹角, 顺时针方向为正。但由于画布是右下方为正,等价于做垂直镜像 var radian = Math.atan2(dx, dy); //色相 var hue; //绕中心旋转速度类型[same(等角速度)、random(随机)] this.resetStepType = function() { if(stepType === "same") { step = sameRadianStep; } else { step = randomAtRange(randomRadianRange); } } //判断当前点是否与给定点离的很近 this.isNear = function(pointX, pointY) { if(Math.abs(pointX - x) < offsetThreshold && Math.abs(pointY - y) < offsetThreshold) { return true; } return false; } //当画布大小被改变的时候 this.resetPos = function() { x = lastX = cx + radius * Math.sin(radian); y = lastY = cy + radius * Math.cos(radian); } this.update = function() { lastX = x; lastY = y; x = cx + radius * Math.sin(radian); y = cy + radius * Math.cos(radian); hue = 360 * radian / doublePI; if(direction === "clockwise") { radian = (radian - step) % doublePI; } else { radian = (radian + step) % doublePI; } } this.render = function() { ctx.strokeStyle = "hsla(" + hue + ",100%,50%,1)"; ctx.lineWidth = width; strokeLine(lastX, lastY, x, y); } this.resetStepType(); this.resetPos(); } //初始化所有天体 function initOrbs() { var len = Math.min(cx, cy); var step = len / (initCount+1); orbs = []; for(var i=0, offsetY = cy - step; i<initCount; i++, offsetY -= step) { orbs.push(new Orb(cx, offsetY)); } } function init() { onResize(); var directionRadios = document.getElementsByName("direction"); var stepTypeRadios = document.getElementsByName("stepType"); var trailCb = document.getElementById("trail"); var initBtn = document.getElementById("init"); var clearBtn = document.getElementById("clear"); var switchStateBtn = document.getElementById("switchState"); window.addEventListener("resize", onResize); //指定事件是否在捕获(true)或冒泡(false)阶段执行。true的触发顺序总是在false之前 canvas.addEventListener("mousedown", onMouseDown, false); canvas.addEventListener("mouseup", onMouseUp, false); canvas.addEventListener("mouseout", onMouseOut, false); //旋转方向 for(var i=0; i<directionRadios.length; i++) { //这里用change或者click事件均可以 directionRadios[i].addEventListener("change", function(){ direction = event.target.value; }); } //角速度类型 for(var i=0; i<stepTypeRadios.length; i++) { //这里用change或者click事件均可以 stepTypeRadios[i].addEventListener("change", function(){ stepType = event.target.value; for(var i=0; i<orbs.length; i++) { orbs[i].resetStepType(); } }); } //是否显示轨迹 trailCb.addEventListener("change", function() { isTrails = event.target.checked; }); //清除所有天体 clearBtn.addEventListener("click", function() { orbs = []; //这里还要清除一下画布,否则上面还有颜色残留,只是用某个透明度的黑覆盖而已 ctx.clearRect(0, 0, canvas.width, canvas.height); }); //初始化一部分的天体 initBtn.addEventListener("click", initOrbs); //切换天体的运行和停止状态 switchStateBtn.addEventListener("click", function() { isPause = !isPause; console.log(isPause); switchStateBtn.innerHTML = isPause ? "Pause" : "Start"; }); ctx.lineCap = lineCap; initOrbs(); loop(); } function loop() { if(!isPause) { if(isTrails) { //使用带透明度的颜色来填充就相当于色彩叠加了 ctx.fillStyle = "rgba(0,0,0," + maskAlpha + ")"; ctx.fillRect(0, 0, canvas.width, canvas.height); } else { ctx.clearRect(0, 0, canvas.width, canvas.height); } for(var i=0; i<orbs.length; i++) { for(var j=0; j<onceUpdateAndRenderTimes; j++) { orbs[i].update(); orbs[i].render(); } } } requestAnimationFrame(loop); } //有一个瑕疵是暂停的话,然后resize,所有的点都会消失 function onResize() { canvas.width = window.innerWidth; canvas.height = window.innerHeight; cx = canvas.width / 2; cy = canvas.height / 2; for(var i=0; i<orbs.length; i++) { orbs[i].resetPos(); } } function onMouseDown() { canvas.addEventListener("mousemove", onMouseMove); onMouseMove(); } function onMouseMove() { //event.offsetX 等价于 event.pageX - canvas.offsetLeft var x = event.offsetX; var y = event.offsetY; for(var i=0; i<orbs.length; i++) { if(orbs[i].isNear(x, y)) { return; } } orbs.push(new Orb(x, y)); } function onMouseUp() { canvas.removeEventListener("mousemove", onMouseMove); } function onMouseOut() { canvas.removeEventListener("mousemove", onMouseMove); } init(); </script> </body> </html>

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • Canvas Clock

    Canvas Clock

    2017-01-24 16:00

  • HTML canvas to blob to downloadable file in IE9, 10

    HTML canvas to blob to downloadable file in IE9, 10

    2017-01-20 10:00

  • [Canvas学习]绘制图形

    [Canvas学习]绘制图形

    2017-01-19 09:02

  • 高性能动画!HTML5 Canvas JavaScript框架KineticJS

    高性能动画!HTML5 Canvas JavaScript框架KineticJS

    2017-01-17 10:00

网友点评