该画图工具主要有以下几个功能:
- 文件菜单中主要有保存、清除、撤销三个功能
- 画图菜单中主要有线条、圆形、矩形三个功能
- 颜色菜单
- 边框菜单中主要有3个线条
- 类型菜单中主要有实心和空心
- 编辑件菜单中主要有擦除、选择2个功能
先看下效果
HTML部分
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<link rel="stylesheet" href="css/canvas.css">
<script src="js/jquery-1.11.2.js"></script>
<script src="js/shapes.js"></script>
<script>
window.onload=function (){
var box=document.getElementsByClassName("canvas")[0];
var canvas=document.getElementsByTagName("canvas")[0];
canvas.width=box.offsetWidth;
canvas.height=box.offsetHeight;
var cobj=canvas.getContext("2d");
/*
cobj.putImageData(data,100,100)
*/
var files=document.getElementsByClassName("file");
for (var i = 0; i < files.length; i++) {
files[i].onmouseover=function (){
var son=this.getElementsByClassName("son")[0];
son.style.display="block";
}
files[i].onmouseout=function (){
var son=this.getElementsByClassName("son")[0];
son.style.display="none";
}
};
var lis=document.getElementsByClassName("menu")[0].getElementsByTagName("li");
var color=document.getElementsByTagName("input")[0];
var attrObj={};
//图形菜单
var shape=document.getElementsByClassName("shape")[0];
var shapeMenu=shape.getElementsByTagName("li");
for (var i = 0; i < shapeMenu.length; i++) {
shapeMenu[i].onclick=function (){
this.parentNode.style.display="none";
drag(canvas,cobj,this.getAttribute("data-role"),attrObj)
}
};
//文件菜单
var fileObj=document.getElementsByClassName("files")[0];
var fileMenu=fileObj.getElementsByTagName("li");
for (var i = 0; i < fileMenu.length; i++) {
fileMenu[i].onclick=function (){
this.parentNode.style.display="none";
var attrVal=this.getAttribute("data-role");
if(attrVal=="save"){
var url=canvas.toDataURL("image/png");
var str=url.replace("image/png","image/octet-stream");
location.href=str;
}else if(attrVal=="clear"){
cobj.clearRect(0,0,canvas.width,canvas.height);
arr=[];
}else if(attrVal=="back"){
if(arr.length==0){
alert("顶层");
return;
}
cobj.clearRect(0,0,canvas.width,canvas.height);
arr.pop();
for (var i = 0; i < arr.length; i++) {
arr[i][arr[i].style]()
};
}
}
};
//color菜单
var colorObj=document.getElementsByClassName("color")[0];
var colorMenu=colorObj.getElementsByTagName("input")[0];
attrObj.strokeColor=colorMenu.value;
attrObj.fillColor=colorMenu.value;
colorMenu.onchange=function (){
colorObj.style.display="none";
attrObj.strokeColor=this.value;
attrObj.fillColor=this.value;
}
//边框菜单
var borderObj=document.getElementsByClassName("border")[0];
var borderMenu=borderObj.getElementsByTagName("li");
for (var i = 0; i < borderMenu.length; i++) {
borderMenu[i].onclick=function (){
this.parentNode.style.display="none";
if(this.getAttribute("data-role")=="one"){
attrObj.strokeW=1;
}
if(this.getAttribute("data-role")=="two"){
attrObj.strokeW=3;
}
if(this.getAttribute("data-role")=="three"){
attrObj.strokeW=5;
}
}
};
//绘制类型
var lxObj=document.getElementsByClassName("leixing")[0];
var lxMenu=lxObj.getElementsByTagName("li");
for (var i = 0; i < lxMenu.length; i++) {
lxMenu[i].onclick=function (){
this.parentNode.style.display="none";
var attrName=this.getAttribute("data-role")
if(attrName=="stroke"){
attrObj.type="stroke";
}else if(attrName=="fill"){
attrObj.type="fill";
}
}
};
//编辑菜单
var editObj=document.getElementsByClassName("edit")[0];
var editMenu=editObj.getElementsByTagName("li");
for (var i = 0; i < editMenu.length; i++) {
editMenu[i].onclick=function (){
this.parentNode.style.display="none";
var attrVal=this.getAttribute("data-role");
if(attrVal=="die"){
die(canvas,cobj)
}else if(attrVal=="select"){
}
}
};
//----隐藏按钮功能
var hongyuan=document.getElementsByClassName("hongyuan")[0];
var menus=document.getElementsByClassName("menu")[0];
hongyuan.onclick=function(){
box.style.cssText="width:75px;height:30px;left:45%;top:90%;";
menus.style.overflow="hidden";
}
//----显示放大按钮功能
var huangyuan=document.getElementsByClassName("huangyuan")[0];
var clintw=parseInt(document.documentElement.clientWidth);
huangyuan.onclick=function(){
var boxw=parseInt(box.offsetWidth);
//alert(clintw);
//alert(boxw);
if(boxw<(clintw*0.5)){
menus.style.overflow="visible";
box.style.cssText="width:70%;height:80%;left:15%;top:5%";
} else if((boxw>(clintw*0.4))&&(boxw<(clintw*0.6))){
box.style.cssText="width:70%;height:80%;left:15%;top:5%";
}else if(boxw>(clintw*0.6)){
box.style.cssText="width:50%;height:60%;left:25%;top:5%";
};
}
//----关闭按钮功能
var lvyuan=document.getElementsByClassName("lvyuan")[0];
lvyuan.onclick=function(){
box.style.cssText="width:0;height:0;display:none;"
}
}
</script>
</head>
<body>
<div class="canvas">
<div class="menu">
<div class="yuandian">
<div class="hongyuan">~</div>
<div class="huangyuan">口</div>
<div class="lvyuan">X</div>
</div>
<!--文件-->
<div class="file files">
文件
<ul class="son ">
<li data-role="save">保存</li>
<li data-role="clear">清除</li>
<li data-role="back">撤销</li>
</ul>
</div>
<!--画图-->
<div class="file">
画图
<ul class="son shape">
<li data-role="line">线条</li>
<li data-role="circle">圆形</li>
<li data-role="rect">矩形</li>
</ul>
</div>
<!--颜色-->
<div class="file">
颜色
<ul data-role="color" class="son color">
<li><input type="color" name="color" value="#ffffff"></li>
</ul>
</div>
<!--边框宽度-->
<div class="file">
边框
<ul class="son border">
<li data-role="one" ></li>
<li data-role="two" ></li>
<li data-role="three" ></li>
</ul>
</div>
<!--类型-->
<div class="file">
类型
<ul class="son leixing">
<li data-role="stroke"></li>
<li data-role="fill"></li>
</ul>
</div>
<!--编辑-->
<div class="file">
编辑
<ul class="son edit">
<li data-role="die">擦除</li>
<li data-role="select">选择</li>
</ul>
</div>
</div>
<canvas width=500 height=500>
</canvas>
</div>
</body>
</html>
样式css
body{
padding:0;margin:0;
background:url("../img/bg1.jpg") no-repeat 0 0;
}
ul,li{
list-style:none;padding:0;margin:0;
}
.canvas{
width:70%;height:80%;border:1px solid #aaa;
margin:2% auto;border-radius: 10px;overflow:hidden;
box-shadow: 0 0 20px #000;background:#313131;
position:fixed;left:15%;top:5%;
transition:all 0.5s ease;
}
.yuandian{float:left;width:100px;height:100%;
font-family: "微软雅黑";font-size: 10px;
}
.hongyuan{
width: 15px;height:15px;border-radius: 50%;background: #F5544D;
float:left;margin:7px 5px;text-align:center;line-height:15px;
cursor: pointer;
}
.huangyuan{
width: 15px;height:15px;border-radius: 50%;background: #F0D765;
float:left;margin:7px 5px;text-align:center;line-height:15px;
cursor: pointer;
}
.lvyuan{
width: 15px;height:15px;border-radius: 50%;background: #97CD75;
float:left;margin:7px 5px;text-align:center;line-height:15px;
cursor: pointer;
}
.menu{
width:100%;height:30px;border-bottom: 1px solid #575757;text-align: center;
background:#282828;font-size: 16px;color:#fff;font-weight: 100;
overflow:visible;
}
.menu .file{
float:left;width:10%;height:100%;margin:0 10px;line-height:30px;
cursor:pointer;position: relative;z-index:3;
}
.file .son{
width:100%;height:auto;display:none;padding:10px 0;
background:#282828;box-shadow: 0 0 20px #000;
}
.file .son li:hover{
background:#1e4157;opacity: 0.8;
}
.border li{
width:80%;height:10px;margin:10px auto;
}
.border li[data-role="one"]{
height:2px;background:#fff;border-radius:5px;
}
.border li[data-role="two"]{
height:3px;background:#fff;border-radius:5px;
}
.border li[data-role="three"]{
height:5px;background:#fff;border-radius:5px;
}
canvas{
background:#313131;display:block;position:relative;
}
.leixing li[data-role="stroke"]{
width:30px;height:30px;margin:10px auto;
border:1px solid #fff;
border-radius: 5px;
}
.leixing li[data-role="fill"]{
width:32px;height:32px;
margin:10px auto;background:#fff;border-radius: 5px;
}
shapes.js
function shapes(cobj,type,typeObj){
this.cobj=cobj;
this.type=type||"stroke";
if(typeof typeObj=="object"){
this.strokeColor=typeObj.strokeColor||"#fff";
this.fillColor=typeObj.fillColor||"#fff";
this.strokeW=typeObj.strokeW||1;
}
}
shapes.prototype={
rect:function (x,y,x1,y1){
this.x=x||this.x;
this.y=y||this.y;
this.x1=x1||this.x1;
this.y1=y1||this.y1;
this.cobj.strokeStyle=this.strokeColor;
this.cobj.fillStyle=this.fillColor;
this.cobj.lineWidth=this.strokeW;
this.cobj[this.type+"Rect"](this.x,this.y,this.x1-this.x,this.y1-this.y);
this.style="rect";
},
line:function (x,y,x1,y1){
this.x=x||this.x;
this.y=y||this.y;
this.x1=x1||this.x1;
this.y1=y1||this.y1;
this.cobj.strokeStyle=this.strokeColor;
this.cobj.fillStyle=this.fillColor;
this.cobj.lineWidth=this.strokeW;
this.cobj.beginPath();
this.cobj.moveTo(this.x,this.y);
this.cobj.lineTo(this.x1,this.y1);
this.cobj.stroke();
this.style="line";
},
circle:function (x,y,x1,y1){
this.x=x||this.x;
this.y=y||this.y;
this.x1=x1||this.x1;
this.y1=y1||this.y1;
var ox=this.x;
var oy=this.y;
var r=Math.sqrt((this.x1-this.x)*(this.x1-this.x)+(this.y1-this.y)*(this.y1-this.y))
var startA=0;
var endA=2*Math.PI;
this.cobj.strokeStyle=this.strokeColor;
this.cobj.fillStyle=this.fillColor;
this.cobj.lineWidth=this.strokeW;
this.cobj.beginPath();
this.cobj.arc(ox,oy,r,startA,endA);
this.cobj[this.type]();
this.style="circle";
}
}
var arr=[];
function drag(canvas,cobj,type,attrobj){
canvas.onmousedown=function (e){
var ox,oy,mx,my;
ox=e.layerX;
oy=e.layerY;
var shapetype=attrobj.type
var obj=new shapes(cobj,shapetype,attrobj);
canvas.onmousemove=function (e){
cobj.clearRect(0,0,canvas.width,canvas.height);
mx=e.layerX;
my=e.layerY;
obj[type](ox,oy,mx,my);
for (var i = 0; i < arr.length; i++) {
arr[i][arr[i].style]()
};
}
document.onmouseup=function (){
document.onmouseup=null;
canvas.onmousemove=null;
arr.push(obj);
}
}
}
function die(canvas,cobj,xiangpi){
canvas.onmousedown=function (e){
var ox,oy,mx,my;
ox=e.layerX;
oy=e.layerY;
canvas.onmousemove=function (e){
mx=e.layerX;
my=e.layerY;
var data=cobj.getImageData(mx-5,my-5,10,10)
for (var i = 0; i < data.width*data.height*4; i++) {
data.data[i]=0;
};
cobj.putImageData(data,mx-5,my-5)
}
document.onmouseup=function (){
document.onmouseup=null;
canvas.onmousemove=null;
}
}
}