3.3 自定义画板

前面的章节已经将Canvas的API大致介绍完毕了,下面我们来制作一个自定义画板,进一步熟悉一下这些API的用法。
3.3.1 画板的建立
建立一个画板的步骤如下:
(1)当鼠标按下的时候,开始描画,此处需要加入鼠标按下事件。
(2)当鼠标弹起的时候,结束描画,此处需要加入鼠标弹起事件。
(3)在鼠标按下并且移动的时候,在鼠标经过的路径上画线,此处需要加入鼠标移动事件。
代码清单3-22实现了建立一个简单画板的功能。
代码清单 3-22

<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8" />
</head>
<body><canvas id="canvas" width="600" height="300""></canvas><br><script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//画一个黑色矩形
ctx.fillStyle="black";
ctx.fillRect(0,0,600,300);
//按下标记
var onoff = false;
var oldx = -10;
var oldy = -10;
//设置颜色
var linecolor = "white";
//设置线宽
var linw = 4;
//添加鼠标移动事件
canvas.addEventListener("mousemove",draw,true);
//添加鼠标按下事件
canvas.addEventListener("mousedown",down,false);
//添加鼠标弹起事件
canvas.addEventListener("mouseup",up,false);
function down(event){onoff = true;oldx = event.pageX-10;oldy = event.pageY-10;
}
function up(){onoff = false;
}
function draw(event){if(onoff == true){ var newx = event.pageX-10; var newy = event.pageY-10; ctx.beginPath();ctx.moveTo(oldx,oldy);ctx.lineTo(newx,newy);ctx.strokeStyle=linecolor;ctx.lineWidth=linw;ctx.lineCap="round";ctx.stroke();oldx = newx;oldy = newy;};
};
</script></body>
</html>

运行效果如图3-38所示。

代码清单3-22建立了一个黑色画板,当鼠标在画板上移动时,随鼠标的移动会画出白色线条。
在代码清单3-22中,下列代码画了一个黑色矩形区域,作为画板。

//画一个黑色矩形
ctx.fillStyle="black";
ctx.fillRect(0,0,600,300);

下面建立了3个变量,变量onoff用来控制鼠标是否按下,只有当鼠标按下的时候才会开始绘图。变量oldx、oldy表示鼠标发生移动前的坐标。

//按下标记
var onoff = false;
var oldx = -10;
var oldy = -10;

下面设置画笔的颜色为白色,线宽为4。

//设置颜色
var linecolor = "white";
//设置线宽
var linw = 4;

下面给Canvas添加了鼠标按下侦听事件,当鼠标按下的时候,会调用down函数。

//添加鼠标按下事件
canvas.addEventListener("mousedown",down,false);

下面给Canvas添加了鼠标弹起侦听事件,当鼠标弹起的时候,会调用up函数。

//添加鼠标弹起事件
canvas.addEventListener("mouseup",up,false);

下面给Canvas添加了鼠标移动侦听事件,当鼠标在Canvas上移动的时候,会持续调用draw函数。

//添加鼠标移动事件
canvas.addEventListener("mousemove",draw,true);

下面看看up、down、draw 3个函数中的内容。
down函数是在鼠标按下的时候调用的。当调用down函数的时候,会将onoff变量设置为true,表示开始绘图,并给oldx、oldy赋予鼠标当前位置的坐标值。

function down(event){onoff = true;oldx = event.pageX-10;oldy = event.pageY-10;
}

up函数是在鼠标弹起的时候调用的。当调用up函数的时候,将onoff变量设置为false,表示结束绘图。

function up(){onoff = false;
}

draw函数是在鼠标发生移动的时候不断持续调用的。当调用draw函数的时候,首先判断onoff变量的值,即判断鼠标是否处于按下状态,如果鼠标处于按下状态,则开始画线。

