【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】

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

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】_第1张图片

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

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

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

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

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

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

 创意来源

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

 

配上我自己画的图先:

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】_第2张图片 

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

DEMO讲解

1.效果分析

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

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

c.配置区 -- 简单dom

 

简单来看,很容易实现嘛

 

2.开搞

1> 坐标系统

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

  

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

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

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

    1、存储ctx状态到栈,

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

    3、旋转指定角度,

    4、执行绘制函数fn,

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

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

 

然后,是绘制参考线坐标

 1 function baseLine() {
 2     ctx_role.clearRect(0, 0, ctx_role.canvas.width, ctx_role.canvas.height);
 3     var deg = 360 / pieace;
 4     console.log(deg);
 5     ctx_role.lineWidth = 1;
 6     ctx_role.strokeStyle = 'rgba(0,0,0,.5)';
 7     for (var i = 0, l = pieace; i < l; i++) {
 8         drawRotate(i * deg / 180 * Math.PI, function(ctx_role) {
 9             draw({
10                 bx: can_role.width / 2,
11                 by: can_role.width / 2,
12                 ex: can_role.width / 2 + can_role.width,
13                 ey: can_role.width / 2
14             }, ctx_role);
15         }, ctx_role);
16     }
17 }
1 function draw(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过冲中一直画线链接两个点。对拖拽不了解的可以去了解下,直接上代码

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

 

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

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

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

 

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

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

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

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

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

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

 

3>设置等

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

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

线上代码

1 function download() {
2     var data = can.toDataURL('image/png', 0.8);
3     var $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方法,不清楚的可以去去了解下,这里不再赘述)

 

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

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





    
    
    
    
    Document
    



    

下载到本地

  

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

涉及姿势点总结  

 

1.canvas_translate

2.canvas_rotate

3.canvas_toDataUrl

4.a.download  &&  base64

其余的想起来再添加吧

 

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

再丢一张图

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】_第3张图片

 

下期再见咯~~~

 

 

 

 

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

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

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

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

1.找一只木质铅笔

2.削出铅笔头

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

【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】_第4张图片

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

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

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

 

转载于:https://www.cnblogs.com/ufex/p/6689004.html

你可能感兴趣的:(【canvas系列】canvas实现“ 简单的Amaziograph效果”--画对称图【强迫症福利】)