• 实现一个绘图功能的微信小程序


    在上一篇canvas绘图的基础上做了延伸,做了一个绘图小程序。

    下面附上draw文件夹下各文件的源码:

    html文件 ----- draw.html:

    <view class="container">
      <canvas canvas-id="canvas" disable-scroll='true'
       bindtouchstart="beginStroke"
       bindtouchmove="moveStroke"
        bindtouchend="endStroke"
        style="{{canvasWidth}}rpx;height:{{canvasHeight}}rpx"
       ></canvas>
    </view>
    <view class="controller">
      <view class="colorContr">
        <block wx:for="{{colors}}">
          <button bindtap="selectColor" class="colorBtn {{curColor == item ? 'selected' : ''}}" data-value="{{item}}" style="background-color:{{item}}"></button>
        </block>
      </view>
       
      <slider bindchange='changeBold' min="1" max="20" value="5" block-size="18"/>
      <button bindtap="clearCanvas" class="clearBtn"><image src="../imgs/reset.png" mode="aspectFit"></image></button>
       <button bindtap="eraser" class="clearBtn {{isEraser ? 'selected' : ''}}"><image src="../imgs/eraser-v3.png" mode="aspectFit"></image></button>
    </view>
    <button class="saveImg" bindtap='saveImg'>保存</button>
    <text class="sucTip" hidden="{{isSuc}}">保存成功</text>
    

    css文件 ----- draw.css:

    /* pages/draw/draw.wxss */
    .container{
      604rpx;
      height:604rpx;
      overflow: hidden;
      margin:40rpx auto;
      border: 1px solid #91d487;
      padding:1rpx;
    }
    .controller{
      600rpx;
      margin:30rpx auto;
    }
    .controller slider{
      360rpx;
      float:left;
      margin:10rpx 0;
    }
    .controller .colorContr{
      overflow: hidden;
      margin-bottom:40rpx;
    }
    .controller .colorBtn{
      29px;
      height:29px;
      margin:3px;
      float:left;
      padding:0;
      border:3px solid #fff;
    }
    .controller .selected{
      border:1px solid #666;
    }
    .clearBtn{
      80rpx;
      height:60rpx;
      float:right;
      padding:0;
      margin:0 10rpx;
      line-height:60rpx;
      font-size:30rpx;
     
      background:none;
    }
    .clearBtn::after{
      border:none;
    }
    .clearBtn image{
      100%;
      height:100%;
    }
    .saveImg{
      position:fixed;
      bottom:8rpx;
      left:50%;
      margin-left:-80rpx;
      132rpx;
      height:132rpx;
      line-height:132rpx;
      font-size:34rpx;
      font-weight: bold;
      letter-spacing: 5rpx;
      background:#91d487;
      color:#ffffff;
      border-radius: 50%;
      border:0;
      box-shadow: 3px 3px 3px #aaa; 
      text-align:center;
    }
    .saveImg.button-hover{
       background:#82c078;
       color:#efefef;
    }
    .sucTip{
      /* display:block; */
      position:fixed;
      bottom:35%;
      left:50%;
      transform: translateX(-50%);
      color:#fff;
      padding:10rpx 20rpx;
      border-radius: 5px;
      background:#91d487;
    }
    

    js文件 ----- draw.js:

    Page({
    
      /**
       * 页面的初始数据
       */
      data: {
        canvasWidth:'600',
        canvasHeight: 0,
        boldVal:5,
        colors: ['black', 'pink', 'red', 'skyblue', 'greenyellow', '#00FF00', '#0000FF', '#FF00FF','#00FFFF',
          '#FFFF00', '#70DB93', '#5C3317 ', '#9F5F9F', '#B5A642', '#FF7F00','#42426F'],
        curColor:'#000000',
        isEraser:false,
        isSuc:true,
        isTap:true,
      },
    
      /**
       * 生命周期函数--监听页面加载
       */
      onLoad: function (options) {
        this.context = wx.createCanvasContext('canvas');
        this.setData({ canvasHeight: this.data.canvasWidth})
        this.isMouseDown=false
        this.lastLoc={ x: 0, y: 0 }
        this.lastTimestamp = 0;
        this.lastLineWidth = -1;
        this.drawBgColor();
      },
    
      /**
       * 生命周期函数--监听页面初次渲染完成
       */
      onReady: function () {
        // this.setData({context: });
      },
      drawBgColor(){
        this.context.save();
        this.context.setFillStyle('#ffffff');
        this.context.fillRect(0, 0, this.data.canvasWidth, this.data.canvasHeight)
        this.context.restore();
        this.context.draw({
          reserve: true
        })
      },
      changeBold:function(e){
        this.setData({boldVal: e.detail.value})
      },
      selectColor:function(e){
        this.setData({ curColor: e.currentTarget.dataset.value })
        this.setData({ isEraser: false })
      },
      beginStroke(event) {
          this.isMouseDown = true
          this.lastLoc = { x: event.touches[0].x, y: event.touches[0].y }
          this.lastTimestamp = event.timeStamp;
          this.setData({ isTap: true })
          // //draw
          this.context.arc(this.lastLoc.x, this.lastLoc.y, this.data.boldVal / 2, 0, 2 * Math.PI)
          this.context.setFillStyle(this.data.curColor);
          this.context.fill();
          wx.drawCanvas({
            canvasId: 'canvas',
            reserve: true,
            actions: this.context.getActions() // 获取绘图动作数组
          })
    
          // if (event.touches.length>1){
          //   var xMove = event.touches[1].x - event.touches[0].x;
          //   var yMove = event.touches[1].y - event.touches[0].y;
          //   this.lastDistance = Math.sqrt(xMove * xMove + yMove * yMove);
    
          // }
        
      },
    
      endStroke(event) {
        // console.log(this.data.isTap)
        // if (this.data.isTap){
        //   this.lastLoc = { x: event.changedTouches[0].x, y: event.changedTouches[0].y }
        //   this.lastTimestamp = event.timeStamp;
        //   //draw
        //   this.context.arc(this.lastLoc.x, this.lastLoc.y, this.data.boldVal / 2, 0, 2 * Math.PI)
        //   this.context.setFillStyle(this.data.curColor);
        //   this.context.fill();
        //   wx.drawCanvas({
        //     canvasId: 'canvas',
        //     reserve: true,
        //     actions: this.context.getActions() // 获取绘图动作数组
        //   })
    
        // }
        this.isMouseDown= false
      },
    
      moveStroke(event) {
        if (this.isMouseDown && event.touches.length == 1) {
          var touch = event.touches[0];
          var context = this.context;
          var curLoc = { x: touch.x, y: touch.y };
          var curTimestamp = event.timeStamp;
          var s = this.calcDistance(curLoc, this.lastLoc)
          var t = curTimestamp - this.lastTimestamp;
          var lineWidth = this.calcLineWidth(t, s)
          //draw
      
          context.setStrokeStyle(this.data.curColor);
          context.setLineWidth(lineWidth);
          context.beginPath()
          context.moveTo(this.lastLoc.x, this.lastLoc.y)
          context.lineTo(curLoc.x, curLoc.y)
    
          // locHistory.push({ x: curLoc.x, y: curLoc.y, with: lineWidth, t: t })
    
    
          context.setLineCap("round")
          context.setLineJoin("round")
          context.stroke();
     
          this.lastLoc=curLoc;
          // this.setData({ lastTimestamp: curTimestamp })
          // this.setData({ lastLineWidth: lineWidth })
    
          wx.drawCanvas({
            canvasId: 'canvas',
            reserve: true,
            actions: this.context.getActions() // 获取绘图动作数组
          })
       
        } else if (event.touches.length > 1){
          this.setData({isTap:false})
    
          var xMove = event.touches[1].x - event.touches[0].x;
          var yMove = event.touches[1].y - event.touches[0].y;
          var newdistance = Math.sqrt(xMove*xMove + yMove*yMove);
          // if (newdistance - this.lastDistance>0){
          //   this.setData({ canvasWidth: this.data.canvasWidth * 1.2 })
          //   this.setData({ canvasHeight: this.data.canvasHeight * 1.2 })
          // }else{
          //   this.setData({ canvasWidth: this.data.canvasWidth * 0.8 })
          //   this.setData({ canvasHeight: this.data.canvasHeight * 0.8})
          // }
    
        }
      },
      calcLineWidth(t, s){
        var v = s / t;
        var resultLineWidth = this.data.boldVal;
        if(v <= 0.1) {
          resultLineWidth = resultLineWidth * 1.2;
        }else if(v >= 10) {
          resultLineWidth = resultLineWidth/1.2
        }else{
          resultLineWidth = resultLineWidth - (v - 0.1) / (10 - 0.1) * (resultLineWidth * 1.2 - resultLineWidth / 1.2)
        }
        return resultLineWidth
      },
     calcDistance(loc1, loc2) {
        return Math.sqrt((loc1.x - loc2.x) * (loc1.x - loc2.x) + (loc1.y - loc2.y) * (loc1.y - loc2.y))
      },
     clearCanvas:function(){
       this.drawBgColor()
       this.setData({ isEraser:false})
      },
     eraser:function () {
       this.setData({ isEraser: !this.data.isEraser})
       this.setData({ curColor:'#ffffff'})
      // this.context.clearActions();
      // this.context.draw()
     },
     saveImg:function(){
       var that = this;
       var keys = wx.getStorageSync('myImg') || [];
       console.log(that.data.keyLength)
       wx.canvasToTempFilePath({
         canvasId: 'canvas',
         success: function (response) {
           keys.unshift(response.tempFilePath)
           wx.setStorage({
             key: 'myImg',
             data: keys,
           })
           that.setData({ isSuc: false })
           setTimeout(function () {
             that.setData({ isSuc: true })
             wx.navigateTo({
               url: '../index/index',
             })
           }, 1000)
         
         } 
       })
     }
    })
    

      小程序中canvas的具体用法和属性请参考小程序文档。  

      

  • 相关阅读:
    去除文本多余空行
    自定义裁剪图片
    遍历文件目录下所有图片并保存到统一路径
    根据节点解析xml
    坐标转换——GCJ-02
    获取进程列表
    判断进程状态
    VSDK modify HDMI resolution
    mcspi
    TI RTOS
  • 原文地址:https://www.cnblogs.com/xunhuang/p/8484098.html
Copyright © 2020-2023  润新知