今天给各网友分享一款基于HTML5 Canvas的画板涂鸦动画。记得之前我们分享过一款HTML5 Canvas画板工具,可以切换不同的笔刷,功能十分强大。本文今天要再来分享一款基于HTML5 Canvas的画板涂鸦动画应用,功能和之前那个类似,但是新增了回撤和清空画板的操作,实现思路也基本类似。实现的效果图如下:

在线预览   源码下载

实现的代码。

html代码:

<div class="wrap">
<canvas id="canvas" class="fl" width="600" height="400">
</canvas>
<div id="control" class="fl">
<div id="canvas-color">
<h5>
画笔颜色</h5>
<ul>
<li style="background: #fef4ac"></li>
<li style="background: #0018ba"></li>
<li style="background: #ffc200"></li>
<li style="background: #f32f15"></li>
<li style="background: #cccccc"></li>
<li style="background: #5ab639"></li>
</ul>
</div>
<div id="canvas-brush">
<h5>
画笔大小</h5>
<span class="small-brush"></span><span class="middle-brush"></span><span class="big-brush">
</span>
</div>
<div id="canvas-control">
<h5>
操作</h5>
<span title="上一步" class="return-control"></span><span title="下一步" class="next-control">
</span><span title="清除" class="empty-control"></span>
</div>
<div id="canvas-drawImage">
<h5>
生成图像</h5>
<p>
<button class="drawImage">
生成图像</button></p>
</div>
</div>
</div>
<div id="imgDiv">
</div>

css代码:

 html, body, canvas, div, ul, li, h5, p
{
margin:;
padding:;
-moz-user-select: none;
-webkit-user-select: none;
}
img
{
border: 1px #ccc solid;
}
ul, li
{
list-style: none;
}
.wrap
{
width: 740px;
margin: 20px auto 5px;
border: 1px #ccc solid;
overflow: hidden;
}
.fl
{
float: left;
display: inline;
}
#canvas
{
border-right: 1px #ccc solid;
cursor: crosshair;
}
#control
{
width: 130px;
height: 400px;
margin-left: 4px;
}
#control div
{
padding: 5px;
}
#canvas-color ul
{
overflow: hidden;
}
#canvas-color ul li
{
float: left;
display: inherit;
width: 13px;
height: 13px;
border: 3px #fff solid;
margin: 8px;
cursor: pointer;
}
#canvas-color ul li.js-border-color
{
border-color: #000;
}
#canvas-brush span
{
display: inline-block;
width: 10px;
height: 10px;
margin-left: 10px;
background: url(images/brush.png);
cursor: pointer;
}
#canvas-brush span.small-brush
{
background-position: -6px -6px;
}
#canvas-brush span.middle-brush
{
background-position: -31px -6px;
}
#canvas-brush span.big-brush
{
background-position: -56px -6px;
}
#canvas-brush span.js-bg-color
{
background-color: #aaa;
}
#canvas-control span
{
display: inline-block;
width: 20px;
height: 15px;
margin-left: 10px;
background: url(images/sketchpad_icons.png);
cursor: pointer;
}
#canvas-control span.return-control
{
background-position: -2px -148px;
}
#canvas-control span.next-control
{
background-position: right -168px;
}
#canvas-control span.empty-control
{
background-position: -2px -188px;
}
#canvas-control span.js-return-control
{
background-position: -2px -209px;
}
#canvas-control span.js-next-control
{
background-position: right -230px;
}
#canvas-control span.js-empty-control
{
background-position: -2px -251px;
}
#imgDiv
{
text-align: center;
}

js代码:

  var doc = document,
