专栏首页胡哥有话说基于Taro的的微信小程序分享图片功能实践

基于Taro的的微信小程序分享图片功能实践

前言

在各种小程序(微信、百度、支付宝)、H5、NativeApp 纷纷扰扰的当下,给大家强烈安利一款基于React的多终端开发利器:京东Taro(泰罗·奥特曼),Taro致力于多终端统一解决方案,一处代码,多处运行。

Taro支持以React语言开发小程序,支持CSS预处理器,支持实时编译更新,支持NPM,等等等等,简直不要太爽!

微信小程序分享图片功能是经常在小程序业务中出现的,比如学习打卡分享,推广会员分享,推广商品分享等等。因为小程序是不支持直接分享图片到朋友圈的,一般操作为:

  1. 生成包含小程序码(当前也可以是其他特定的信息)的图片;
  2. 用户点击保存图片,下载到本地,再发布到朋友圈;
  3. 其他用户长按识别该小程序码,进入当前小程序。

今天胡哥给大家分享下,基于Taro框架实现微信小程序分享图片功能的实践。

一、搭建Taro项目框架,创建微信小程序

1. 安装taro脚手架工具

npm install -g @tarojs/cli

2. 初始化taro项目

taro init taro-img-share

3. 编译项目,开启Dev模式,生成小程序 -- dist目录

npm run dev:weapp

4. 微信开发者工具,创建小程序,选择项目根目录为taro-img-share下的dist目录

二、小程序分享图片功能实践 --- 打卡图片分享功能

先上图,再说话

效果图

点击保存到相册

这是重点:使用Canvas绘制图片并展示,保存图片到相册

drawImage()方法负责绘制展示,saveCard()方法负责下载图片到相册

src/pages/index/index.js

import Taro, { Component } from '@tarojs/taro'
// 引入对应的组件
import { View, Text, Button, Canvas } from '@tarojs/components'
import './index.scss'

export default class Index extends Component {

  config = {
    navigationBarTitleText: '首页'
  }

  /**
  * 初始化信息
  */
  constructor () {
    this.state = {
      // 用户信息
      userInfo: {},
      // 是否展示canvas
      isShowCanvas: false
    }
  }

  /**
   * getUserInfo() 获取用户信息
   */
  getUserInfo (e) {
    if (!e.detail.userInfo) {
      Taro.showToast({
        title: '获取用户信息失败,请授权',
        icon: 'none'
      })
      return
    }
    this.setState({
      isShowCanvas: true,
      userInfo: e.detail.userInfo
    }, () => {
      // 调用绘制图片方法
      this.drawImage()
    })
  }

  /**
   * drawImage() 定义绘制图片的方法
   */
  async drawImage () {
    // 创建canvas对象
    let ctx = Taro.createCanvasContext('cardCanvas')
    
    // 填充背景色
    let grd = ctx.createLinearGradient(0, 0, 1, 500)
    grd.addColorStop(0, '#1452d0')
    grd.addColorStop(0.5, '#FFF')
    ctx.setFillStyle(grd)
    ctx.fillRect(0, 0, 400, 500)

    // // 绘制圆形用户头像
    let { userInfo } = this.state
    let res = await Taro.downloadFile({
      url: userInfo.avatarUrl
    })
    ctx.save()
    ctx.beginPath()
    // ctx.arc(160, 86, 66, 0, Math.PI * 2, false)
    ctx.arc(160, 88, 66, 0, Math.PI * 2)
    ctx.closePath()
    ctx.clip()
    ctx.stroke()
    ctx.translate(160, 88)
    ctx.drawImage(res.tempFilePath, -66, -66, 132, 132)
    ctx.restore()

    // 绘制文字
    ctx.save()
    ctx.setFontSize(20)
    ctx.setFillStyle('#FFF')
    ctx.fillText(userInfo.nickName, 100, 200)
    ctx.setFontSize(16)
    ctx.setFillStyle('black')
    ctx.fillText('已在胡哥有话说公众号打卡20天', 50, 240)
    ctx.restore()

    // 绘制二维码
    let qrcode = await Taro.downloadFile({
      url: 'https://upload-images.jianshu.io/upload_images/3091895-f0b4b900390aec73.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/258/format/webp.jpg'
    })
    ctx.drawImage(qrcode.tempFilePath, 70, 260, 180, 180)

    // 将以上绘画操作进行渲染
    ctx.draw()
  }

  /**
   * saveCard() 保存图片到本地
   */
  async saveCard () {
    // 将Canvas图片内容导出指定大小的图片
    let res = await Taro.canvasToTempFilePath({
      x: 0,
      y: 0,
      width: 400,
      height: 500,
      destWidth: 360,
      destHeight: 450,
      canvasId: 'cardCanvas',
      fileType: 'png'
    })
    let saveRes = await Taro.saveImageToPhotosAlbum({
      filePath: res.tempFilePath
    })
    if (saveRes.errMsg === 'saveImageToPhotosAlbum:ok') {
      Taro.showModal({
        title: '图片保存成功',
        content: '图片成功保存到相册了,快去发朋友圈吧~',
        showCancel: false,
        confirmText: '确认'
      })
    } else {
        Taro.showModal({
        title: '图片保存失败',
        content: '请重新尝试!',
        showCancel: false,
        confirmText: '确认'
      })
    }
  }

