zoukankan      html  css  js  c++  java
  • 用canvas画一个的小画板(PC端移动端都能用)

    前言

    本篇的内容主要包括:

    1. canvas标签简介
    2. 画板的功能简介
    3. 画板的JS部分
      (包括:1、获取画布 2、使画板全屏幕显示且自适应 3、如何绘制直线 4、绘画时的三种状态(鼠标点击、移动、离开)5、画笔功能(画笔颜色、画笔粗细) 6、橡皮擦功能 7、一键清除功能 8、一键下载功能)
    4. 画板的HTML部分
    5. 画板的CSS部分

    正文

    1  canvas标签简介

    <canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形。例如,它可以用于绘制图形,制作照片,创建动画,甚至可以进行实时视频处理或渲染。
    
    <canvas> 看起来和 <img> 元素很相像,唯一的不同就是它并没有 src 和 alt 属性。实际上,<canvas> 标签只有两个属性—— width和height。这些都是可选的,并且同样利用 DOM properties 来设置。当没有设置宽度和高度的时候,canvas会初始化宽度为300像素和高度为150像素。该元素可以使用CSS来定义大小,但在绘制时图像会伸缩以适应它的框架尺寸:如果CSS的尺寸与初始画布的比例不一致,它会出现扭曲。
    
    //注意:canvas不能使用CSS来设置宽高

    2  画板的功能简介

    • 画板的主要功能有:1  画笔功能(多种画笔颜色、画笔粗细),2  橡皮擦功能 ,3  一键清除功能 , 4 一键保存功能。
    • 画板效果如下图所示,

     

    3  画板的JS部分

    1. 获取画布

      //1  获取画布
      var canvasname=document.getElementById("canvas");
      if(canvasname.getContext){
          var context=canvasname.getContext('2d');
      }
    2. 使画板全屏幕显示且自适应

      //2  全屏幕画布,ps:最好不要用css,会出bug 
      setCanvasSize();
      window.onresize=function(){
          setCanvasSize();
      }; //这句的用处是在用户拖动屏幕的时候,宽度会重新全屏幕。但是会有刚刚画的东西丢失的bug
    3. 绘画时的三种状态(鼠标点击、移动、离开)

      //3  特性检测,检测设备是否可触碰。
      lisenToUser(canvas)
      function lisenToUser(canvas){
          //使用document.body.ontouchstart!==undefined或者in方法ontouchstart in document.body都行。
          if(document.body.ontouchstart!==undefined){
              lisenToTouch(canvas);
          }else{
              lisenToMouse(canvas);
          }
      }
      
      //监听触摸事件的函数
      function lisenToTouch(canvas){
          var lastPoint={x:undefined,y:undefined};
          var usingBrush=false;
          canvas.ontouchstart=function(aaa){
            console.log(aaa)  //打印出touchevent
            var x=aaa.touches[0].clientX;     //因为clientX/clientY的在Touch event的touchs下面的0数组中,所以。。。
            var y=aaa.touches[0].clientY;
            console.log(x,y)   //打印出坐标
            if(usingEraser){
                context.clearRect(x-10,y-10,20,20)     //橡皮擦功能
            }else{
           usingBrush=true;
              lastPoint={"x":x,"y":y};
              //drawCircle(x,y,3);
          }
          };
          canvas.ontouchmove=function(aaa){
            var x=aaa.touches[0].clientX;
            var y=aaa.touches[0].clientY;
            if(usingEraser){
                context.clearRect(x-10,y-10,20,20)
            }else{
              if (usingBrush){
              var newPoint={"x":x,"y":y};
              //drawCircle(x,y,3);
              drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y);
              lastPoint=newPoint;
              }
           }
          };
          canvas.ontouchup=function(){
            usingBrush=false;
            usingEraser=false;
          };
      }
      
      //监听鼠标事件的函数
      function lisenToMouse(canvas){
          var lastPoint={x:undefined,y:undefined};
          var usingBrush=false;
          canvas.onmousedown=function(aaa){
            var x=aaa.clientX;
            var y=aaa.clientY;
            if(usingEraser){
                context.clearRect(x-10,y-10,20,20)
            }else{
           usingBrush=true;
              lastPoint={"x":x,"y":y};
              //drawCircle(x,y,3);
          }
          };
          canvas.onmousemove=function(aaa){
            var x=aaa.clientX;
            var y=aaa.clientY;
            if(usingEraser){
                context.clearRect(x-10,y-10,20,20)
            }else{
              if (usingBrush){
              var newPoint={"x":x,"y":y};
              //drawCircle(x,y,3);
              drawLine(lastPoint.x,lastPoint.y,newPoint.x,newPoint.y);
              lastPoint=newPoint;
              }
           }
          };
          canvas.onmouseup=function(){
            usingBrush=false;
            usingEraser=false;
          };
      }
    4. 如何绘制直线

      //画一个直线
      function drawLine(x1,y1,x2,y2){
          context.beginPath();
          context.moveTo(x1,y1);
          context.lineTo(x2,y2);
          context.stroke();     //画直线不能用fill()
          context.closePath();
          context.lineWidth=lineWidth;  //此处将线宽赋值给一个变量时为了使为了方便设置画笔宽度
      }

      一条直线的作用是生成画笔的功能。配合鼠标/触摸的点击和移动的坐标,每次鼠标移动时保存上次的坐标并将上次的坐标和移动到的新的坐标相连接,用户在使用鼠标/手机触摸在页面上移动时会随着用户的移动形成线条。
    5. 画笔功能(画笔颜色、画笔粗细)

      //4  画笔功能
      brush.onclick=function(){
          usingEraser=false;   //如果用户在使用画笔,则关闭橡皮擦功能
      }
      //有颜色的画笔,添加几个有颜色的按钮 red.onclick=function(){ context.strokeStyle="red"; context.fillStyle="red"; } yellow.onclick=function(){ context.strokeStyle="yellow"; context.fillStyle="yellow"; } green.onclick=function(){ context.strokeStyle="green"; context.fillStyle="green"; } blue.onclick=function(){ context.strokeStyle="blue"; context.fillStyle="blue"; } //画笔的粗细 var lineWidth; thin.onclick=function(){ lineWidth=2; } thin2.onclick=function(){ lineWidth=4; } thick.onclick=function(){ lineWidth=6; } thick2.onclick=function(){ lineWidth=8; }
    6. 橡皮擦功能

      //5  橡皮擦功能
      eraser.onclick=function(){ usingEraser=true; }

      实现橡皮擦的功能:在鼠标/触摸点击和移动的时候检测用户是否在使用eraser按钮,如果在使用,使用如下语句擦除所画内容:
      context.clearRect(x-10,y-10,20,20),如用户未使用橡皮擦,则执行画笔功能。
      
      
    7. 一键清除功能

      //6  一键清除
      clear.onclick=function(){
          context.clearRect(0,0,canvas.width,canvas.height);  //清除整个画布的内容即可实现一键清除
      }
    8. 一键下载功能

      //7  一键下载
      download.onclick = function(){
          var url = canvas.toDataURL('image/png');
          var a = document.createElement('a');
          document.body.appendChild(a);
          a.href = url;
          a.download = 'my pic';
          a.target="_blank"
          a.click();
          eraser.classList.remove("activesvg")
          brush.classList.remove("activesvg")
          clear.classList.remove("activesvg")
          download.classList.add("activesvg")
      }

    4  画板的HTML部分

    <!DOCTYPE html>
    <html lang="zh-Hans">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <!--加上"user-scalable=no/"会使手机真正自适应,使页面到手机上时字体不会自动缩放。"device-width"设备宽度-->
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>myCanvas</title>
        <link rel="stylesheet" href="./style.css">
        <script src="//at.alicdn.com/t/font_650559_geuacjzbo98p8pvi.js"></script>
        
    </head>
    <body>
        <canvas id="canvas" width="300px" height="300px"></canvas>
        <!--不要用css添加宽度高度样式,不要用css添加宽度高度样式,不要用css添加宽度高度样式重要的事情说三遍-->
        <div class="actions" id="actions">
            <svg class="icon" aria-hidden="true" id="brush">
                    <use xlink:href="#icon-pen"></use>
            </svg>
            <svg class="icon" aria-hidden="true" id="eraser">
                    <use xlink:href="#icon-eraser"></use>
            </svg>
            <svg class="icon" aria-hidden="true" id="clear">
                    <use xlink:href="#icon-clear"></use>
            </svg>
            <svg class="icon" aria-hidden="true" id="download">
                    <use xlink:href="#icon-download"></use>
            </svg>
        </div>
        <div class="colors">
            <ol>
                <li id="red"></li>
                <li id="yellow"></li>
                <li id="green"></li>
                <li id="blue"></li>
            </ol>
        </div>
        <div class="sizes">
            <ol>
                <li id="thin"></li>
                <li id="thin2"></li>
                <li id="thick"></li>
                <li id="thick2"></li>
            </ol>
        </div>
        <script src="./main.js"></script>
    </body>
    </html>

    5  画板的CSS部分

        
    .icon {
         1em; height: 1em;
        vertical-align: -0.15em;
        fill: currentColor;
        overflow: hidden;
     }
     ol,li{
         list-style: none;   /*清除无序列表前面的点点*/
     }
     *{
        margin: 0;   
        padding: 0;  /*kill掉元素的外边距和内边距*/
     }
    body{
        overflow: hidden;   /*解决在手机上页面会滚动的bug*/
        position: fixed;
        top: 0;
        left: 0;
    }
    #canvas{
        background:rgb(255, 255, 255);
        display:block;
    }
    .actions{
        position: fixed;  /*使元素脱离文档流,自己重新定位*/
        top:0;
        left:0;
        padding:20px;
    
    }
    .actions svg{
         1.5em;
        height: 1.5em;
        transition: all 0.3s;
        margin: 4px;
    }
    .colors{
        position: fixed;
        top: 70px;
        left: 10px;
    }
    .colors ol li{
         20px;
        height: 20px;
        margin: 8px 6px;
        border-radius: 50%;   /*是元素变成一个圆*/
    }
    .colors ol li#red{
        background: red;
    }
    .colors ol li#yellow{
        background: yellow;
    }
    
    .colors ol li#green{
        background: green;
    }
    .colors ol li#blue{
        background: blue;
    }
    .sizes{
        position: fixed;
        top: 70px;
        right: 10px;
    }
    .sizes ol li{
        margin: 20px 6px;
    }
    .sizes ol li#thin{
        border-top: 2px solid black;
         16px;
        height: 0;
    }
    .sizes ol li#thin2{
        border-top: 4px solid black;
         16px;
        height: 0;
    }
    .sizes ol li#thick{
        border-top: 6px solid black;
         16px;
        height: 0;
    }
    .sizes ol li#thick2{
        border-top: 8px solid black;
         16px;
        height: 0;
    }

     

  • 相关阅读:
    listbox,tree定位item后显示出来
    dbgrideh导出Excel
    ---注册job 设置时间 必须在命令窗口内执行
    四舍五入函数 function MyRound2
    解决delphi7注册过期方法
    Trunc错误浮点计算处理
    BGridEh,同时也用了DBGrid。在OnDrawColmnCell事件中调用DefaultDrawColumnCell,编译时却提示Incom
    不能借助DLL的全局变量来达到两个应用程序间的数据传递,除非使用内存映像文件
    JavaScript实现换肤功能
    echarts图表隐藏之后再展示出现变形
  • 原文地址:https://www.cnblogs.com/nolaaaaa/p/8971689.html
Copyright © 2011-2022 走看看