咔叽游戏

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 429|回复: 0

[其它] 基于canvas剪辑区域功能实现橡皮擦效果

[复制链接]
  • TA的每日心情
    无聊
    2019-6-2 14:11
  • 签到天数: 4 天

    [LV.2]圆转纯熟

    发表于 2020-7-3 11:54:05 | 显示全部楼层 |阅读模式
    效果如图
    基于canvas剪辑区域功能实现橡皮擦效果-1.jpg

    这是基础结构 没什么好说的

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
      <style>
      *{padding: 0;margin: 0}
      a{text-decoration: none}
      img{border: none}
      ul,ol{list-style: none}
      br{font-size: 0;line-height: 0;font-size: 0}
      canvas{border: 1px solid red;background: white}
      body{background: gray;text-align: center}
      </style>
    </head>
    <body>
        <div id='controls'>
            Stroke color: <select id='strokeStyleSelect'>
                     <option value='red'>red</option>
                     <option value='green'>green</option>
                     <option value='blue'>blue</option>
                     <option value='orange'>orange</option>
                     <option value='cornflowerblue'>cornflowerblue</option>
                     <option value='goldenrod'>goldenrod</option>
                     <option value='navy' selected>navy</option>
                     <option value='purple'>purple</option>
                     <option value='purple'>purple</option>
                   </select>
            Fill color: <select id='fillStyleSelect'>
                     <option value='rgba(255,0,0,0.5)'>semi-transparent red</option>
                     <option value='green'>green</option>
                     <option value='rgba(0,0,255,0.5)'>semi-transparent blue</option>
                     <option value='orange'>orange</option>
                     <option value='rgba(100,140,230,0.5)'>semi-transparent cornflowerblue</option>
                     <option value='goldenrod' selected>goldenrod</option>
                     <option value='navy'>navy</option>
                     <option value='purple'>purple</option>
                   </select>
            Draw <input id='drawRadio' name='drawEraserRadios' type='radio' checked/>
            Erase <input id='eraserRadio' name='drawEraserRadios' type='radio'/>
            Eraser: <select id='eraserShapeSelect'>
                    <option value='circle'>circle</option>
                    <option value='square'>square</option>
                   </select>
            Eraser width: <select id='eraserWidthSelect'>
                    <option value=25>25</option>
                    <option value=50>50</option>
                    <option value=75>75</option>
                    <option value=100>100</option>
                    <option value=125>125</option>
                    <option value=150>150</option>
                    <option value=175>175</option>
                    <option value=200>200</option>
                   </select>
           </div>
      <canvas id="canvas" width="950" height="600"></canvas>
    </body>
    </html>
    <script src="./js/test9.js"></script>下面是重点的js

    这里有个坑要十分注意 调用clip()方法的时候,所定义的剪辑区域总是局限于期初的那个剪辑区域范围。
    简单来说 clip()方法总是在上一次的剪辑区域基础上进行操作,所以说我们要把clip()方法放在save()和restore()方法中

    var canvas = document.getElementById('canvas'),
    context = canvas.getContext('2d'),
    strokeStyleSelect = document.getElementById('strokeStyleSelect'),  //画图的描边颜色
    fillStyleSelect = document.getElementById('fillStyleSelect'),    //画图填充颜色
    drawRadio = document.getElementById('drawRadio'),          //画图按钮
    eraserRadio = document.getElementById('eraserRadio'),       //橡皮擦按钮
    eraserShapeSelect = document.getElementById('eraserShapeSelect'), //橡皮擦形状
    eraserWidthSelect = document.getElementById('eraserWidthSelect'), //橡皮擦宽度
    ERASER_LINE_WIDTH = 1,
    drawingSurfaceImageData,
    lastX,
    lastY,
    mousedown = {},
    rubberbandRect = {},
    dragging = false
    function windowToCanvas(x,y){ //这个函数的作用是捕捉鼠标点在canvas上的坐标
      var bbox=canvas.getBoundingClientRect()
      return {
        x:x-bbox.left,
        y:y-bbox.top
      }
    }
    function saveDrawingSurface(){  //这个函数的作用是初始化读取画布信息并储存起来
      drawingSurfaceImageData=context.getImageData(0,0,canvas.width,canvas.height)
    }
    function restoreDrawingSurface(){ //这个函数的作用是读取画布信息
      context.putImageData(drawingSurfaceImageData,0,0)
    }
    function drawGrid(){ //这个函数的作用是填充进橡皮擦的剪辑区域
      context.save()
      context.fillStyle="#fff"
      context.fillRect(0,0,canvas.width,canvas.height)
      context.restore()
    }
    function drawrubber(x,y){
      context.beginPath()
      context.arc(x,y,eraserWidthSelect.value,0,Math.PI*2,false)
      context.clip()
    }
    function drawCri(x,y){
      var x_width=Math.abs(x-mousedown.x)
      var y_width=Math.abs(y-mousedown.y)
      var radius=Math.sqrt(x_width*x_width+y_width*y_width)
    context.save()
      context.beginPath()
      context.fillStyle=fillStyleSelect.value;
      context.arc(mousedown.x,mousedown.y,radius,0,Math.PI*2,false)
      context.fill()
    context.restore()
    }
    canvas.onmousedown=function(e){
      var loc=windowToCanvas(e.clientX,e.clientY)
      mousedown.x=loc.x
      mousedown.y=loc.y
      lastX=loc.x
      lastY=loc.y
      saveDrawingSurface()
      dragging=true
    }
    canvas.onmousemove=function(e){
      if(dragging){
        var loc=windowToCanvas(e.clientX,e.clientY)
        if(drawRadio.checked){ //如果是画图状态
          //
          restoreDrawingSurface()
          drawCri(loc.x,loc.y)
        }else{ //如果是橡皮擦状态
          context.save()
          drawrubber(loc.x,loc.y)
          drawGrid()
          context.restore()
        }
      }
    }
    canvas.onmouseup=function(e){
      dragging=false;
      var loc=windowToCanvas(e.clientX,e.clientY)
      if(drawRadio.checked){
      lastX=loc.x;
      lastY=loc.y;
      restoreDrawingSurface()
      drawCri(lastX,lastY)
      }else{
      context.save()
      drawrubber(loc.x,loc.y)
      drawGrid()
      context.restore()
      }
    }总结
    以上所述是小编给大家介绍的基于canvas剪辑区域功能实现橡皮擦效果,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

    原文地址:https://www.jb51.net/article/136615.htm

    QQ|免责声明|小黑屋|手机版|Archiver|咔叽游戏

    GMT+8, 2024-3-1 08:49

    Powered by Discuz! X3.4

    © 2001-2023 Discuz! Team.

    快速回复 返回顶部 返回列表