没事仿照windows画板工具用canvas实现了一个简易版的画板。

html:

 <!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>画板</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<div class="toolbar js-toolbar">
<div class="toolbar-box">
<div class="toolbar-main">
<div class="shape-box">
<ul class="shape-lst js-tool-lst">
<!-- <li data-tool="eraser">橡皮擦</li> -->
<li data-tool="eraserAll">清除全部</li>
</ul>
</div>
</div>
<div class="toolbar-title">工具</div>
</div>
<div class="toolbar-split"></div>
<div class="toolbar-box">
<div class="toolbar-main">
<div class="shape-box">
<ul class="shape-lst js-shape-lst">
<li data-tool="line" class="selected">直线</li>
<li data-tool="rect">矩形</li>
<li data-tool="arc">圆形</li>
</ul>
</div>
<div class="shape-chose">
<ul>
<li>轮廓</li>
<li>填充</li>
</ul>
</div>
</div>
<div class="toolbar-title">形状</div>
</div>
<div class="toolbar-split"></div>
<div class="toolbar-box">
<div class="toolbar-main toolbar-lineWidth-main">
<ul class="line-width-lst js-line-width-lst">
<li class="line-width-1 selected" data-lineWidth="1"><span></span></li>
<li class="line-width-2" data-lineWidth="2"><span></span></li>
<li class="line-width-3" data-lineWidth="3"><span></span></li>
<li class="line-width-4" data-lineWidth="4"><span></span></li>
<li class="line-width-5" data-lineWidth="5"><span></span></li>
</ul>
</div>
<div class="toolbar-title">线条</div>
</div>
<div class="toolbar-split"></div>
<div class="toolbar-box">
<div class="toolbar-main">
<ul class="color-lst js-color-lst">
<li class="black selected" data-color="#000"><span></span></li>
<li class="red" data-color="#f00"><span></span></li>
<li class="blue" data-color="#00f"><span></span></li>
<li class="green" data-color="#0f0"><span></span></li>
<li class="yellow" data-color="#ff0"><span></span></li>
</ul>
</div>
<div class="toolbar-title">颜色</div>
</div>
</div>
<canvas id="canvas" class="canvas" width="800" height="600"></canvas>
<script src="js/drawBoard.js"></script>
<script>
window.onload=function(){
var drawBoard=new DrawBoard();
}
</script>
</body>
</html>

