小程序实现canvas添加图文

小程序实现canvas添加图文

笔者今年刚毕业,也没从业经历,难免有代码编写不成熟的地方,欢迎指正
上周开始接触小程序,这里实现的功能类似表情包制作:选择图片、输入文字后保存到本地。目前只是demo 后续会不断完善所以不是最终效果
下面是界面效果
在这里插入图片描述
该页面的data:

//字号
for(let i=12; i<32; i++)
{
  fontsize.push(i)
}
data: {
    fontsize:fontsize,
    sizeindex:0,
    textsize:0,
    textlength:0,
    imgurl:"",
    textvalue:"",
    x:0,
    y:0,
    fontcolorrange: ['黑', '粉红', '纯红', '紫罗兰', '蓝色', '绿宝石', '金', '深橙色','白色'],
    fontcolorhex: ['#000000', '#FF69B4', '#ff0000', '#9400D3', '#0000FF', '#00FA9A', '#FFD700', '#FF8C00', '#ffffff'],
    colorIndex:0,
    tempfile:"",
    canvasWidth:675,
    canvasHeight:0,
    imgwidth:0,
    imgheight:0,
    textIsClick:false,
    EmoPic: ['/img/Emoticon1.jpg', '/img/Emoticon2.jpg', '/img/Emoticon3.jpg','/img/Emoticon4.jpg'],
    EmoIndex:0,
    EmoButtonIsClick:false,
    EmoHeight:1,
    ishavePic:false
  }

我的思路是使用两个canvas分别用于绘制图片和文字,文字样式使用picker选择数据。
上方选择图片区域使用【cover-view】,做absolute定位。由于canvas作为原生组件会显示在最上层所以不能用【view】,遗憾的是cover-view不能实现css的transition动画及其他效果。【选择图片】按钮嵌套在cover-view内,点击时控制cover-view显示和隐藏(控制height)

<canvas canvas-id='canvas-pic' class='canvas-img' style='height:{{canvasHeight}}rpx'>
      <canvas canvas-id='canvas-text' class='canvas-text' bindtouchstart='canvasmovestart' bindtouchmove='canvasmoveon' bindtouchend='canvasmoveout' disable-scroll='true'>

        <cover-view class='chooseEmoPicView'>
          <cover-view class='chooseEmoPic' style='height:{{EmoHeight}}px'>
            <cover-image class='emoPic' src="{{EmoPic[0]}}" bindtap='bindEmoPicChoose' data-index='0' />
            <cover-image class='emoPic' src="{{EmoPic[1]}}" bindtap='bindEmoPicChoose' data-index='1' />
            <cover-image class='emoPic' src="{{EmoPic[2]}}" bindtap='bindEmoPicChoose' data-index='2' />
            <cover-image class='emoPic' src="{{EmoPic[3]}}" bindtap='bindEmoPicChoose' data-index='3' />
          </cover-view>
        <button class='empPicButton' bindtap='bindEmoPicbutton'>选择图片</button>
      </cover-view>
      
      <button class='deleteImgBtn' bindtap='bindcanvasclear'></button>
      <cover-image src='/img/icon/icon_04.png' class='deleteImg' bindtap='bindcanvasclear'></cover-image>
      <cover-view class='deleteImgText' bindtap='bindcanvasclear'>清空画布</cover-view>

      </canvas>
    </canvas>

选择图片触发bindtap事件,函数bindEmoPicChoose:

bindEmoPicChoose:function(e){
    var that = this
    var index = e.currentTarget.dataset.index
    var EmoPic = that.data.EmoPic
    that.setData({
      imgurl: EmoPic[index],
      ishavePic:true
    })
    that.canvasfunction()
  }

canvasfunction函数用于在canvas根据‘imgurl’绘制图片

canvasfunction:function(){
    var that = this
    var mycanvas = wx.createCanvasContext("canvas-pic")
    var imgwidth = that.data.imgwidth
    var imgheight = that.data.imgheight
    var imgurl = that.data.imgurl
    var ishavePic = that.data.ishavePic
    if (ishavePic == true)
    {
      mycanvas.drawImage(imgurl, 0, 0, imgwidth, imgheight)
    }
    else
    {
      mycanvas.setFillStyle("#000000")
      mycanvas.setFontSize("20")
      mycanvas.fillText("请选择一张图片吧~",app.globalData.screenWidth/2 - 100,(app.globalData.screenHeight)*0.3)
    }
    mycanvas.draw()
    console.log("发生了canvasfunction")
    console.log("ishavePic :" + ishavePic)
  },

(图片另外有函数做宽高自适应处理)
触发canvasfunction函数后,在需要绘制图片的canvas就根据imgurl绘制图片,该函数在onshow时也会执行,由于没有图片则示意用户选择图片。imgwidth与imgheight是另外函数获取图片的宽高,然后做自适应的数值。

