最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • canvas实现你画我猜(入门级别)

    正文概述 掘金(用户1682972487087)   2021-08-07   809

    canvas实现你画我猜(入门级别)

    初学canvas做的一个小功能,大佬勿喷

    之前一直没有去了解canvas 最近玩steam你画我猜感觉很有意思 就打算自己实现一个单机版的

    成果图:

    canvas实现你画我猜(入门级别) 预备工作: vs code,及几张图片

    canvas实现你画我猜(入门级别)

    canvas实现你画我猜(入门级别)

    因为考虑到体积问题没有用上jquery 先说一下这次使用到的基本的几个canvas方法

    moveTo绘制心线条起点

    lineTo绘制线条的末尾

    stroke绘制线条结束

    clearRect 清除一个正方形出来

    fillRect 填充一个正方形

    beginPath 重新绘制一条新的线条

    beginPath这个方法比较关键 同一条线条的情况下换颜色,所有线条都变颜色了,回放自己画图时候也会出问题

    canvas中文文档:www.canvasapi.cn/CanvasRende…

    Hmtl部分

    
          <img src="./huabu.jpg"  id="scream" class="img" >
          <canvas class="canvas"  id="canvas" width="800" height="800"></canvas>
        </div>
        <div class="function">
          <div></div>
          <div>
            <button onclick="start()">清除绘制</button>
          </div>
          <div>
            <button onclick="reset()">回放绘制</button>
          </div>
          <div>
            <input type="radio" name="mode" id="canvasMode" onChange="modeChange(1)"> <label for="canvasMode">画布模式</label>
            <input type="radio" name="mode" id="backgroundMode" onChange="modeChange(2)"> <label for="backgroundMode">背景颜色模式</label>
          </div>
          <div class="button">
            <input type="color" id="color"> 背景颜色
          </div>
          <div class="button">
            <input type="color" id="fontColor"> 画笔颜色
          </div>
          <div class="button lineWidth">
            <input type="range" value="1" min="1" id="fontWidth"><span style="margin-left:12px;width:95px">画笔粗细:</span>
            <div class="widthPercentage" id="percentage">
            </div>
            <div  class="button">
              <span id="lineNum">1</span>
            </div>
          </div>
          <div class="button lineWidth">
            <input type="range" value="15" min="1" id="rubberWidth"><span style="margin-left:12px;width:95px">橡皮大小:</span>
            <div  class="button">
              <span id="rubberNum">15</span>
            </div>
          </div>
          <div>
          <button onclick="eraserClick()" id='eraser'>橡皮擦 </button>
          </div>
        </div>
      </div>
    

    css部分

      body {
        margin: 0;
      }
      .canvasBox {
        display: flex;
      }
      button,.button {
        margin: 12px;
      }
      .function {
        margin: auto 0;
      }
      .lineWidth {
        position: relative;
        display: flex;
        align-items: center;
      }
      .widthPercentage{
        position: absolute;
        top: 34px;
        left: 30%;
        height: 20px;
        border: 1px dashed #aaa;
        display: none;
        padding: 4px;
      }
      .img {
        top: 0;
        left: 0;
        width: 800px;
        height: 800px;
        position: absolute;
        pointer-events: none;
        z-index: -1;
      }
      .imgbox{
        width: auto;
        position: relative;
      }
      .canvas {
        cursor: url('./brush.ico'), auto;
        opacity: 1;
      }
    </style>
    

    js部分

      let record = []
      let bkgColor = document.getElementById('color')
      let eraser = document.getElementById('eraser')
      let img = document.getElementById("scream");
      let fontWidth = document.getElementById('fontWidth')
      let rubberWidth = document.getElementById('rubberWidth')
      let lineNum = document.getElementById('lineNum')
      let rubberNum = document.getElementById('rubberNum')
      let fontColor = document.getElementById('fontColor')
      let canvas = document.getElementById('canvas')
      let percentage = document.getElementById('percentage')
      let  body = document.document || document.body
      let clientX,clientY,c,lineWidth,rubberSize,eraserFlag,mode=1,color
      let flag,fColor='#000'
      c = canvas.getContext('2d')
      init()
      modeChange = function(e) {
        mode = e
        init({color})
        resetHui(false)
      }
      eraser.onclick = function() { // 橡皮擦点击事件
        eraserFlag = !eraserFlag
        if(eraserFlag) {
          eraser.innerText='画笔'
          canvas.style.cursor = "url('./xp1.ico'), auto"
        } else {
          eraser.innerText='橡皮擦'
          canvas.style.cursor = "url('./brush.ico'), auto"
          c.strokeStyle = fColor
        }
        c.beginPath();
      }
      bkgColor.onchange = function(e) { // 背景颜色
        color = e.target.value
        init({color})
        resetHui(false)
      }
      fontColor.onchange = function(e) { // 画笔颜色
        fColor = e.target.value
        c.beginPath();
        c.strokeStyle = fColor
      }
      fontWidth.onchange = function(e) { // 画笔粗细 选择之后
        lineWidth = e.target.value
        c.beginPath();
        c.lineWidth = lineWidth
      }
      rubberWidth.onmousemove = function(e) { // 橡皮大小 移动滑块
        rubberSize = e.target.value
        percentage.innerText = rubberSize+' %'
        rubberNum.innerText = rubberSize
      }
      fontWidth.onmousemove = function(e) { // 画笔粗细 移动滑块
        lineWidth = e.target.value
        percentage.style.display = 'block'
        percentage.innerText = lineWidth+' %'
        lineNum.innerText = lineWidth
      }
      fontWidth.onmouseleave = function(e) { // 画笔粗细 移除滑块
        lineWidth = e.target.value
        percentage.style.display = 'none'
      }
      canvas.onmouseenter = function(e) {
        if(!eraserFlag) return
        // canvas.style.cursor = 'none'
      }
      canvas.onmousedown = function(e) { // 鼠标按下开始画图
        flag = true
        if(!eraserFlag) {
          c.moveTo(e.clientX,e.clientY)
        }
        // console.log(e.clientX,e.clientY,'开始');
        canvas.onmousemove = function(event) { //鼠标按下移动画图
          if(!flag) return
          clientX = event.clientX;
          clientY = event.clientY
          if(!eraserFlag) {
            c.lineTo(clientX,clientY)
            c.stroke();
            // console.log(clientX,clientY,'结束');
            // console.log(e.clientX,e.clientY,clientX, clientY, '重回');
            record.push({
              start: [e.clientX,e.clientY],
              end: [clientX, clientY],
              strokeStyle: fColor,
              lineWidth: lineWidth
            })
          }else {
            if(mode===1) {
              c.clearRect(clientX, clientY, rubberSize, rubberSize);
            } else {
              c.strokeStyle = color
              c.fillRect(clientX,clientY,rubberSize,rubberSize);
            }
            
          }
        }
      }
      canvas.onmouseup = function() { // 鼠标松开 结束画图
        flag = false
        c.stroke();
        // console.log(record);
      }
      function start(){
        record = []
        init()
        lineNum.innerText = 0
        fontWidth.value = 0
      }
      function reset(){
        init()
        resetHui()
      }
      async function resetHui(needDelay = true) {
        let old = []
        let strokeStyle,setLineWidth
        for(let i=0; i<record.length;i++) {
          let item = record[i]
          if(!old || (old[0] !== item.start[0] && old[1] !== item.start[1])) {
            old[0] = item.start[0]
            old[1] = item.start[1]
            c.beginPath();
            if(!strokeStyle || (strokeStyle !== item.strokeStyle)){
              strokeStyle = item.strokeStyle
              c.strokeStyle = strokeStyle
            }
            if(!setLineWidth || (setLineWidth !== item.lineWidth)) {
              setLineWidth = item.lineWidth
              c.lineWidth = setLineWidth
            }
            c.moveTo(item.start[0],item.start[1])
          }
          c.lineTo(item.end[0],item.end[1])
          c.stroke();
          needDelay && await delay()
        }
      }
      function delay(time = 10) {
        return new Promise((res,rej)=>{
          setTimeout(function(){
            res('随便什么数据');
          }, time);
        })
      }
      function init({color='#fff'}={}) {
        canvas.width = canvas.width
        c.strokeStyle = fontColor // 线条颜色
        c.rect(0,0,800,800); // 矩形
        c.stroke(); // 线条结束
        if (mode===1) { // 模式1为画布模式
          c.fillStyle = 'rgba(255, 255, 255, 0)'
        } else {
          c.fillStyle = color; // 填充颜色 背景色
        }
        c.fillRect(0,0,800,800); // 填充矩形
        c.stroke(); // 线条结束
        c.strokeStyle = '#000' // 线条颜色
        c.lineWidth = 1 // 线条粗细
        c.lineCap = 'square'; // 线条头部形状 扁平 凸起 凹进
      }
    </script>
    

    第一步: 实现你画我猜画布功能

    很简单通过canvas标签和img图片放在div里,img图片和父元素position的定位,然后canvas填充背景色为透明,这样我们就可以获得一个画布背景图了

    具体的步骤:

    canvas实现你画我猜(入门级别)

    (虽然图片在canvas下方但是为了以防万一我还是加了pointer-events: none;防止图片被点击)

    canvas实现你画我猜(入门级别)

    let canvas = document.getElementById('canvas')
      c = canvas.getContext('2d')  // 创建一个2d的canvas画布
      canvas.width = canvas.width // 重新赋值一遍宽度 可以刷新画布
      c.strokeStyle='#000' // 线条颜色
      c.rect(0,0,800,800); // 绘制矩形
      c.fillStyle = 'rgba(255, 255, 255, 0)' // 填充颜色为透明
      c.fillRect(0,0,800,800); // 填充颜色大小
      c.stroke(); // 线条结束
    

    这样就可以获得一个这样的图片了,现在我们canvas的线条就可以在这个背景上为所欲为了

    canvas实现你画我猜(入门级别)

    第二步:开始画画

    给canvas加上鼠标点击时候的事件并且再触发鼠标移动的事件,并且通过一个数组记录鼠标的坐标信息(record),通过一个状态记录鼠标是否松开(flag),如果松开了鼠标移动事件就不再执行,通过一个状态来控制是橡皮擦还是画笔(eraserFlag),通过一个状态来控制展示的是背景图还是背景颜色(mode)

    record的目的 是回放我们刚刚画的图感觉就像动画一样重新画图

    flag的目的 实现点击并且移动才能画画 松开的时候清除

    eraserFlag目的 实现橡皮擦和画笔的切换

    canvas实现你画我猜(入门级别)

    canvas实现你画我猜(入门级别)

    回放画图过程

    canvas实现你画我猜(入门级别)


    起源地下载网 » canvas实现你画我猜(入门级别)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元