style.css:

 *{
margin:;
padding:;
}
body{
background:#c9d3e2;
}
ul,li{
list-style:none;
}
.canvas{
border:1px solid #ddd;
background:#fff;
box-shadow:5px 5px 5px rgba(9,93,224,.1);
cursor:crosshair;
}
.toolbar{
padding:7px 0;
background:-webkit-linear-gradient(top,#fbfdff,#dce7f5);
border-top:1px solid #bac9db;
border-bottom:1px solid #bac9db;
box-shadow:inset 0 -1px 1px #e5f0fb,inset 0 -1px 1px #cedbeb;
overflow:hidden;
}
.toolbar-box{
float:left;
padding:0 6px;
}
.toolbar-main{
height:80px;
overflow:hidden;
}
.shape-box{
float:left;
width:150px;
height:58px;
border:1px solid #aabbd2;
background:#f3f7fc;
overflow-y:auto;
}
.shape-chose{
float:left;
margin-left:10px;
width:50px;
}
.shape-chose li{
color:#489de4;
line-height:20px;
}
.shape-lst{
overflow:hidden;
}
.shape-lst li{
float:left;
height:20px;
line-height:20px;
padding:0 10px;
color:#1a6aab;
cursor:default;
}
.shape-lst li:hover{
background:#fbe7c2;
}
.shape-lst .selected,
.shape-lst .selected:hover,
.shape-lst li:active{
background:#ffc762;
box-shadow:inset 0 0 15px rgba(60,40,3,.2);
}
.toolbar-title{
text-align:center;
color:#738399;
font-size:14px;
font-family:"Microsoft Yahei";
}
.toolbar-split{
float:left;
width:1px;
height:90px;
background:#a5b7d0;
box-shadow:0 0 0 1px #ecf1fa;
}
.color-lst{
overflow:hidden;
}
.color-lst li{
float:left;
margin:0 10px 4px 0;
padding:2px;
background:#fff;
border:1px solid #aabbd2;
}
.color-lst li span{
display:block;
width:22px;
height:22px;
}
.color-lst .black span{
background:#000;
}
.color-lst .red span{
background:#f00;
}
.color-lst .blue span{
background:#00f;
}
.color-lst .green span{
background:#0f0;
}
.color-lst .yellow span{
background:#ff0;
}
.color-lst .selected{
border-color:#ffc762;
}
.toolbar-lineWidth-main{
position:relative;
width:100px;
overflow:hidden;
}
.line-width-lst{ width:100px;
} .toolbar-lineWidth-main:hover{
overflow:visible;
} .toolbar-lineWidth-main:hover .line-width-lst{
position:absolute;
top:;
left:;
background:#fff;
}
.line-width-lst li{
width:100px;
height:20px;
line-height:20px;
}
.line-width-lst li span{
display:inline-block;
vertical-align:middle;
width:100px;
background:#000;
}
.line-width-1 span{
height:1px;
}
.line-width-2 span{
height:2px;
}
.line-width-3 span{
height:3px;
}
.line-width-4 span{
height:4px;
}
.line-width-5 span{
height:5px;
}
.line-width-lst .selected{
background:#ffc762;
}

drawBoard.js:

 function DrawBoard(){
this.oCanvas=document.getElementById("canvas");
this.oCxt=this.oCanvas.getContext("2d");
this.iCvsLeft=this.oCanvas.offsetLeft;
this.iCvsTop=this.oCanvas.offsetTop;
this.init();
} DrawBoard.prototype={
constructor: DrawBoard, /**
* 初始化各种方法
*
**/
init:function(){ this.scroll(); //设置默认的工具
this.colorChoose();
this.lineWidthChoose();
this.shapeChoose();
this.toolChoose(); //初始化工具事件
this.colorFn();
this.lineWidthFn();
this.shapeFn();
this.toolFn();
}, /**
* 滚动条滚动后重新计算鼠标绘制位置
*
**/
scroll:function(){
var _this=this;
document.onscroll=function(){
var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
var scrollLeft=document.documentElement.scrollLeft||document.body.scrollLeft;
_this.iCvsLeft=_this.oCanvas.offsetLeft - scrollLeft;
_this.iCvsTop=_this.oCanvas.offsetTop - scrollTop;
}
}, /**
* 工具选择事件
*
**/
toolFn:function(){
var _this=this;
var aTool=document.querySelector(".js-tool-lst").children;
for(var i=0;i<aTool.length;i++){
aTool[i].onclick=function(){
_this.toolChoose(this.getAttribute("data-tool"));
}
}
}, /**
* 选择工具判断
* @param sTool
**/
toolChoose:function(sTool){
if(sTool=="eraserAll"){
this.clearRectAll();
}else if(sTool=="eraser"){
this.toolSwitch("pointer",sTool);
this.clearRect();
}
}, /**
* 形状选择事件
*
**/
shapeFn:function(){
var _this=this;
var aShape=document.querySelector(".js-shape-lst").children;
for(var i=0;i<aShape.length;i++){
aShape[i].onclick=function(){
for(var j=0;j<aShape.length;j++){
aShape[j].classList.remove("selected");
}
this.classList.add("selected");
_this.shapeChoose(this.getAttribute("data-tool"));
}
}
}, /**
* 形状选择判断
* @param sShape
**/
shapeChoose:function(sShape){
this.toolSwitch("crosshair",sShape);
if(sShape=="rect"){
this.drawRect();
}else if(sShape=="arc"){
this.drawArc();
}else{
this.drawLine();
}
}, /**
* 颜色选择事件
*
**/
colorFn:function(){
var _this=this;
var aColor=document.querySelector(".js-color-lst").children;
for(var i=0;i<aColor.length;i++){
aColor[i].onclick=function(){
for(var j=0;j<aColor.length;j++){
aColor[j].classList.remove("selected");
}
this.classList.add("selected");
_this.colorChoose(this.getAttribute("data-color"));
}
}
}, /**
* 颜色选择判断
* @param sColor
**/
colorChoose:function(sColor){
this.sColor=sColor?sColor:"#000";
this.oCxt.strokeStyle=this.sColor;
}, /**
* 线条选择事件
*
**/
lineWidthFn:function(){
var _this=this;
var aLineWidth=document.querySelector(".js-line-width-lst").children;
for(var i=0;i<aLineWidth.length;i++){
aLineWidth[i].onclick=function(){
for(var j=0;j<aLineWidth.length;j++){
aLineWidth[j].classList.remove("selected");
}
this.classList.add("selected");
_this.lineWidthChoose(this.getAttribute("data-lineWidth"));
}
}
}, /**
* 线条选择判断
* @param iLineWidth
**/
lineWidthChoose:function(iLineWidth){
this.iLineWidth=iLineWidth?iLineWidth:1;
this.oCxt.lineWidth=this.iLineWidth;
}, /**
* 创建虚拟canvas--绘制矩形和圆形时,鼠标按下创建,鼠标抬起移除
*
**/
virtualCanvasCreate:function(){
var vCs=this.oCanvas.cloneNode(true);
vCs.id="virtualCanvas";
vCs.style.background="transparent";
vCs.style.boxShadow="none";
vCs.style.position="absolute";
vCs.style.left=this.oCanvas.offsetLeft+"px";
vCs.style.top=this.oCanvas.offsetTop+"px";
var vCxt=vCs.getContext("2d");
document.querySelector("body").appendChild(vCs);
return {
vCanvas:vCs,
vCxt:vCxt
}
}, /**
* 移除虚拟canvas
*
**/
virtualCanvasRemove:function(vCs){
document.querySelector("body").removeChild(vCs);
}, /**
* 绘制线条
*
**/
drawLine:function(){
var _this=this;
this.oCanvas.onmousedown=function(event){
var oEvent=event||window.event;
var startX=oEvent.clientX-_this.iCvsLeft;
var startY=oEvent.clientY-_this.iCvsTop;
var endX=startX;
var endY=startY; _this.oCxt.beginPath();
_this.oCxt.moveTo(startX,startY); document.onmousemove=function(event){
var oEvent=event||window.event;
endX=oEvent.clientX-_this.iCvsLeft;
endY=oEvent.clientY-_this.iCvsTop; _this.oCxt.lineTo(endX,endY);
_this.oCxt.stroke(); return false;
}
document.onmouseup=function(){
document.onmousemove=null;
document.onmouseup=null;
}
}
}, /**
* 绘制矩形
*
**/
drawRect:function(){
var _this=this;
this.oCanvas.onmousedown=function(event){
var oEvent=event||window.event;
var startX=oEvent.clientX-_this.iCvsLeft;
var startY=oEvent.clientY-_this.iCvsTop;
var endX=startX;
var endY=startY; var virtualCanvas=_this.virtualCanvasCreate();
virtualCanvas.vCxt.strokeStyle=_this.sColor;
virtualCanvas.vCxt.lineWidth=_this.iLineWidth;
var delta=0;
if(_this.iLineWidth%2==1){
delta=.5;
} document.onmousemove=function(event){
var oEvent=event||window.event;
endX=oEvent.clientX-_this.iCvsLeft;
endY=oEvent.clientY-_this.iCvsTop; virtualCanvas.vCxt.clearRect(0,0,virtualCanvas.vCanvas.width,virtualCanvas.vCanvas.height); //清除虚拟canvas
virtualCanvas.vCxt.strokeRect(startX+delta,startY+delta,endX-startX,endY-startY); //在虚拟canvas上绘制 return false;
}
document.onmouseup=function(){
if(endX-startX!=0&&endY-startY!=0){
_this.oCxt.strokeRect(startX+delta,startY+delta,endX-startX,endY-startY); //鼠标松开在真实canvas上绘制
}
_this.virtualCanvasRemove(virtualCanvas.vCanvas); document.onmousemove=null;
document.onmouseup=null;
}
}
}, /**
* 绘制圆形
*
**/
drawArc:function(){
var _this=this;
this.oCanvas.onmousedown=function(event){
var oEvent=event||window.event;
var startX=oEvent.clientX-_this.iCvsLeft;
var startY=oEvent.clientY-_this.iCvsTop;
var endX=startX;
var endY=startY;
var disX,disY,radius,coordsX,coordsY; var virtualCanvas=_this.virtualCanvasCreate();
virtualCanvas.vCxt.strokeStyle=_this.sColor;
virtualCanvas.vCxt.lineWidth=_this.iLineWidth; document.onmousemove=function(event){
var oEvent=event||window.event;
endX=oEvent.clientX-_this.iCvsLeft;
endY=oEvent.clientY-_this.iCvsTop;
disX=(endX-startX)/2;
disY=(endY-startY)/2;
radius=Math.min(Math.abs(disX),Math.abs(disY));
coordsX=disX < 0 ? -radius : radius;
coordsY=disY < 0 ? -radius : radius; virtualCanvas.vCxt.clearRect(0,0,virtualCanvas.vCanvas.width,virtualCanvas.vCanvas.height); //清除虚拟canvas
virtualCanvas.vCxt.beginPath();
virtualCanvas.vCxt.arc(startX+coordsX,startY+coordsY,radius,0,2*Math.PI,false); //在虚拟canvas上绘制
virtualCanvas.vCxt.stroke(); return false;
}
document.onmouseup=function(){
if(endX-startX!=0&&endY-startY!=0){
_this.oCxt.beginPath();
_this.oCxt.arc(startX+coordsX,startY+coordsY,radius,0,2*Math.PI,false); //鼠标松开在真实canvas上绘制
_this.oCxt.stroke();
}
_this.virtualCanvasRemove(virtualCanvas.vCanvas); document.onmousemove=null;
document.onmouseup=null;
}
}
}, /**
* 工具切换后,鼠标样式的切换
*
**/
toolSwitch:function(sCursorStyle,sTool){
this.oCanvas.style="cursor:"+sCursorStyle;
}, /**
* 清楚画布
*
**/
clearRectAll:function(){
this.oCxt.clearRect(0,0,this.oCanvas.width,this.oCanvas.height);
}
}

简易的canvas画板的更多相关文章

  1. 简易祖玛--canvas

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. QML学习笔记(二)-纯qml画图实现canvas画板-鼠标画图

    作者: 狐狸家的鱼 Github: 八至 版权声明:如需转载请获取授权和联系作者 用纯qml实现canvas画板功能,用鼠标进行画图,可以画直线,画圆,画矩形,画弧线. 由于canvas画图会有延迟和 ...

  3. canvas——画板

    注意部分: canvas的height和width不能再css中设定,应该在html中设定,否则会影响页面的分辨率. 效果图: 图1: 代码 css: #canvas{ cursor: crossha ...

  4. canvas 画板

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  5. html5 canvas画板

    点击查看演示地址 <!DOCTYPE HTML> <html> <title>HTML5-CanvasDrawDemo</title> <meta ...

  6. html5 canvas 画板

    <!doctype html> <head> <meta http-equiv="Content-Type" content="text/h ...

  7. JS canvas 画板 撤销

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...

  8. Canvas画板

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA6QAAAGgCAIAAAAy0z21AAAgAElEQVR4nO3dfYwkZ30n8JqZfcNex8

  9. canvas画板基础应用的学习

    canvas是html5中的绘图容器,我们可以通过javascript的控制来进行图形的绘制,绘制对象可以是路径.盒.圆.字符等,同时,你也可以通过js给画布添加图像,下面来介绍canvas的各种基本 ...

随机推荐

  1. JSP知识汇总

    JSP知识汇总 一.简介 > HTML - HTML擅长显示一个静态的网页,但是不能调用Java程序. > Servlet - Servlet擅长调用Java程序和后台进行交互,但是它不擅 ...

  2. 云链接 接口不允许 情况 解决方法 mysql Host is not allowed to connect to this MySQL server解决方法

    在装有MySQL的机器上登录MySQL mysql -u root -p密码 执行use mysql; 执行update user set host = '%' where user = 'root' ...

  3. D09——C语言基础学PYTHON

    C语言基础学习PYTHON——基础学习D09 20180903内容纲要: 线程.进程 1.paramiko 2.线程.进程初识 3.多线程 (1)线程的调用方式 (2)join (3)线程锁.递归锁. ...

  4. .NET源码Stack<T>和Queue<T>的实现

    这阵子在重温数据结构的时候,顺便用ILSpy看了一些.NET类库的实现,发现一些基本的数据结构的实现方法也是挺有意思的,所以这里拿出来跟大家分享一下.这篇文章讨论的是Stack和Queue的泛型实现. ...

  5. mapreduce基本原理

    场景: 一个大小为100T的文件,统计单词"ERROR"和"INFO"的个数 普通做法 是不是效率太低了? 换个方式 说明: 把100T文件分成100份,一台机 ...

  6. ASP.NET:EntityFramework实现Session

    ASP.NET默认的InProc模式的Session既浪费内存又在网站重启时存在数据丢失问题,SQLServer模式的Session只支持SQL Server又需要命令行配置.使用EntityFram ...

  7. 【数组】Search a 2D Matrix

    题目: Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the f ...

  8. C/C++练习题(二)

    1.下面这些指针分别代表什么? float(**p1)[10]; double*(*p2)[10]; double(*p3[10])(); int*((*p4)[10]); long(**p5)(in ...

  9. 使用python遍历文件夹取出特定的字符串

    # -*- coding: utf-8 -* import re import os # 需要处理的文件夹路径(绝对路径) path = u"/Users/a140/Downloads/te ...

  10. InterView之PHP

    PHP HTTP Keep-Alive的作用 作用 Keep-Alive:使客户端到服务器端的连接持续有效,当出现对服务器的后继请求时,Keep-Alive功能避免了建立或者重新建立连接.Web服务器 ...