function draw(event){if(onoff == true){ var newx = event.pageX-10; var newy = event.pageY-10; ctx.beginPath();ctx.moveTo(oldx,oldy);ctx.lineTo(newx,newy);ctx.strokeStyle=linecolor;ctx.lineWidth=linw;ctx.lineCap="round";ctx.stroke();oldx = newx;oldy = newy;};
};

每次画线时,需要确定线条的起始位置和结束位置,线条的起始位置就是坐标(oldx,oldy),然后把当前鼠标位置作为线条的结束位置,代码如下所示:

var newx = event.pageX-10;
var newy = event.pageY-10;

接着,利用moveTo和lineTo画线,代码如下所示:

ctx.beginPath();
ctx.moveTo(oldx,oldy);
ctx.lineTo(newx,newy);
ctx.strokeStyle=linecolor;
ctx.lineWidth=linw;
ctx.lineCap="round";
ctx.stroke();

上面的代码是画一条从坐标(oldx,oldy)到坐标(newx,newy)的线段,并设置了线条的颜色、宽度和线帽的类型。
在此次绘制结束后,新的鼠标位置将作为下一次画线的起始位置,代码如下所示:

oldx = newx;
oldy = newy;

上面的代码已经实现了一个最简单的画板功能。下面将其再完善一下,即加入按钮操作改变画笔颜色和线条宽度的功能。完整的代码如代码清单3-23所示。
代码清单 3-23

<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8" />
</head>
<body><canvas id="canvas" width="600" height="300""></canvas><br>
<button style="width:80px;background-color:yellow;" onclick='linecolor = "yellow";'>YELLOW</button>
<button style="width:80px;background-color:red;" onclick='linecolor = "red";'>RED</button>
<button style="width:80px;background-color:blue;" onclick='linecolor = "blue";'> BLUE</button>
<button style="width:80px;background-color:green;" onclick='linecolor = "green";'> GREEN</button>
<button style="width:80px;background-color:white;" onclick='linecolor = "white";'> WHITE</button>
<button style="width:80px;background-color:black;color:white;" onclick='linecolor = "black";'>BLACK</button><br>
<button style="width:80px;background-color:white;" onclick="linw = 4;">4px</button>
<button style="width:80px;background-color:white;" onclick="linw = 8;">8px</button>
<button style="width:80px;background-color:white;" onclick="linw = 16;">16px</button><script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//画一个黑色矩形
ctx.fillStyle="black";
ctx.fillRect(0,0,600,300);
//按下标记
var onoff = false;
var oldx = -10;
var oldy = -10;
//设置颜色
var linecolor = "white";
//设置线宽
var linw = 4;
//添加鼠标移动事件
canvas.addEventListener("mousemove",draw,true);
//添加鼠标按下事件
canvas.addEventListener("mousedown",down,false);
//添加鼠标弹起事件
canvas.addEventListener("mouseup",up,false);
function down(event){onoff = true;oldx = event.pageX-10;oldy = event.pageY-10;
}
function up(){onoff = false;
}
function draw(event){if(onoff == true){ var newx = event.pageX-10; var newy = event.pageY-10; ctx.beginPath();ctx.moveTo(oldx,oldy);ctx.lineTo(newx,newy);ctx.strokeStyle=linecolor;ctx.lineWidth=linw;ctx.lineCap="round";ctx.stroke();oldx = newx;oldy = newy;};
};</script></body>
</html>

运行效果如图3-39所示。

在代码清单3-23中:
下面的代码加入了6个按钮,并加入了单击事件,当单击不同按钮的时候,就会相应地改变画笔的颜色。

<button style="width:80px;background-color:yellow;" onclick='linecolor = "yellow";'>YELLOW</button>
<button style="width:80px;background-color:red;" onclick='linecolor = "red";'>RED</button>
<button style="width:80px;background-color:blue;" onclick='linecolor = "blue";'>BLUE</button>
<button style="width:80px;background-color:green;" onclick='linecolor = "green";'>GREEN</button>
<button style="width:80px;background-color:white;" onclick='linecolor = "white";'>WHITE</button>
<button style="width:80px;background-color:black;color:white;" onclick='linecolor = "black";'>BLACK</button>

