今天给各网友分享一款基于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. AJAX前台传过来的中文在后台获取是乱码问题

    前台传值时加上encodeURI $.SaveForm({ url: "${basePath}/soft/mergeSoftAction_add.do?ids="+ids+&quo ...

  2. http://m.blog.csdn.net/article/details?id=49132747

    http://m.blog.csdn.net/article/details?id=49132747

  3. 【笔记】css 1像素边框

    有时候在移动端显示1像素的边框时 可能因为dpi 的原因造成像素有变差 所以为了达到显示的像素达到预期效果就要编写一个css 通用类达到1像素边框的效果 关于dpi 的解释请看张鑫旭老师的文章:htt ...

  4. 推荐大家一个CSS书写规范

    CSS书写顺序 1.位置属性(position, top, right, z-index, display, float等) 2.大小(width, height, padding, margin) ...

  5. 使用Loader实时查询本地数据库用法

    在看Android的文档时,看到了这么一个东西: Loader 究竟是什么东西呢? Introduced in Android 3.0, loaders make it easy to asynchr ...

  6. jvm分析备忘

    是什么 jps   查看所有的jvm进程,包括进程ID,进程启动的路径等等. jstack   观察jvm中当前所有线程的运行情况和线程当前状态. 系统崩溃了?如果java程序崩溃生成core文件,j ...

  7. [Elasticsearch] 向已存在的索引中加入自己定义filter/analyzer

    问题描写叙述 随着应用的不断升级,索引中的类型也会越来越多,新添加的类型中势必会使用到一些自己定义的Analyzer.可是通过_settings端点的更新API不能直接在已经存在的索引上使用. 在se ...

  8. Linux lvs DR配置

    三台服务器,(1)做路由.(2)(3)做realserver IP为:192.168.196.121  (1) 192.168.196.122   (2) 192.168.196.123   (3) ...

  9. 解析theme()

    drupal_render()只是对theme()的调用做了包装,真正做任务的还是theme(). function theme($hook, $variables = array()) { ... ...

  10. UVA1492 - Adding New Machine(扫描线)

    UVA1492 - Adding New Machine(扫描线) option=com_onlinejudge&Itemid=8&page=show_problem&cate ...