本文主要是介绍canvas 仿迷盘旋转对称,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
canvas 仿迷盘旋转对称
不知道大家玩没玩过迷盘这类的画图娱乐软件,前几天陪我家小孩子玩的时候,感觉挺有趣的,然后萌发了自己写一个类似的程序玩玩,然后就有了以下的这个程序。
话不多说,先奉上效果图看下:
demo地址:https://liuxiaochaogit.github.io/demo/fandisk/index.html
起初开始是想用多张canvas来实现这个功能,后来看别人的帖子,发现早就类似的程序了,然后还发现别人的思路更清晰,再然后就无耻的借用了别人的思路(请原谅我)。
主要使用了canvas的translate和rotate方法,如有对canvas不了解的小伙伴请自行百度。
过程:
-
首先需要准备两张画布,一张用来显示分割的扇形区域,另一张绘制
// 绘制主体<canvas id="cvs" width="600" height="600">您的浏览器太low了,建议升级或者更换浏览器</canvas>// 用来分割扇形区域<canvas id="lineCvs" width="600" height="600">您的浏览器太low了,建议升级或者更换浏览器</canvas>// scriptlet canvas = document.getElementById('cvs'),lineCanvas = document.getElementById('lineCvs'),partition = document.getElementById('partition'),color = document.getElementById('color'),extent = document.getElementById('extent'),cvs = canvas.getContext('2d'),lineCvs = lineCanvas.getContext('2d'),radius = canvas.width,ob = {};
-
分割扇形区域很简单,其实就是根据数量计算角度,然后旋转到指定角度,画一半径,直至一圈画完
// 绘制扇形分区 numdrawLine(num) {let _ob = {},centerX = _ob.startX = radius / 2,centerY = _ob.startY = radius / 2,moveX = _ob.moveX = radius / 2,moveY = _ob.moveY = 0,_this = this;// 角度let deg = 360 / num;for (var i = 0; i < num; i++) {// 弧度 deg * Math.PI / 180lineCvs.rotate(deg * Math.PI / 180);_this.draw(lineCvs, _ob);lineCvs.save();}}// 绘制draw(cvs, ob) {let _cvs = cvs,_ob = ob;_cvs.beginPath();// 坐标_cvs.moveTo(_ob.startX, _ob.startY);_cvs.lineTo(_ob.moveX, _ob.moveY);_cvs.stroke();}
-
这样的话你会发现是旋转了,但是他是围绕着(0,0)坐标旋转的,我们想要的是围绕中心旋转,这就用到了translate方法
// 将中心点移动到画布的中心lineCvs.translate(lineCvs.canvas.width / 2, lineCvs.canvas.height / 2);// 绘制坐标也需要减去位移的距离draw(cvs, ob) {let _cvs = cvs,_ob = ob;_cvs.beginPath();// 坐标减去位移的长度_cvs.moveTo(_ob.startX - radius / 2, _ob.startY - radius / 2);_cvs.lineTo(_ob.moveX - radius / 2, _ob.moveY - radius / 2);_cvs.stroke();}
-
接下来就是主体了,首先我们需要监听鼠标事件,得到鼠标运动路径,并在画布上将轨迹画出来
// 监听事件 画图canvas.addEventListener('mousedown', (e) => {let ob = {};let startX = ob.startX = ob.moveX = e.clientX - canvas.parentElement.offsetLeft + window.scrollX,startY = ob.startY = ob.moveY = e.clientY - canvas.parentElement.offsetTop + window.scrollY;document.addEventListener('mousemove', moveE = (e) => {ob.startX = ob.moveX;ob.startY = ob.moveY;let moveX = ob.moveX = e.clientX - canvas.parentElement.offsetLeft + window.scrollX,moveY = ob.moveY = e.clientY - canvas.parentElement.offsetTop + window.scrollY;draw(cvs, ob);});document.addEventListener('mouseup', (e) => {document.removeEventListener('mousemove', moveE);});});
-
是可以随意涂鸦了,但是怎么才能做到对称呢,这还得依靠rotate()这个牛叉的方法,我的思路是这样的,比如说被分成了6个扇形区域,那么这六个扇形区域内部的所有都必须是对称的,
我们可以将一个区域复制六份,每个区域一份不就完了(为自己的机智点赞),其实就是旋转六次,每次都保存住画布状态,下次画的时候再取出状态,然后不就行了// 旋转rotateDraw(num, ob) {let deg = 360 / num,_this = this;// 位移 坐标定于圆心 让旋转围绕圆心旋转cvs.translate(radius / 2, radius / 2);for (var i = 0; i < 360; i++) {// 取出之前保存的状态cvs.restore();cvs.rotate(deg * Math.PI / 180);this.draw(cvs, ob);// 绘制完保存状态cvs.save();}}
-
现在一个可以对称涂鸦的画板就成功了,有点注释,虽然不是很完美,有点注释,虽然不是很完美,但是相信差不多都能看懂,完整demo代码在这里 https://github.com/liuxiaochaoGit/demo/tree/master/fandisk
本文纯手打,有不当之处请留言!如果对小伙伴们有帮助的话,点赞啊,谢谢!
这篇关于canvas 仿迷盘旋转对称的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!