今天给各网友分享一款基于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. Mysql优化与使用集锦

    MyISAM的读性能是比Innodb强 MyISAM的索引和数据是分开的,并且索引是有压缩的 Innodb是索引和数据是紧密捆绑的,没有使用压缩从而会造成Innodb比MyISAM体积庞大不小 MyI ...

  2. [C#.NET] X509 數位電子簽章

    摘自: http://www.dotblogs.com.tw/yc421206/archive/2012/06/30/73140.aspx 在上篇[C#.NET] 字串及檔案,利用 RSA 演算法加解 ...

  3. 在Docker和Kubernetes上运行MongoDB微服务

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟.容器是完全使用沙箱机制,相互之间不会有任何接 ...

  4. [转]JavaScript异步机制详解

    原文: https://www.jianshu.com/p/4ea4ee713ead --------------------------------------------------------- ...

  5. Python+Django+SAE系列教程13-----MySQL记录的添\删\改

    建立了数据库后,我们就来做一个简单的表(person_classroom)的加入.删除.改动的操作. 首先我们建立一个加入的页面的模板Classroom_Add.html(加入的表单)并把它放在Bid ...

  6. zend studio 13.0.0 安装破解汉化

    zend studio 13安装破解汉化步骤 官网原版下载 http://downloads.zend.com/studio-eclipse/13.0.0/ZendStudio-13.0.0-win3 ...

  7. java基础知识精华

    转载:https://www.jianshu.com/p/6c078abb720f java基础知识 java内存模型 java运行时数据区域 hashMap 如何解决冲突 存储方式 冲突达到一定数量 ...

  8. 如何申请iOS开发者证书/发布app到手机

    申请iOS开发者证书 http://blog.csdn.net/htttw/article/details/7939405 如何向App Store提交应用 http://www.cocoachina ...

  9. 外媒关注:中国版Twitter新浪微博推出微米对抗微信

    Sina, China’s answer to Twitter, enters the mobile messaging battle with its own app 中国版Twitter新浪,用自 ...

  10. Android APP安装后不在桌面显示图标的应用场景

    一般情况下是由于特殊情况下,需要隐藏app的启动入口,即在launcher界面不需要显示该入口,会由其他app跳转至.怎么设置如下代码: <activity android:name=" ...