小程序使用canvas绘画并保存图片,组件

 效果如图: 

 


<template>
  <view class="xx-share"
        bind:tap="handleModal">
    <view class="flez_jz">
      <image wx:if="{{showPoster}}"
             src="{{canvasSrc}}"
             class="img_canv"
             mode="aspectFill"></image>
    </view>
    <!-- 要下载的海报 (尺寸*2) -->
    <canvas canvas-id="myCanvas"></canvas>
  </view>
</template>

<script>
import wepy from 'wepy';
import env from '@/env';
import { showToast, showLoading } from '@/utils/util'
const ctx = wx.createCanvasContext('myCanvas');
const width = 670, height = 800, r = 16, height0 = 530
export default class ShareHB extends wepy.component {
  config = {}

  components = {}
  watch = {
    initCanvas () {
      wx.showLoading({
        title: '图片正在生成',
      });
      this._getCode();
    }
  }
  props = {
    initCanvas: Boolean,
    title: String,
    content: String,
    introduce: {
      type: String,
      default: '我把最好的推荐给你,快去看看吧~'
    },

    imgLogo: String,
    nickName: String,
    price: String,
    priceLabel: String,
    toPagePath: String,
    toPageParam: String, // 参数 (用'#'连接)
    Hierarchy: String,//层级。默认空需要嵌套,1为直接使用
  }

  mixins = []

  data = {
    imgLogo2: '',
    showPoster: false,
    codeImgSrc: '', // 小程序码
    canvasSrc: '',
    config: {
      startX: 0,
      startY: 0,
      maxWidth: 650,
      maxHeight: 1000
    }
  }

  computed = {}

  methods = {
    handleModal () {
      this.$emit('handle-modal');
    }
  }

  events = {}

  /* 生命周期 */
  onLoad () { }

  /* 函数 */
  // 获取小程序码
  _getCode () {
    if (!this.toPagePath) {
      wx.hideLoading();
      wx.showToast({
        title: '二维码路径无效',
        icon: 'none',
        duration: 2000
      });
      return;
    }
    let userInfo = wx.getStorageSync('userInfo');

    let shareInfo = ''
    if (this.Hierarchy) {
      shareInfo = this.$parent.$parent.globalData.shareInfo;
    } else {
      shareInfo = this.$parent.$parent.$parent.globalData.shareInfo;
    }

    var storeId = ''
    var id = ''
    if (shareInfo) {
      storeId = shareInfo.storeId
      id = shareInfo.distributorId
    } else {

      storeId = userInfo.storeId ? userInfo.storeId : wx.getStorageSync('storeId')
      if (userInfo.distributorId) {
        id = userInfo.distributorId
      } else {
        id = wx.getStorageSync('customerId')
      }
    }


    var shareUserinfo = wx.getStorageSync('shareUserinfo')
    if (shareUserinfo) {
      storeId = shareUserinfo.storeId
      id = shareUserinfo.distributorId
    }
    let scene;

    if (!this.toPageParam) {
      scene = encodeURIComponent(`id=${id}#storeId=${storeId}`);
    } else {
      scene = encodeURIComponent(this.toPageParam);
    }

    console.log(this.toPageParam, 'toPageParam正在测')
    console.log(this.toPagePath, 'toPagePath正在测')
    // scene = encodeURIComponent(`id=${id}#storeId=${storeId}`);
    let page = encodeURIComponent(this.toPagePath);
    // 装宝宝type2 名片3 导行供应链4分销客1

    let codeImgSrc = `${env.API_URL}/wxacode/get?scene=${scene}&page=${page}&type=1`;

    wx.getImageInfo({
      src: codeImgSrc,
      success: res => {

        this.codeImgSrc = res.path;
        this.$apply();
        setTimeout(() => {
          this._getImageInfo();
        }, 1000)

      },
      fail: err => {
        wx.hideLoading();
        wx.showToast({
          title: '二维码生成失败',
          icon: 'none',
          duration: 2000
        });
      }
    });
  }

