微信小程序基于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 相关文章推荐
jquery.jstree 增加节点的双击事件代码
Jul 27 Javascript
JavaScript限定复选框的选择个数示例代码
Aug 25 Javascript
javascript自动给文本url地址增加链接的方法分享
Jan 20 Javascript
JS实现关键字搜索时的相关下拉字段效果
Aug 05 Javascript
加随机数引入脚本不让浏览器读取缓存
Sep 04 Javascript
详解JavaScript的Polymer框架中的通知交互
Jul 29 Javascript
表单元素值获取方式js及java方式的简单实例
Oct 15 Javascript
浅谈webpack编译vue项目生成的代码探索
Dec 11 Javascript
实例分析Array.from(arr)与[...arr]到底有何不同
Apr 09 Javascript
JS中的算法与数据结构之栈(Stack)实例详解
Aug 20 Javascript
layui使用form表单实现post请求页面跳转的方法
Sep 14 Javascript
vue双向绑定数据限制长度的方法
Nov 04 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
php实现从ftp服务器上下载文件树到本地电脑的程序
2009/02/10 PHP
PHP获取用户的浏览器与操作系统信息的代码
2012/09/04 PHP
PHP中数据库单例模式的实现代码分享
2014/08/21 PHP
PHP判断数据库中的记录是否存在的方法
2014/11/14 PHP
php实现字符串反转输出的方法
2015/03/14 PHP
php隐藏实际地址的文件下载方法
2015/04/18 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
2017/05/05 PHP
PHP之认识(二)关于Traits的用法详解
2019/04/11 PHP
URL编码转换,escape() encodeURI() encodeURIComponent()
2006/12/27 Javascript
兼容Mozilla必须知道的知识。
2007/01/09 Javascript
基于jquery的15款幻灯片插件
2011/04/10 Javascript
JavaScript高级程序设计 阅读笔记(十三) js定义类或对象
2012/08/14 Javascript
防止浏览器记住用户名及密码的简单实用方法
2013/04/22 Javascript
javascript打印html内容功能的方法示例
2013/11/28 Javascript
JavaScript获取图片真实大小代码实例
2014/09/24 Javascript
javascript实现checkBox的全选,反选与赋值
2015/03/12 Javascript
页面get请求 中文参数方法乱码问题的快速解决方法
2016/05/31 Javascript
js实现漫天星星效果
2017/01/19 Javascript
JS操作input标签属性checkbox全选的实现代码
2017/03/02 Javascript
详解Vue如何支持JSX语法
2017/11/10 Javascript
详解npm 配置项registry修改为淘宝镜像
2018/09/07 Javascript
解决vue单页面修改样式无法覆盖问题
2019/08/05 Javascript
vue指令v-html使用过滤器filters功能实例
2019/10/25 Javascript
使用axios请求接口,几种content-type的区别详解
2019/10/29 Javascript
vue 解决移动端弹出键盘导致页面fixed布局错乱的问题
2019/11/06 Javascript
Python中Django发送带图片和附件的邮件
2017/03/31 Python
同时安装Python2 &amp; Python3 cmd下版本自由选择的方法
2017/12/09 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
2018/06/19 Python
Python enumerate函数功能与用法示例
2019/03/01 Python
Python实现RGB与HSI颜色空间的互换方式
2019/11/27 Python
tensorflow多维张量计算实例
2020/02/11 Python
科颜氏加拿大官方网站: Kiehl’s加拿大
2016/08/16 全球购物
英国电动工具购买网站:Anglia Tool Centre
2017/04/25 全球购物
Proenza Schouler官方网站:纽约女装和配饰品牌
2019/01/03 全球购物
大学生入党思想汇报
2014/01/14 职场文书
争先创优个人总结
2015/03/04 职场文书