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


Posted in Javascript onJuly 12, 2019

前言

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

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

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

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

今天胡哥给大家分享下,基于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目录

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

先上图,再说话

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

效果图

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

点击保存到相册

这是重点:使用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.发布小程序

点击微信开发者工具上传按钮,上传小程序,然后在微信小程序平台发布小程序即可。

小结

本文着重介绍了使用Taro实现小程序生成打卡图片,保存相册,分享图片功能的开发原理与实践步骤,各位童鞋可参考并结合自己的实际业务进行扩展开发。

本文并为深入的对不同手机进行图片适配,部分值也是设置的固定值(如填充文字的开始坐标与填充的文字长度、大小),并未做比例响应。需要进一步交流的小伙伴,可以关注胡哥有话说公众号,持续关注相关文章,也可直接在文章留言交流。

无论是使用何种框架如Taro、mpvue、wepy等开发小程序分享图片功能,原理都是一样的,只不过是在调用方法以及处理逻辑时需要进行响应的小调整

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 装载iframe子页面,自适应高度
Mar 20 Javascript
让你的CSS像Jquery一样做筛选的实现方法
Jul 10 Javascript
node.js中的console.timeEnd方法使用说明
Dec 09 Javascript
jquery实现弹窗功能(窗口居中显示)
Feb 27 Javascript
jQuery插件FusionCharts绘制的2D双柱状图效果示例【附demo源码】
May 13 jQuery
Vue.js结合Ueditor富文本编辑器的实例代码
Jul 11 Javascript
js实现HTML中Select二级联动的实例
Jan 05 Javascript
JavaScript实现学生在线做题计时器功能
Dec 05 Javascript
vue-router结合vuex实现用户权限控制功能
Nov 14 Javascript
ES6学习笔记之let与const用法实例分析
Jan 22 Javascript
vue使用vant中的checkbox实现全选功能
Nov 17 Vue.js
WebPack工具运行原理及入门教程
Dec 02 Javascript
小程序实现悬浮搜索框
Jul 12 #Javascript
小程序实现搜索框功能
Mar 26 #Javascript
iview的table组件自带的过滤器实现
Jul 12 #Javascript
es6中比较有用的7个技巧小结
Jul 12 #Javascript
echarts大屏字体自适应的方法步骤
Jul 12 #Javascript
javascript实现简易聊天室
Jul 12 #Javascript
简单了解vue中父子组件如何相互传递值(基础向)
Jul 12 #Javascript
You might like
ADODB结合SMARTY使用~超级强
2006/11/25 PHP
php实现无限级分类实现代码(递归方法)
2011/01/01 PHP
php去除重复字的实现代码
2011/09/16 PHP
symfony2.4的twig中date用法分析
2016/03/18 PHP
thinkPHP引入类的方法详解
2016/12/08 PHP
Alliance vs AM BO3 第一场2.13
2021/03/10 DOTA
Extjs列表详细信息窗口新建后自动加载解决方法
2010/04/02 Javascript
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
2010/06/19 Javascript
jquery 选项卡效果 新手代码
2011/07/08 Javascript
js实现的点击div区域外隐藏div区域
2014/06/30 Javascript
jQuery中not()方法用法实例
2015/01/06 Javascript
jQuery进行组件开发完整实例
2015/12/15 Javascript
JS代码实现根据时间变换页面背景效果
2016/06/16 Javascript
JavaScript数据存储 Cookie篇
2016/07/02 Javascript
html+js+highcharts绘制圆饼图表的简单实例
2016/08/04 Javascript
10分钟掌握XML、JSON及其解析
2020/12/06 Javascript
基于Marquee.js插件实现的跑马灯效果示例
2017/01/25 Javascript
微信小程序代码上传、审核发布小程序
2019/05/18 Javascript
websocket4.0+typescript 实现热更新的方法
2019/08/14 Javascript
node.js中事件触发器events的使用方法实例分析
2019/11/23 Javascript
node创建Vue项目步骤详解
2020/03/06 Javascript
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
python读取中文txt文本的方法
2018/04/12 Python
Python 实现两个服务器之间文件的上传方法
2019/02/13 Python
Python MongoDB 插入数据时已存在则不执行,不存在则插入的解决方法
2019/09/24 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
实例教程 HTML5 Canvas 超炫酷烟花绽放动画实现代码
2014/11/05 HTML / CSS
西班牙语在线票务市场:SuperBoletería
2019/06/10 全球购物
设计毕业生简历中的自我评价
2013/10/01 职场文书
纪律教育学习心得体会
2014/09/02 职场文书
2014年驻村干部工作总结
2014/11/17 职场文书
2019商业计划书格式、范文
2019/04/24 职场文书
祝福语集锦:给满月宝宝的祝福语
2019/11/20 职场文书
500字作文之周记
2019/12/13 职场文书
python中的被动信息搜集
2021/04/29 Python
Mysql 一主多从的部署
2022/05/20 MySQL