收藏
回答

canvas性能问题

问题模块
API和组件


1.下面代码在绘制是用的是wx.drawCanvas();原因是我想要把用户绘制的动作保存下来,如果用户中途退出,可以保证下次打开时不从头开始。

2.我会在用户保存后将缓存清空,暂时还没实现。

3.画布在安卓机上,画不了多少内容就很卡,ios还好,基本上感觉不出来,有没有大神能指导我一下该怎么优化代码,重点在 canvasStart、canvasMove、canvasEnd方法上。

/**
 * 路径: pages/draw/draw.js
 * 作者: 花易折
 * 时间: 2017年10月28日23:11:09
 */
 
var that = null;
 
// canvas 全局配置
var context = null;// 使用 wx.createContext 获取绘图上下文 context
var isButtonDown = false;
var arrx = [];
var arry = [];
var arrz = [];
var canvasw = 0;
var canvash = 0;
 
// 获取缓存绘制数据
var drawActions = wx.getStorageSync("drawActions");
 
//获取系统信息
wx.getSystemInfo({
  success: function (res) {
    // canvas宽度
    canvasw = res.windowWidth;
    // 宽高比
    var ratio = res.windowWidth / res.windowHeight;
    // canvas高度
    canvash = 750 / ratio / 2 - 200;
  }
});
 
//注册页面
Page({
  /**
   * 页面的初始数据
   */
  data: {
    // 已经有绘制内容
    drawing: false,
    // 当前画笔颜色坐标
    currentPenIndex: 7,
    // 当前背景颜色坐标
    currentBackIndex: 0,
    // true:选中画笔, false:选中橡皮
    isPen: true,
    //画笔宽度
    penWidth: 4,
    // 是否进入move事件
    isMove: false,
    // 默认颜色
    defaulteColor: [
        // 奶白
        { "color": "#FFFBEC", "penActive": "noActive", "backActive": "active" },
        // 浅蓝
        { "color": "#0066FF", "penActive": "noActive", "backActive": "noActive"},
        // 浅绿
        { "color": "#00CC66", "penActive": "noActive", "backActive": "noActive"},
        // 嫣红
        { "color": "#CC0066", "penActive": "noActive", "backActive": "noActive"},
        // 橘色
        { "color": "#FF6633", "penActive": "noActive", "backActive": "noActive"},
        // 粉色
        { "color": "#FF9999", "penActive": "noActive", "backActive": "noActive"},
        // 鹅黄
        { "color": "#FFCC33", "penActive": "noActive", "backActive": "noActive"},
        // 黑色
        { "color": "#000000", "penActive": "active", "backActive": "noActive"},
        // 灰色
        { "color": "#D2D2D2", "penActive": "noActive", "backActive": "noActive"},
      ]
  },
 
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    that = this;
    // 使用 wx.createContext 获取绘图上下文 context
    context = wx.createCanvasContext('firstCanvas');
    // 初始化画布样式
    initCanvas(that.data.defaulteColor[0].color);
    // 如果緩存中有绘制数据,则绘制画板上
    if ("" != drawActions && undefined != drawActions && null != drawActions) {
      // for (var i = 0; i < drawActions.length; i++) {
      //   wx.drawCanvas({
      //     canvasId: 'firstCanvas',
      //     actions: drawActions[i],
      //     reserve: true
      //   });
      // }
    } else {
      drawActions = [];
    }
  },
 
  /**
   * 分享
   */
  onShareAppMessage: function () {
 
  },
 
  /**
   * canvasId错误回调
   */
  canvasIdErrorCallback: function (e) {
    console.error(e.detail.errMsg)
  },
 
  /**
   * 手指触摸开始
   */
  canvasStart: function (event) {
    isButtonDown = true;
    arrz.push(0);
    arrx.push(event.changedTouches[0].x);
    arry.push(event.changedTouches[0].y);
    that.setData({ drawing: true});
  },
 
  /**
   * 手指触摸后移动
   */
  canvasMove: function (event) {
    // 进入move事件
    that.setData({ isMove: true });
    if (isButtonDown) {
      arrz.push(1);
      arrx.push(event.changedTouches[0].x);
      arry.push(event.changedTouches[0].y);
    }
 
    if (arrx.length > 3) {
      arrx.splice(1, 1);
      arry.splice(1, 1);
    }
 
    for (var i = arrx.length - 2; i < arrx.length; i++) {
      if (arrz[i] == 0) {
        context.moveTo(arrx[i], arry[i]);
      } else {
        context.lineTo(arrx[i], arry[i]);
      };
    };
    context.stroke();
    // context.draw(true);
    var actions = context.getActions();
    console.log(actions);
    wx.drawCanvas({
      canvasId: 'firstCanvas',
      actions: actions,
      reserve: true
    });
    drawActions.push(actions);
  },
 
  /**
   * 手指触摸动作结束
   */
  canvasEnd: function (event) {
    isButtonDown = false;
    // 如果没有进入move事件测绘制点
    if (!that.data.isMove) {
      context.arc(event.changedTouches[0].x, event.changedTouches[0].y, that.data.penWidth / 2, 0, 2 * Math.PI)
      context.setFillStyle(that.data.defaulteColor[that.data.currentPenIndex].color);
      context.fill();
      // context.draw(true);
      var actions = context.getActions();
      wx.drawCanvas({
        canvasId: 'firstCanvas',
        actions: actions,
        reserve: true
      });
      drawActions.push(actions);
    }
    that.setData({ isMove: false });
    wx.setStorageSync("drawActions", drawActions);
  },
 
  /**
   * slider滑动监听事件
   */
  sliderChange: function (e) {
    context.setLineWidth(e.detail.value);
    that.setData({
      penWidth: e.detail.value
    });
  },
 
  /**
   * 设置橡皮擦
   */
  setRubber: function () {
    context.setStrokeStyle(that.data.defaulteColor[that.data.currentBackIndex].color);
    // 设置当前状态为正在使用橡皮
    that.setData({
      isPen: false
    });
  },
 
  /**
   * 清空画布
   */
  clearDraw: function () {
    // 调用清空画布方法
    //clearCanvas();
    wx.showModal({
      title: '清空画布',
      content: '你确定要清除所有内容么?',
      showCancel: true,
      cancelText: 'Oh,不',
      confirmText: '嗯,是的',
      confirmColor: '#9966CC',
      success: function(res) {
        if (res.confirm) {
          // 调用清空画布方法
          clearCanvas();
        }
      }
    })
  },
 
  /**
   * 设置画笔颜色
   */
  setPenColor: function (e) {
    // 设置画笔颜色
    context.setStrokeStyle(that.data.defaulteColor[e.currentTarget.dataset.index].color);
    that.setData({
      // 清除之前画笔颜色选中样式
      ["defaulteColor[" + that.data.currentPenIndex + "].penActive"] : "noActive",
      // 设置当前画笔颜色选中样式
      ["defaulteColor[" + e.currentTarget.dataset.index +"].penActive"]: "active",
      // 设置当前选中画笔颜色
      currentPenIndex: e.currentTarget.dataset.index,
      // 设置当前状态为正在绘制
      isPen: true
    });
  },
 
  /**
   * 设置背景颜色
   */
  setBackColor: function (e) {
    // 设置背景颜色
    initCanvas(that.data.defaulteColor[e.currentTarget.dataset.index].color);
    that.setData({
      // 清除当前背景颜色选中样式
      ["defaulteColor[" + that.data.currentBackIndex + "].backActive"]: "noActive",
      // 设置当前背景颜色选中样式
      ["defaulteColor[" + e.currentTarget.dataset.index + "].backActive"]: "active",
      // 设置当前背景颜色
      currentBackIndex: e.currentTarget.dataset.index,
      drawing: false
    });
  },
 
  /**
   * 保存绘制内容为图片到本地
   */
  saveFile: function () {
    wx.showModal({
      title: '保存提醒',
      content: '你确定要保存当前内容么?',
      showCancel: true,
      cancelText: 'Oh,不',
      confirmText: '嗯,是的',
      confirmColor: '#9966CC',
      success: function (res) {
        if (res.confirm) {
          // 生成图片
          wx.canvasToTempFilePath({
            canvasId: 'firstCanvas',
            success: function (res) {
              // 获取图片路径数组
              var myDrawMood = wx.getStorageSync("myDrawMood");
              // 判断是否已有图片路径数组
              if ("" == myDrawMood || myDrawMood.length <= 0) {
                myDrawMood = [];
              }
              myDrawMood.push(res.tempFilePath);
              wx.setStorageSync("myDrawMood", myDrawMood);
              wx.navigateTo({
                url: '../my/myGallery/myGallery',
              });
            }
          })
        }
      }
    });
  }
})
 