下面的代码加入了3个按钮,并加入了单击事件,当单击不同按钮的时候,就会相应地改变线条的宽度。

<button style="width:80px;background-color:white;" onclick="linw = 4;">4px</button>
<button style="width:80px;background-color:white;" onclick="linw = 8;">8px</button>
<button style="width:80px;background-color:white;" onclick="linw = 16;">16px</button>

3.3.2 Canvas画布的导出功能
在3.3.1节中我们建立了一个画板,这一节再来给画板添加图片导出功能,即复制Canvas画板上的图像,使其保存为图片格式。
要将Canvas画板保存为图片格式,只需要使用下面的方法即可:

canvas.toDataURL("image/png");

现在可在页面上新建一个< img >标签,然后将复制的Canvas内容用< img>表示出来。完整代码如代码清单3-24所示。
代码清单 3-24

<!DOCTYPE HTML>
<html>
<head><meta charset="utf-8" />
</head>
<body>
<canvas id="canvas" width="600" height="300""></canvas><br>
<button style="width:80px;background-color:yellow;" onclick='linecolor = "yellow";'>YELLOW</button>
<button style="width:80px;background-color:red;" onclick='linecolor = "red";'>RED</button>
<button style="width:80px;background-color:blue;" onclick='linecolor = "blue";'>BLUE</button>
<button style="width:80px;background-color:green;" onclick='linecolor = "green";'>GREEN</button>
<button style="width:80px;background-color:white;" onclick='linecolor = "white";'>WHITE</button>
<button style="width:80px;background-color:black;color:white;" onclick='linecolor = "black";'>BLACK</button><br>
<button style="width:80px;background-color:white;" onclick="linw = 4;">4px</button>
<button style="width:80px;background-color:white;" onclick="linw = 8;">8px</button>
<button style="width:80px;background-color:white;" onclick="linw = 16;">16px</button>
<br>
<button style="width:80px;background-color:pink;" onclick="copyimage();">EXPORT</button>
<br>
<img src="" id="image_png"  width="600" height="300">
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
//画一个黑色矩形
ctx.fillStyle="black";
ctx.fillRect(0,0,600,300);
//按下标记
var onoff = false;
var oldx = -10;
var oldy = -10;
//设置颜色
var linecolor = "white";
//设置线宽
var linw = 4;
//添加鼠标移动事件
canvas.addEventListener("mousemove",draw,true);
//添加鼠标按下事件
canvas.addEventListener("mousedown",down,false);
//添加鼠标弹起事件
canvas.addEventListener("mouseup",up,false);
function down(event){onoff = true;oldx = event.pageX-10;oldy = event.pageY-10;
}
function up(){onoff = false;
}
function draw(event){if(onoff == true){ var newx = event.pageX-10; var newy = event.pageY-10; ctx.beginPath();ctx.moveTo(oldx,oldy);ctx.lineTo(newx,newy);ctx.strokeStyle=linecolor;ctx.lineWidth=linw;ctx.lineCap="round";ctx.stroke();oldx = newx;oldy = newy;};
};
function copyimage(event){var img_png_src = canvas.toDataURL("image/png");document.getElementById("image_png").src = img_png_src;
}
</script></body>
</html>

运行效果如图3-40所示。

如果想要将图片保存为图片文件,还需要借助PHP或ASP等工具,这里就不做讨论了。