canvas = doc.getElementById('canvas'),
colorDiv = doc.getElementById('canvas-color'),
brushDiv = doc.getElementById('canvas-brush'),
controlDiv = doc.getElementById('canvas-control'),
drawImageDiv = doc.getElementById('canvas-drawImage'),
imgDiv = doc.getElementById('imgDiv');
function Canvas() {
this.init.apply(this, arguments);
}
Canvas.prototype = {
//存储当前表面状态数组-上一步
preDrawAry: [],
//存储当前表面状态数组-下一步
nextDrawAry: [],
//中间数组
middleAry: [],
//配置参数
confing: {
lineWidth: 1,
lineColor: "blue",
shadowBlur: 2
},
init: function (oCanvas, oColor, oBrush, oControl, oDrawImage, imgDiv) {
this.canvas = oCanvas;
this.context = oCanvas.getContext('2d');
this.colorDiv = oColor;
this.brushDiv = oBrush;
this.controlDiv = oControl;
this.drawImageDiv = oDrawImage;
this.imgDiv = imgDiv;
this._initDraw();
this._draw(oCanvas);
this.setColor();
this.setBrush();
this.preClick();
this.nextClick();
this.clearClick();
this.drawImage(oCanvas);
},
_initDraw: function () {
var preData = this.context.getImageData(0, 0, 600, 400);
//空绘图表面进栈
this.middleAry.push(preData);
},
//涂鸦主程序
_draw: function (oCanvas, context) {
var _this = this;
oCanvas.onmousedown = function (e) {
var x = e.clientX,
y = e.clientY,
left = this.parentNode.offsetLeft,
top = this.parentNode.offsetTop,
canvasX = x - left,
canvasY = y - top;
_this._setCanvasStyle();
//清除子路径
_this.context.beginPath();
_this.context.moveTo(canvasX, canvasY);
//当前绘图表面状态
var preData = _this.context.getImageData(0, 0, 600, 400);
//当前绘图表面进栈
_this.preDrawAry.push(preData);
document.onmousemove = function (e) {
var x2 = e.clientX,
y2 = e.clientY,
t = e.target,
canvasX2 = x2 - left,
canvasY2 = y2 - top;
if (t == oCanvas) {
_this.context.lineTo(canvasX2, canvasY2);
_this.context.stroke();
} else {
_this.context.beginPath();
}
}
document.onmouseup = function (e) {
var t = e.target;
if (t == oCanvas) {
//当前绘图表面状态
var preData = _this.context.getImageData(0, 0, 600, 400);
if (_this.nextDrawAry.length == 0) {
//当前绘图表面进栈
_this.middleAry.push(preData);
} else {
_this.middleAry = [];
_this.middleAry = _this.middleAry.concat(_this.preDrawAry);
_this.middleAry.push(preData);
_this.nextDrawAry = [];
$('.js-next-control').addClass('next-control');
$('.next-control').removeClass('js-next-control');
} _this._isDraw();
}
this.onmousemove = null;
}
}
},
//设置画笔
_setCanvasStyle: function () {
this.context.lineWidth = this.confing.lineWidth;
this.context.shadowBlur = this.confing.shadowBlur;
this.context.shadowColor = this.confing.lineColor;
this.context.strokeStyle = this.confing.lineColor;
},
//设置颜色
setColor: function () {
this.colorDiv.onclick = this.bind(this, this._setColor);
},
_setColor: function (e) {
var t = e.target;
if (t.nodeName.toLowerCase() == "li") {
this.confing.lineColor = t.style.backgroundColor;
$('.js-border-color').removeClass('js-border-color');
$(t).addClass('js-border-color');
}
},
//设置画笔大小
setBrush: function () {
this.brushDiv.onclick = this.bind(this, this._setBrush);
},
_setBrush: function (e) {
var t = e.target;
if (t.nodeName.toLowerCase() == "span") {
if (t.className.indexOf("small-brush") >= 0) {
this.confing.lineWidth = 3;
} else if (t.className.indexOf("middle-brush") >= 0) {
this.confing.lineWidth = 6;
} else if (t.className.indexOf("big-brush") >= 0) {
this.confing.lineWidth = 12;
}
$('.js-bg-color').removeClass('js-bg-color');
$(t).addClass('js-bg-color');
}
},
//判断是否已涂鸦,修改按钮状态
_isDraw: function () {
if (this.preDrawAry.length) {
$('.return-control').addClass('js-return-control');
$('.return-control').removeClass('return-control');
$('.empty-control').addClass('js-empty-control');
$('.empty-control').removeClass('empty-control');
} else {
return false;
}
},
//点击上一步-改变涂鸦当前状态
preClick: function () {
var pre = this.controlDiv.getElementsByTagName("span")[0];
pre.onclick = this.bind(this, this._preClick);
},
_preClick: function () {
if (this.preDrawAry.length > 0) {
var popData = this.preDrawAry.pop();
var midData = this.middleAry[this.preDrawAry.length + 1];
this.nextDrawAry.push(midData);
this.context.putImageData(popData, 0, 0);
}
if (this.nextDrawAry.length) {
$('.next-control').addClass('js-next-control');
$('.next-control').removeClass('next-control');
}
if (this.preDrawAry.length == 0) {
$('.js-return-control').addClass('return-control');
$('.return-control').removeClass('js-return-control');
}
},
//点击下一步-改变涂鸦当前状态
nextClick: function () {
var next = this.controlDiv.getElementsByTagName("span")[1];
next.onclick = this.bind(this, this._nextClick);
},
_nextClick: function () {
if (this.nextDrawAry.length) {
var popData = this.nextDrawAry.pop();
var midData = this.middleAry[this.middleAry.length - this.nextDrawAry.length - 2];
this.preDrawAry.push(midData);
this.context.putImageData(popData, 0, 0);
}
if (this.preDrawAry.length) {
$('.return-control').addClass('js-return-control');
$('.return-control').removeClass('return-control');
} if (this.nextDrawAry.length == 0) {
$('.js-next-control').addClass('next-control');
$('.next-control').removeClass('js-next-control');
}
},
//清空
clearClick: function () {
var clear = this.controlDiv.getElementsByTagName("span")[2];
clear.onclick = this.bind(this, this._clearClick);
},
_clearClick: function () {
var data = this.middleAry[0];
this.context.clearRect(0, 0, this.context.canvas.width, this.context.canvas.height);
this.preDrawAry = [];
this.nextDrawAry = [];
this.middleAry = [this.middleAry[0]];
this.controlDiv.getElementsByTagName("span")[0].className = "return-control";
this.controlDiv.getElementsByTagName("span")[1].className = "next-control";
this.controlDiv.getElementsByTagName("span")[2].className = "empty-control";
},
//生成图像
drawImage: function () {
var btn = this.drawImageDiv.getElementsByTagName("button")[0];
btn.onclick = this.bind(this, this._drawImage);
},
_drawImage: function () {
var url = this.canvas.toDataURL('image/png'),
img = new Image();
img.src = url;
this.imgDiv.innerHTML = "";
this.imgDiv.appendChild(img);
},
bind: function (obj, handler) {
return function () {
return handler.apply(obj, arguments);
}
}
}
new Canvas(canvas, colorDiv, brushDiv, controlDiv, drawImageDiv, imgDiv);