  // 如果是网络图片的话, 必须先保存至本地进行绘制
  _getImageInfo () {
    let bgimg = 'https://cdn.ylnhome.com/tuike/fxk_share.png'
    // 正式环境必须要 https
    if (bgimg.indexOf('https') === -1) {
      bgimg = bgimg.replace(/^http/, 'https');
    }
    wx.getImageInfo({
      src: bgimg,
      success: res => {
        this.bgimg = res.path;
        this.$apply()
        if (this.imgLogo) {
          wx.getImageInfo({
            src: this.imgLogo,
            success: res => {
              this.imgLogo2 = res.path;
              this.$apply()
              this._drawCanvas(res.path);
            },
            fail: err => {
              wx.hideLoading();
            }
          })
        } else {
          this._drawCanvas(res.path);
        }
      },
      fail: err => {
        wx.hideLoading();
      }
    })
  }
//开始canvas绘画
  _drawCanvas () {
    let _this = this
    const ctx = wx.createCanvasContext('myCanvas')
    ctx.setFillStyle('#fff')
    ctx.rect(0, 0, width, height)
    ctx.fill()
    ctx.draw(true)
    // 营销图
    ctx.drawImage(_this.bgimg, 0, 0, width, height0)
    ctx.draw(true)
    // 头像
    ctx.save()
    ctx.beginPath()
    ctx.setShadow(0, 5, 5, '#E2E2E2')
    ctx.arc(102, 616, 60, 0, 2 * Math.PI)
    ctx.setStrokeStyle('#fff')
    ctx.setLineWidth(6)
    ctx.stroke()
    ctx.closePath()
    ctx.clip()
    ctx.drawImage(_this.imgLogo2, 43, 555, 130, 130)
    ctx.restore()
    ctx.draw(true)
    // 姓名
    ctx.setTextAlign('left')
    ctx.font = 'bold 36px sans-serif'
    ctx.setFillStyle('#333')
    ctx.fillText(this.nickName, 180, 640)
    ctx.draw(true)

    // 地址、电话、qq
    ctx.font = 'normal 25px sans-serif';
    ctx.setFillStyle('#101010')
    ctx.fillText('努力打工不如躺着赚钱!', 48, 725, 460)
    ctx.fillText('跟我一起注册成为意罗尼推荐官吧!', 48, 765, 460)
    ctx.draw(true)
    // 小程序码
    ctx.drawImage(_this.codeImgSrc, 460, 574, 180, 180)
    ctx.draw(true)
    setTimeout(() => {
      wx.hideLoading()
      wx.canvasToTempFilePath({
        quality: 1,
        canvasId: 'myCanvas',
        success (res) {
          wx.hideLoading()
          // this._canvasToTempFilePath();
          _this.canvasSrc = res.tempFilePath;
          _this.showPoster = true;
          _this.$apply()
          _this.saveToPhotosAlbum(res.tempFilePath)
        }
      })
    }, 3000)
    //     }
    // })
  }
  // 保存canvas生成的图片到相册
  saveToPhotosAlbum (path) {
    var that = this;
    wx.saveImageToPhotosAlbum({
      filePath: path,
      success (res) {
        that.$emit('save-img-success', res);
        wx.showToast({
          title: '保存成功',
          icon: 'success',
          duration: 1500
        });
      }
    })
  }

  // 生成canvas
  _canvasToTempFilePath () {

    setTimeout(() => {
      wx.canvasToTempFilePath({
        quality: 1,
        canvasId: 'myCanvas',
        success: res => {
          wx.hideLoading();
          this.canvasSrc = res.tempFilePath;
          console.log(res.tempFilePath, 'res.tempFilePath')
          this.showPoster = true;
          this.$apply();
          this._saveImageToPhotosAlbum(res.tempFilePath);
        },
        fail: err => {
          wx.hideLoading();
          wx.showToast({
            title: '生成失败',
            icon: 'none',
            duration: 2000
          });
        }
      })
    }, 500);
  }
  // 保存canvas生成的图片到相册
  _saveImageToPhotosAlbum (filePath) {
    wx.saveImageToPhotosAlbum({
      filePath,
      success: res => {
        wx.showToast({
          title: '保存成功',
          icon: 'success',
          duration: 2000
        });
        this.$emit('save-img-success', res);
      },
      fail: err => {
        wx.showToast({
          title: '保存失败',
          icon: 'none',
          duration: 2000
        });
      }
    });
  }

  //文字换行处理
  // canvas 标题超出换行处理
  _wordsWrap (ctx, name, nameWidth, maxWidth, startX, srartY, wordsHight) {
    let lineWidth = 0;
    let lastSubStrIndex = 0;
    for (let i = 0; i < name.length; i++) {
      lineWidth += ctx.measureText(name[i]).width;
      if (lineWidth > maxWidth) {
        ctx.fillText(name.substring(lastSubStrIndex, i), startX, srartY);
        srartY += wordsHight + 10;
        lineWidth = 0;
        lastSubStrIndex = i;
      }
      if (i == name.length - 1) {
        ctx.fillText(name.substring(lastSubStrIndex, i + 1), startX, srartY);
      }
    }
  }
}
</script>

<style lang="less" scoped>
.flez_jz {
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 10%;
  width: 100%;
}
.img_canv {
  width: 670rpx;
  height: 800rpx;
}
.xx-share {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  z-index: 1001;
  canvas {
    width: 670px;
    height: 800px;
    position: absolute;
    top: -2000px;
    transform: scale(0.5);
  }

}
</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值