点击图片后canvas绘制了图片,接下来选择文字样式

文字样式

在这里插入图片描述
文字内容、大小、颜色分别触发picker的bindchange事件相应函数,data中对应数据以数组的形式保存。bindchange的函数参照小程序官方开发文档。

【点我新增文字】按钮触发bindtap事件,事件函数如下:

canvasaddtext:function(){
	var that = this
    var mytext = wx.createCanvasContext("canvas-text")
    var text = that .data.textvalue
    var color = that .data.fontcolorhex[that .data.colorIndex]
    mytext.setFillStyle(color)
    mytext.setFontSize(that.data.fontsize[that.data.sizeindex])
    mytext.fillText(text, 150, 150)
    mytext.draw()
    console.log("发生了canvasaddtext")
    that.setData({
      textsize: that.data.fontsize[that.data.sizeindex]
    })
    console.log("textsize:" + that.data.textsize)
  }

该函数使canvas-id为canvas-text的canvas绘制文字
在这里插入图片描述
文字允许拖拽以改变位置,我们需要对文字所在canvas的bindtouchstart事件、bindtouchmove事件设置对应函数

bindtouchstart事件:保存用户当前点击位置x、y坐标的值

canvasmovestart:function(e){
    var x = e.touches[0].x
    var y = e.touches[0].y
    this.setData({
      x:x,
      y:y,
    })
    console.log("x:" + e.touches[0].x)
    console.log("y:" + e.touches[0].y)
  }

bindtouchmove事件: 在手指移动后修改x、y坐标的值,并根据x、y值绘制canvas

canvasmoveon:function(e){
      console.log("moveon!")
      var x = e.touches[0].x
      var y = e.touches[0].y
      var textsize = this.data.textsize
      var textlength = this.data.textlength
      if(x<0){x = 0}
      if (x + (textlength * textsize) > 280) { x = 280 - (textlength * textsize)}
      if (y - (textsize) < 0){y = textsize}
      if(y + (textsize)>300){ y = 300 - textsize}
      console.log("x:" + x + "  y:" + y)
      var mytext = wx.createCanvasContext("canvas-text")
      var text = this.data.textvalue
      var color = this.data.fontcolorhex[this.data.colorIndex]
      mytext.setFillStyle(color)
      mytext.setFontSize(this.data.fontsize[this.data.sizeindex])
      mytext.fillText(text, x, y)
      mytext.draw()
      this.setData({
        x: x,
        y: y,
        textvalue: text
      })
  }

这里textsize保存的是文本的px值,textlength 是文本框文字长度(e.detail.value.length可获得),文本px值与文本长度的积是文字总像素长度,用于判断距离canvas右边距的位置。由于这里需要限制文本可拖拽范围不能超过canvas图片区,当大于这个范围时,对应的x、y值将被固定。
拖动文字的效果,实际上就是每当坐标值更改时,对canvas重新绘制。
拖动文字时不允许屏幕滚动,因此在canvas标签内添加【disable-scroll=‘true’】

清除画布

在这里插入图片描述
清空画布按钮在右上角。由于在canvas上方,所以也需要嵌套在cover-view内,absolute定位,点击时触发bingtap事件,事件函数如下:

bindcanvasclear:function(){
    this.setData({
      ishavePic:false
    })
    this.canvasfunction()
    this.canvascleartext()
  },
  canvascleartext:function(){
    var mytext = wx.createCanvasContext("canvas-text")
    mytext.fillText("",0,0)
    mytext.draw()
    console.log("发生了canvascleartext")
  }

清除文本目前使用绘制空字符串的方法达到清除的效果

图片保存

图片保存需要调用wx.canvasToTempFilePath 和 wx.saveImageToPhotosAlbum接口,分别用于获取导出图片的url及图片保存到本地

wx.showToast({
      title: '图片生成中',
      duration:1000
    })
wx.canvasToTempFilePath({
        x: 0,
        y: 0,
        width: imgwidth,
        height: imgheight,
        canvasId: 'canvas-pic',
        success: function (res) {
          //var tempfile = res.tempFilePath
          console.log(res.tempFilePath)
          wx.hideToast()
          temp = res.tempFilePath
          wx.saveImageToPhotosAlbum({
            filePath: temp,
            success: function (data) {
              console.log('图片保存成功!data:' + data)
            },
            fail: function (err) {
              console.log("图片保存失败:error:" + err)
            }
          })
        }
      })

图片保存需要用户授权,在app.js中添加以下代码:

if (!res.authSetting['scope.writePhotosAlbum'])
        {
          wx.authorize({
            scope: 'scope.writePhotosAlbum',
            success() {
              console.log('图片保存授权成功')
            }
          })
        }
  • 6
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值