今天给各网友分享一款基于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. 解决Vue用Nginx做web服务器报错favicon.ico 404 (Not Found)的问题

    有多种解决方案 1.vue静态资源 vue中为网页增加favicon的最便捷的方式为使用link标签 <link rel="shortcut icon" type=" ...

  2. window yii2 安装插件 报yiisoft/yii2 2.0.x-dev requires ext-mbstring错

    Problem 1 - yiisoft/yii2 2.0.x-dev requires ext-mbstring * -> the requested PHP extens ion mbstri ...

  3. Android -- SurfaceView绘制

    SurfaceView SurfaceView是View的一个特殊子类,它的目的是另外提供一个线程进行绘制操作. 步骤 1.用SurfaceView进行绘制,首先要创建一个类,继承 SurfaceVi ...

  4. 微信-js sdk invalid signature签名错误 问题解决

    如果出现 invalid signature,首先可以确定的是你的签名算法有问题.建议:首先查看微信官方网站给出的解决方案,链接为: http://mp.weixin.qq.com/wiki/7/aa ...

  5. (转)实现AI中LOD优化技术

    LOD(Level Of Detail)是3D渲染中用到的概念,按照wikipedia上的翻译,可以译为“细节层次”,它是一种根据与观察点的距离,来减低物体或者模型的复杂度来提升渲染效率的优化技术,因 ...

  6. x为正变数,求y=x^3/(x^4+4)的最大值

    设z=1/y=x4+4/x3 显然,当z有最小值时,y有最大值,求得zmin,就得到了ymax 而z=x+4/x3=x/3+x/3+x/3+4/x3 根据正实数算术平均数大于等于它们的几何平均数的定理 ...

  7. 初识 NoSQL Databases RethinkDB

    初识 NoSQL Databases RethinkDB rethinkDB所有数据都是基于 json的Document; 官网:http://rethinkdb.com/ github: https ...

  8. MySQL 工具

    MySQL 客户端工具: 1:mysql       #mysql的功能和Oracle的sqlplus一样,它为用户提供一个命令行接口来管理Mysql服务器. 2:mysqladmin #mysqla ...

  9. 获得客户端详细信息以及每个进程的sql语句

    db性能下降时很多朋友都想监控到是哪个客户端.哪个用户.哪台客户端发起的什么会话sql语句, 但是微软自带的要使用profiler才能实现,但是考虑性能问题,很多人不愿意! 网上有很多脚本能监控到客户 ...

  10. 查看Buffer Pool使用情况--[转]

    ----源自:微软官方博客论坛 我的SQL Server buffer pool很大,有办法知道是哪些对象吃掉我的buffer Pool内存么?比方说,能否知道是哪个数据库,哪个表,哪个index占用 ...