via:http://www.w2bc.com/Article/15776

一款基于HTML5 Canvas的画板涂鸦动画的更多相关文章

  1. 基于HTML5 Canvas粒子效果文字动画特效

    之前我们分享过很多超酷的文字特效,其中也有利用HTML5和CSS3的.今天我们要来分享一款基于HTML5 Canvas的文字特效,输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的 ...

  2. 4款基于html5 canvas充满想象力的重力特效

    今天给大家分享4个物理和重力实验,用来展示 html canvas 的强大.几年前,所有这些实验都必须使用 Java 或 Flash 才能做.在下面这些惊人的例子中,就个人而言,我比较喜欢仿真布料的那 ...

  3. smoke.js是一款基于HTML5 Canvas的逼真烟雾特效js插件。通过该js插件,可以非常轻松的在页面中制作出各种烟雾效果。

    Smoke.js 是一个浏览器默认警告系统的JavaScript替代品,如果你想要跨浏览器与平台的标准化JavaScript警告窗口,Smoke.js就是你想要的. Smoke.js是一个轻量级且灵活 ...

  4. 基于 HTML5 Canvas 实现的文字动画特效

    前言 文字是网页中最基本的元素,一般我们在网页上都是展示的静态文字,但是就效果来说,还是比较枯燥的.文字淡入淡出的动画效果在项目中非常实用,如果有某些关键的文字,可以通过这种动态的效果来提醒用户阅读. ...

  5. 基于HTML5 Canvas的网页画板实现教程

    HTML5的功能非常强大,尤其是Canvas的应用更加广泛,Canvas画布上面不仅可以绘制任意的图形,而且可以实现多种多样的动画,甚至是一些交互式的应用,比如网页网版.这次我们要来看的就是一款基于H ...

  6. 9款基于HTML5/SVG/Canvas的折线图表应用

    1.华丽的HTML5图表 可展示实时数据 HTML5在图表应用中也十分广泛,比起以前的网页图表,HTML5图表制作更便捷,功能更强大.这款HTML5图表插件外观十分华丽和专业,在数据展示方面也很有优势 ...

  7. 基于html5 canvas和js实现的水果忍者网页版

    今天爱编程小编给大家分享一款基于html5 canvas和js实现的水果忍者网页版. <水果忍者>是一款非常受喜欢的手机游戏,刚看到新闻说<水果忍者>四周年新版要上线了.网页版 ...

  8. 基于HTML5 Canvas的线性区域图表教程

    之前我们看到过很多用jQuery实现的网页图表,有些还是比较实用的.今天我们来介绍一款基于HTML5 Canvas的线性区域图表应用,这个图表应用允许你使用多组数据来同时展示,并且将数据结果以线性图的 ...

  9. 10款基于jquery实现的超酷动画源码

    1.jQuery二级下拉菜单 下拉箭头翻转动画 之前我们分享过不少基于jQuery的二级下拉菜单,甚至是多级的下拉菜单,比如这款jQuery/CSS3飘带状多级下拉菜单就非常华丽.但今天要介绍的这款j ...

