用Canvas模拟苹果画图工具

该画图工具主要有以下几个功能:
- 文件菜单中主要有保存、清除、撤销三个功能
- 画图菜单中主要有线条、圆形、矩形三个功能
- 颜色菜单
- 边框菜单中主要有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;


    }
  }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值