《HTML5 Canvas游戏开发实战》——3.3 自定义画板相关推荐

  1. HTML5 Canvas游戏开发实战 PDF扫描版

    HTML5 Canvas游戏开发实战主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读 ...

  2. 《HTML5 Canvas游戏开发实战》——2.1 绘制基本图形

    本节书摘来自华章计算机<HTML5 Canvas游戏开发实战>一书中的第2章,第2.1节,作者:张路斌著, 更多章节内容可以访问云栖社区"华章计算机"公众号查看. 2. ...

  3. HTML5 canvas游戏开发实战 7 : 是男人就下一百层“游戏

    卷轴游戏是因为游戏的背景看起来像是卷轴在滚动而得名,"是男人就下一百层"即为一款2D卷轴游戏.游戏中玩家的任务是让主角持续下落,其过程中会遇到各种麻烦,或地板消失,或地板消失,或地 ...

  4. 【HTML5 Canvas游戏开发】笔记(一) 概述和基础讲解

    本系列文章由Shin-Knight编写,转载需注明出处. 作者:Shin-Knight 邮箱:shinknight@163.com 文章链接:http://www.cnblogs.com/knight ...

  5. HTML5 Canvas游戏开发(一)基础知识

    一.绘制基本图形 在每次用canvas画布时,都有几步是"套路" 1.在HTML中创建Canvas画布: <canvas id="mycanvas" wi ...

  6. HTML5 Canvas游戏开发(二)高级功能

    一.变形 1.放大和缩小 scale(X,Y)函数. 当使用该函数时,其起始坐标值也被放大或缩小.当X.Y为负值时,可以实现翻转. 2.平移变换 translate(X,Y)函数. 表示水平方向向左移 ...

  7. HTML5游戏开发实战

    <HTML5游戏开发实战> 基本信息 原书名:HTML5 Games Development by Example: Beginner's Guide 作者: (美)Makzan 译者: ...

  8. 从踩坑到填坑|淘宝Web 3D应用与游戏开发实战

    导读:本文是淘宝前端技术专家--徐乾伟(烧鹅)分享的淘宝 Web 3D 应用与游戏开发实战,这个话题在业界被谈及得比较少.今天将会从移动.3D.游戏三种交叉的话题来和大家探讨.接下来和小编一起从初试 ...

  9. 微信小游戏开发实战教程15-关卡编辑器的制作以及关卡分享功能的实现

    微信小游戏开发实战系列的第15篇. 本节主要内容有游戏中的关卡编辑器的实现思路以及如何利用分享功能将自己制作的关卡与好友分享. 如果你没有任何的游戏开发经验,欢迎阅读我的"人人都能做游戏&q ...

最新文章

  1. AngularJS中的指令全面解析(必看)
  2. 体验cygwin纪实
  3. linux下的c库函数大全
  4. 简述平均池化和最大池化
  5. 学python可以干嘛-学习Python可以做什么
  6. 如何评价rcnn、fast-rcnn和faster-rcnn这一系列方法?
  7. 某公司邮件系统的安全检测
  8. python3安装scrapy及使用方法(爬虫框架)
  9. ROS 科大讯飞语音(三)识别篇
  10. java stream 泛型
  11. PHP获取当前页面的完整URL
  12. [Swift]LeetCode1051.高度检查器 | Height Checker
  13. 玩与学 | 《乐高EV3机器人搭建与编程》
  14. 小小一方士 C# Async\Await 之 上传/下载文件进度条实现原理
  15. 计算机网络情景分析 写在开始
  16. 如何将安卓系统的手机屏幕同步显示在电脑上
  17. Mac苹果电脑安装软件显示:映像数据已损坏的解决办法
  18. 基于Python/Capl脚本 对通信矩阵报文(Flexray/CAN)的周期检测(一)
  19. Python基础:实现猜拳游戏(简单版)
  20. NUCLEO-L476RG开发板学习笔记汇总

热门文章

  1. C# 委托与事件(delegate)
  2. How to make your 100k to 10k (5)
  3. 商务人士,你抛弃邮箱了吗?
  4. 原生JS与Jquery删除iframe并释放内存(IE)
  5. 思科交换机2950 强制恢复出厂设置(清密码)
  6. php curl 及其参数
  7. 随记:Linux下修改网络配置
  8. 在WCF中的异常处理方法
  9. 左边工具栏 隐藏_203 【Ps基础】 工具栏
  10. Python实现对nginx日志access.log统计