没事仿照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. 线程TLAB局部缓存区域(Thread Local Allocation Buffer)

    TLAB(Thread Local Allocation Buffer) 1,堆是JVM中所有线程共享的,因此在其上进行对象内存的分配均需要进行加锁,这也导致了new对象的开销是比较大的 2,Sun ...

  2. Python小白学习之路(十八)—【内置函数三】

    一.对象操作 help() 功能:返回目标对象的帮助信息 举例: print(help(input)) #执行结果 Help on built-in function input in module ...

  3. iOS根据图片url获取尺寸

    可以在UIImage的分类中加入下面的代码,并且引入系统的ImageIO.framework /** 根据图片的url获取尺寸 @param URL url @return CGSize */ + ( ...

  4. input验证码框,输入非数字或非12位时,红框提示;每4位加一个空格

    以下代码:input验证码框,输入非数字或非12位时,红框提示;每4位加一个空格 //input验证码框,输入非数字或非12位时,红框提示;每3位加一个空格 $(".text"). ...

  5. 使用图片预加载,解决断网后无法从后台获取提示网络异常的logo图片的问题

    项目中有需求,断网后,显示小提示窗,里面包含网络异常提示语和异常小logo图片. 在实际操作时,遇到,断网后,无法从后台获取异常小logo图片. 我是才用图片预加载的方法解决这个问题的,解决方法如下: ...

  6. h5移动端聊天室|仿微信界面聊天室|h5多人聊天室

    今年的FIFA世界杯甚是精彩,最近兴致高涨就利用HTML5开发了一个手机端仿微信界面聊天室,该h5聊天室采用750px全新伸缩flex布局,以及使用rem响应式配合fontsize.js,页面弹窗则是 ...

  7. 导出数据库数据成txt格式

    set verify off; set colsep ‘分隔符’; set echo off; set feedback off; set heading off; set pagesize 0; s ...

  8. activity和Task 有关的 Intent启动方式结合intent.setFlags()

      通过设置Intent对象的标记,来改变当前任务堆栈中既存的Activity的顺序: FLAG_ACTIVITY_NEW_TASK----简而言之,跳转到的activity根据情况,可能压在一个新建 ...

  9. wildfly8+jpa EntityBean 简单入门

    1)首先配置wildfly的数据源,我使用的是mysql数据库 1.jboss7开始,jboss使用模块化设计所以数据源的配置也是遵循模块化. 打开wildfly的安装目录进入modules\syst ...

  10. 自己动手实现一个WEB服务器

    自己动手实现一个 Web Server 项目背景 最近在重温WEB服务器的相关机制和原理,为了方便记忆和理解,就尝试自己用Java写一个简化的WEB SERVER的实现,功能简单,简化了常规服务器的大 ...