美文网首页自定义控件
canvas实现简单的Amaziograph效果画对称图

canvas实现简单的Amaziograph效果画对称图

作者: kingZXY2009 | 来源:发表于2017-04-10 19:07 被阅读278次

    标题很难引人入胜,先放个效果图好了

    如果图片吸引不了你,那我觉得也就没啥看的了。

    demo链接:https://win7killer.github.io/can_demo/demo/draw_roll_2.html

    *************************************************

    上次“雷达图效果”文章很荣幸,被“某天头条”抓数据抓去了,不开心的是demo链接等所有链接都干掉了~~~  blabla,连个名字都木有。

    想看的再看下:http://www.cnblogs.com/ufex/p/6655336.html

    *************************************************

    创意来源

    之前看到的gif效果,为了这个文章又去找了一下。貌似是ipad的app “Amaziograph”。看起来真的很爽,很美

    配上我自己画的图先:

    手残不会画画,各位见笑。(手机上浏览器画的哦)

    DEMO讲解

    1.效果分析

    a.参考线坐标轴 -- 为了简单控制参考线显示隐藏,单独一个canvas来搞,也不用每次重绘

    b.绘画主体 -- 绘画效果(canvas画线);对称效果(canvas旋转)

    c.配置区 -- 简单dom

    简单来看,很容易实现嘛

    2.开搞

    1> 坐标系统

    其实就是画几条线,但是要均分角度。一种方法是,计算出各个点,然后从中心点发散去画线;另一种是,一边旋转canvas,一边画圆心到统一坐标的线。由于绘画是需用到canvas旋转,所以这里统一使用旋转来处理。

    那么,就需要先来处理canvas旋转

    1functiondrawRotate(deg, fn, _ctx) {2_ctx = _ctx ||ctx3_ctx.save();4_ctx.translate(_ctx.canvas.width / 2, _ctx.canvas.height / 2);5_ctx.rotate(deg);6fn &&fn(_ctx);7_ctx.restore();8}

    当然,这个是我尝试多次之后写好的方法。

    1、存储ctx状态到栈,

    2、移动旋转点(canvas坐标原点)到canvas中心,

    3、旋转指定角度,

    4、执行绘制函数fn,

    5、从栈里边取回ctx的状态(包含但不仅包含 fillStyle、strokenStyle、translate等等),这里主要处理的是translate,因为我们下次用到坐标会受影响,所以要让canva坐标原点回到原来的位置。

    其实这里translate还是比较抽象比较绕的。。。可能我比较迟缓

    然后,是绘制参考线坐标

    1functionbaseLine() {2ctx_role.clearRect(0, 0, ctx_role.canvas.width, ctx_role.canvas.height);3vardeg = 360 /pieace;4console.log(deg);5ctx_role.lineWidth = 1;6ctx_role.strokeStyle = 'rgba(0,0,0,.5)';7for(vari = 0, l = pieace; i < l; i++) {8drawRotate(i * deg / 180 * Math.PI,function(ctx_role) {9draw({10bx: can_role.width / 2,11by: can_role.width / 2,12ex: can_role.width / 2 +can_role.width,13ey: can_role.width / 214}, ctx_role);15}, ctx_role);16}17}

    1functiondraw(option, _ctx) {2_ctx = _ctx ||ctx;3_ctx.beginPath();4_ctx.moveTo(option.bx - _ctx.canvas.width / 2, option.by - _ctx.canvas.height / 2);5_ctx.lineTo(option.ex - _ctx.canvas.width / 2, option.ey - _ctx.canvas.height / 2);6_ctx.stroke();7}

    这样,就绘制完成参考线。

    2>绘画主体

    首先处理一般的画线。跟拖拽效果类似,在move过冲中一直画线链接两个点。对拖拽不了解的可以去了解下,直接上代码

    1functionbindPc() {2can.onmousedown =function(e) {3if(e.button != 0) {4returnfalse;5}67varop ={};8op.ex = op.bx = e.clientX - can.parentElement.offsetLeft +window.scrollX;9op.ey = op.by = e.clientY - can.parentElement.offsetTop +window.scrollY;10drawFn(op);11document.onmousemove =function(e) {12document.body.style.cursor = 'pointer';13op.bx =op.ex;14op.by =op.ey;15op.ex = e.clientX - can.parentElement.offsetLeft +window.scrollX;16op.ey = e.clientY - can.parentElement.offsetTop +window.scrollY;17drawFn(op);18};19document.onmouseup =function() {20document.body.style.cursor = 'default';21document.onmouseup = document.onmousemove =null;22};23};24}

    1functiondrawFn(op) {2vardeg = Math.floor(360 /pieace);3for(vari = 0, l = 360; i < l; i +=deg) {4drawRotate(i / 180 * Math.PI,function(ctx) {5draw(op);6});7}8}

    需要注意,e.button 用来判断是鼠标哪个键,0是左键

    这里又用到了前边的drawRotate 和 draw。

    ************************************

    至此,应该可以画出对称的线条了。

    以下就是锦上添花的事情了

    ************************************

    增加移动端的绘制支持(惭愧,没怎么写过移动端,欢迎多指教)

    1functionbindWp() {2can.addEventListener('touchstart',function(e) {3op = can.op ={};4op.ex = op.bx = e.touches[0].clientX - can.parentElement.offsetLeft +window.scrollX;5op.ey = op.by = e.touches[0].clientY - can.parentElement.offsetTop +window.scrollY;6drawFn(op);7can.addEventListener('touchmove', touchMoveFn);8can.addEventListener('touchend', touchEndFn);9});1011functiontouchEndFn() {12document.body.style.cursor = 'default';13can.removeEventListener('touchmove', touchMoveFn);14can.removeEventListener('touchend', touchEndFn);15}1617functiontouchMoveFn(e) {18op =can.op;19document.body.style.cursor = 'pointer';20op.bx =op.ex;21op.by =op.ey;22op.ex = e.touches[0].clientX - can.parentElement.offsetLeft +window.scrollX;23op.ey = e.touches[0].clientY - can.parentElement.offsetTop +window.scrollY;24drawFn(op);25returnfalse;26}27}

    3>设置等

    这里dom比较简单,就略过了。只说一项,下载canvas图片到本地

    最简单的,右键保存图片到本地,但是你肯定会骂我傻,谁不知道这操作啊;那么就来稍微装X一下吧

    线上代码

    1functiondownload() {2vardata = can.toDataURL('image/png', 0.8);3var$a = document.createElement('a');4$a.download = imgName.value || 'default.png';5$a.target = '_blank';6$a.href =data;7$a.click();8}

    (写这个博客的时候,返现自己把这个方法写麻烦了,绕远了。/手动尴尬,这里直接改了)

    关键点在于a.download属性,这个是把文件下载到本地的关键哦,然后要把canvas转成base64(canvas.toDataUrl方法,不清楚的可以去去了解下,这里不再赘述)

    ******************************************************

    最后,附上完整代码(可能会和上边的有点出如,还在调整)

    + View Code

    **************偷偷留个名字,防抓  博客园-fe-bean***************

    涉及姿势点总结

    1.canvas_translate

    2.canvas_rotate

    3.canvas_toDataUrl

    4.a.download  &&  base64

    其余的想起来再添加吧

    最后,欢迎大家多提意见、交流,点赞转载那就更棒了。

    再丢一张图

    下期再见咯~~~

    ****************   少侠留步,能看到这里的,我要给你们一个奖励   ***************

    这个demo是可以在移动端玩的,意味着有电容笔的亲,可以爽啊~(个别浏览器脑残会左右来回跑~~)

    没有电容笔的亲,肯定是大多数,我们一样能玩啊!!!

    叫你们快速做一款电容笔(当然没那么好用)

    1.找一只木质铅笔

    2.削出铅笔头

    3.把铅笔头斜着磨平,如图

    4.用磨平这一侧去电容屏上画(开始吧)

    我上边那张图就是拿铅笔画的~~~

    欢迎加入技术qq群:364595326

    相关文章

      网友评论

        本文标题:canvas实现简单的Amaziograph效果画对称图

        本文链接:https://www.haomeiwen.com/subject/gkkeattx.html