/**
 * 初始化画布
 */
function initCanvas (color) {
  // 清空画布
  context.fillRect(0, 0, canvasw, canvash);
  // 绘制默认画板颜色
  context.beginPath();
  context.setStrokeStyle(that.data.defaulteColor[that.data.currentPenIndex].color);
  context.setLineWidth(that.data.penWidth);
  context.setLineCap('round');
  context.setLineJoin('round');
  context.setFillStyle(color);
  context.fillRect(0, 0, canvasw, canvash);
  context.draw();
  that.setData({
    isPen: true,
    drawing: false
  });
}
 
/**
 * 清空画布
 */
function clearCanvas () {
  // 清除画布数据
  arrx = [];
  arry = [];
  arrz = [];
 
  // 清空画布
  context.fillRect(0, 0, canvasw, canvash);
  // 恢复画布默认状态
  context.beginPath();
  context.setStrokeStyle(that.data.defaulteColor[that.data.currentPenIndex].color);
  context.setLineWidth(that.data.penWidth);
  context.setLineCap('round');
  context.setLineJoin('round');
  context.setFillStyle(that.data.defaulteColor[that.data.currentBackIndex].color);
  context.fillRect(0, 0, canvasw, canvash);
  context.draw();
  that.setData({
    isPen: true,
    drawing: false
  });
}


最后一次编辑于  2017-11-09  (未经腾讯允许,不得转载)
回答关注问题邀请回答
收藏

1 个回答

  • 徐烈
    徐烈
    2018-12-28

    你问题解决了吗?

    2018-12-28
    赞同
    回复 1
    • 花易折 skr skr ~
      花易折 skr skr ~
      05-07

      是 demo 项目,代码已经没了,后面代码做了优化 会好一点,但是绘制的比较多了之后 还是会有一些卡顿

      不好意思没能帮到你

      05-07
      回复