随机推荐

  1. 如何高效的将excel导入sqlserver?

    大部分人都知道用oledb来读取数据到dataset,但是读取之后怎么处理dataset就千奇百怪了.很多人通过循环来拼接sql,这样做不但容易出错而且效率低下,System.Data.SqlClie ...

  2. C++ 相关面试题汇总

    多态性与虚函数 (陈维兴教材) (1)所谓多态性就是不同对象在收到相同的消息时,产生不同的动作.直观的说,多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作,从而可以使用相同的方式来调 ...

  3. 机器学习学习笔记之一:K最近邻算法(KNN)

    算法 假定数据有M个特征,则这些数据相当于在M维空间内的点 \[X = \begin{pmatrix} x_{11} & x_{12} & ... & x_{1M} \\ x_ ...

  4. T-SQL 之 DDL语法

    CREATE语句的开头都是一样的,然后是特定的细节. CREATE <object type> <object name> 一.CREATE DATABASE CREATE D ...

  5. 黑苹果安装 this is an unknown cpu model 0x3a

    一:安装说明 安装的是 mac os x 10.8.3 懒人版: ASUS b75ma 主板 i3 cpu 二:安装出现错误 百度谷歌,各种找原因,各路大神们都说是显卡的问题,因这电源管理只是一个警告 ...

  6. 金蝶K3,域环境中,无本地用户管理员权限的域用户如何设置注册表权限?

    如果该用户是属于Power Users组:只需要给用户添加注册表中的HKEY_LOCAL_MACHINE的SOFTWARE完全控制的权限.(勾选允许父项的继承权限和传播到该对象和所有子对象) 如果该用 ...

  7. OFBiz:解析doRequest()

    这里的doRequest()是指RequestHandler中的同名函数: public void doRequest(HttpServletRequest request, HttpServletR ...

  8. (三)hibernate单表操作

    0. 贴上节hbm文件 <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hib ...

  9. linux 查看 内存条具体信息, 几根内存条 命令

    sudo dmidecode | grep -A16 "Memory Device$" 需要root 权限.. [life@localhost mp3blaster-3.2.5]$ ...

  10. 使用Ubuntu12.04创建无线WiFi热点供手机上网

    [日期:2012-10-10]   1,单击右上角网络连接管理器(记得打开电脑的无线网络开关),选择“编辑连接…”   2,选择无线,然后单击添加.   3,{无线}输入连接名称,如longer,然后 ...