canvas教程

HTML5 Canvas+JS画图程序

字号+ 作者:H5之家 来源:H5之家 2015-11-20 18:04 我要评论( )

canvas 写的小项目,练练手,一个画图板,功能点有绘制、直线、圆、方形、涂鸦、线条粗细、颜色切换、撤销、回退、保存、下载、外部图片拖入等 , 用的技术是包含html5中的本地存储、下载、canvas 等技术,上图。 这个项目中用到了canvas的很多基础功能 。在

   canvas 写的小项目,练练手,一个画图板,功能点有绘制、直线、圆、方形、涂鸦、线条粗细、颜色切换、撤销、回退、保存、下载、外部图片拖入等 , 用的技术是包含html5中的本地存储、下载、canvas 等技术,上图。



这个项目中用到了canvas的很多基础功能 。在这里解释一下核心代码的思路。

   在这个项目中 我用到了2层canvas, 原因是当用户在画部分图形的时候希望看到绘画的过程,比如在画圆的时候,而canvas 目前支持的就是清空和绘制操作, 所以在这里我用了bak层做了一个假象。用户一开始的所有绘制都是在bak层做的绘制,之后当鼠标松开的时候才会到真正的canvas层保存。这个是核心思路。

接下来我们来看一下代码的构造。
1.首先第一部。是做对象初始化, 包括有初始化canvas ,context,height,width这个很简单就不做多的解释了 代码如下

 //初始化
 var initCanvas = function(){
 canvas = document.getElementById("canvas");
 canvas.width = canvasWidth;
 canvas.height = canvasHeight;
 context = canvas.getContext('2d');
 canvasTop = $(canvas).offset().top
 canvasLeft = $(canvas).offset().left;

 canvas_bak = document.getElementById("canvas_bak");
 canvas_bak.width = canvasWidth;
 canvas_bak.height = canvasHeight;
 context_bak = canvas_bak.getContext('2d');
 }

2. 第二部就是绘制了 ,思路是当鼠标点下得时候确定一个初始点,当鼠标移动的时候开始绘制。之前说过鼠标移动只是在bak层绘制 , 当松开鼠标时把bak层的添加到canvas层 。 那么这里就包含三个事件 。 点击,移动,松开,对应了三个不同的方法 。代码如下:

//鼠标按下获取 开始xy开始画图 var mousedown = function(e){ context.strokeStyle= color; context_bak.strokeStyle= color; context_bak.lineWidth = size; e=e||window.event; startX = e.clientX - canvasLeft; startY = e.clientY - canvasTop; context_bak.moveTo(startX ,startY ); canDraw = true; if(graphType == 'pencil'){ context_bak.beginPath(); }else if(graphType == 'circle'){ context.beginPath(); context.moveTo(startX ,startY ); context.lineTo(startX +2 ,startY+2); context.stroke(); }else if(graphType == 'rubber'){ context.clearRect(startX - size * 10 , startY - size * 10 , size * 20 , size * 20); } }; //鼠标离开 把蒙版canvas的图片生成到canvas中 var mouseup = function(e){ e=e||window.event; canDraw = false; var image = new Image(); if(graphType!='rubber'){ image.src = canvas_bak.toDataURL(); image.onload = function(){ context.drawImage(image , 0 ,0 , image.width , image.height , 0 ,0 , canvasWidth , canvasHeight); clearContext(); saveImageToAry(); } var x = e.clientX - canvasLeft; var y = e.clientY - canvasTop; context.beginPath(); context.moveTo(x ,y ); context.lineTo(x +2 ,y+2); context.stroke(); } }; // 鼠标移动 var mousemove = function(e){ e=e||window.event; var x = e.clientX - canvasLeft; var y = e.clientY - canvasTop; //方块 4条直线搞定 if(graphType == 'square'){ if(canDraw){ context_bak.beginPath(); clearContext(); context_bak.moveTo(startX , startY); context_bak.lineTo(x ,startY ); context_bak.lineTo(x ,y ); context_bak.lineTo(startX ,y ); context_bak.lineTo(startX ,startY ); context_bak.stroke(); } //直线 }else if(graphType =='line'){ if(canDraw){ context_bak.beginPath(); clearContext(); context_bak.moveTo(startX , startY); context_bak.lineTo(x ,y ); context_bak.stroke(); } //画笔 }else if(graphType == 'pencil'){ if(canDraw){ context_bak.lineTo(e.clientX - canvasLeft ,e.clientY - canvasTop); context_bak.stroke(); } //圆 未画得时候 出现一个小圆 }else if(graphType == 'circle'){ clearContext(); if(canDraw){ context_bak.beginPath(); var radii = Math.sqrt((startX - x) * (startX - x) + (startY - y) * (startY - y)); context_bak.arc(startX,startY,radii,0,Math.PI * 2,false); context_bak.stroke(); }else{ context_bak.beginPath(); context_bak.arc(x,y,20,0,Math.PI * 2,false); context_bak.stroke(); } //涂鸦 未画得时候 出现一个小圆 }else if(graphType == 'handwriting'){ if(canDraw){ context_bak.beginPath(); context_bak.strokeStyle = color; context_bak.fillStyle = color; context_bak.arc(x,y,size*10,0,Math.PI * 2,false); context_bak.fill(); context_bak.stroke(); context_bak.restore(); }else{ clearContext(); context_bak.beginPath(); context_bak.fillStyle = color; context_bak.arc(x,y,size*10,0,Math.PI * 2,false); context_bak.fill(); context_bak.stroke(); } //橡皮擦 不管有没有在画都出现小方块 按下鼠标 开始清空区域 }else if(graphType == 'rubber'){ context_bak.lineWidth = 1; clearContext(); context_bak.beginPath(); context_bak.strokeStyle = '#000000'; context_bak.moveTo(x - size * 10 , y - size * 10 ); context_bak.lineTo(x + size * 10 , y - size * 10 ); context_bak.lineTo(x + size * 10 , y + size * 10 ); context_bak.lineTo(x - size * 10 , y + size * 10 ); context_bak.lineTo(x - size * 10 , y - size * 10 ); context_bak.stroke(); if(canDraw){ context.clearRect(x - size * 10 , y - size * 10 , size * 20 , size * 20); } } };

 3. 顺便提一下撤销和回退的做法。之前有提过在鼠标松开的时候,我们会把bak层的内容绘制到canvas层中,那么在这个时候,同步的会把一份图片信息存到一个数组中去,用于回滚,当点击撤销的时候只需要把上一个的图片信息取出来,在绘制一遍canvas即可。撤销回退同理。

 

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

相关文章
  • html5canvas核心技术图形、动画与游戏开发源码

    html5canvas核心技术图形、动画与游戏开发源码

    2017-05-02 17:42

  • 打印html5中Canvas的方法

    打印html5中Canvas的方法

    2017-05-01 15:03

  • HTML5+Canvas调用手机拍照功能实现图片上传(下)

    HTML5+Canvas调用手机拍照功能实现图片上传(下)

    2017-04-30 17:00

  • HTML5新特性详解(三)

    HTML5新特性详解(三)

    2017-04-30 16:03

网友点评
"