  render () {
    let { isShowCanvas } = this.state
    return (
      <View className='index'>
        <Button onGetUserInfo={this.getUserInfo} openType="getUserInfo" type="primary" size="mini">打卡</Button>
        {/* 使用Canvas绘制分享图片 */}
        {
          isShowCanvas &&
            <View className="canvas-wrap">
              <Canvas 
                id="card-canvas"
                className="card-canvas"
                style="width: 320px; height: 450px"
                canvasId="cardCanvas" >
              </Canvas>
              <Button onClick={this.saveCard} className="btn-save" type="primary" size="mini">保存到相册</Button>
            </View> 
        }
      </View>
    )
  }
}

src/pages/index/index.sass

index.js组件中的css样式

.index {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
}
.canvas-wrap {
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.3);
  position: fixed;
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  .btn-save {
    margin-top: 40rpx;
  }
}

注意事项

设置Taro支持ES6的async/await

  1. 下载@tarojs/async-await npm install -D @tarojs/async-await
  2. app.js中引入 import '@tarojs/async-await'

开发完毕,发布小程序

  1. 执行打包,生成最终的小程序源码 npm run build:weapp
  2. 发布小程序 点击微信开发者工具上传按钮,上传小程序,然后在微信小程序平台发布小程序即可。

小结

  1. 本文着重介绍了使用Taro实现小程序生成打卡图片,保存相册,分享图片功能的开发原理与实践步骤,各位童鞋可参考并结合自己的实际业务进行扩展开发。
  2. 本文并为深入的对不同手机进行图片适配,部分值也是设置的固定值(如填充文字的开始坐标与填充的文字长度、大小),并未做比例响应。需要进一步交流的小伙伴,可以关注胡哥有话说公众号,持续关注相关文章,也可直接在文章留言交流。
  3. 无论是使用何种框架如Taro、mpvue、wepy等开发小程序分享图片功能,原理都是一样的,只不过是在调用方法以及处理逻辑时需要进行响应的小调整

掌握业务功能实现原理,是制胜一切的法宝!

如何获取该案例的源代码

  1. 关注胡哥有话说公众号
  2. 回复关键字Taro即可,会收到项目源码地址

后记

以上就是胡哥今天给大家分享的内容,喜欢的小伙伴记得收藏转发、点击右下角按钮在看,推荐给更多小伙伴呦,欢迎多多留言交流...

胡哥有话说,一个有技术,有情怀的胡哥!京东开放平台首席前端攻城狮。与你一起聊聊大前端,分享前端系统架构,框架实现原理,最新最高效的技术实践!

本文分享自微信公众号 - 胡哥有话说(hugeyouhuashuo),作者:胡小帅童鞋

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-07-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 单屏页面响应式适配玩法

    把公共的 页头 、页脚、导航栏、边框 放到最顶层,比方说设置层级为 999,其他每个独立页则放在下面,然后切换页面的时候更新独立页的层级以达到效果图的效果(当然...

    胡哥有话说
  • 深入揭秘前端路由本质,手写 mini-router

    前端路由一直是一个很经典的话题,不管是日常的使用还是面试中都会经常遇到。本文通过实现一个简单版的 react-router 来一起揭开路由的神秘面纱。

    胡哥有话说
  • JavaScript模块化-CommonJS、AMD、CMD、UMD、ES6

    AMD(Asynchronous Module Definition)异步模块定义,客户端规范。采用异步方式加载模块,模块加载不影响它后面语句的代执行。

    胡哥有话说
  • canvas-画线

    坐标系统简析 ? 左边是笛卡尔坐标系,右边是canvas坐标系。 笛卡尔坐标系(Cartesian coordinate system): 也称直角坐标系,是一...

    前端黑板报
  • 基于Canvas的时钟

    这里有一点取巧:画完外圈圆、内圈圆后,将原点(默认为0,0)转换为圆的中心点,这样的话,只需要知道角度,在已知时针、分针、秒针它的长度情况下,很容易求出对应的坐...

    meteoric
  • 第156天:canvas(三)

    ​ translate方法接受两个参数。x 是左右偏移量,y 是上下偏移量,如右图所示。

    半指温柔乐
  • 给pugjs的stun主题添加canvas时钟

    首先隔了这么久才继续进行更新的原因是网站备案和毕业设计,加上刚入职没有时间去进行内容更新,以后会继续更新了

    impressionyang
  • JavaScript实现iphone时钟

    http://www.w3school.com.cn/tags/html_ref_canvas.asp

    Jack Chen
  • canvas仿芝麻信用分仪表盘

    唉,总感觉不像。这个是GIF图,可能在网页上打开的效果会好一点(当然可能就是这样)。大家可以点击底部预览codepen上的演示。有两个不完美的地方,一个是实际上...

    前端博客 : alili.tech
  • Canvas 奇妙历险(一)

    canvas的中文名叫画布,是HTML5元素的一部分。最早是由苹果公司提出的这么一个概念,后来被应用在我们的网络技术上,结合Javascript脚本编程,我们可...

    丰臣正一

扫码关注云+社区

领取腾讯云代金券