微信小程序基于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 相关文章推荐
js对象的比较
Feb 26 Javascript
javascript jq 弹出层实例
Aug 25 Javascript
基于jQuery实现文本框缩放以及上下移动功能
Nov 24 Javascript
JS动态创建DOM元素的方法
Jun 09 Javascript
EXT中单击button按钮grid添加一行(光标位置可设置)的实例代码
Jun 02 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
Mar 09 Javascript
详解Vue 动态添加模板的几种方法
Apr 25 Javascript
Async Validator 异步验证使用说明
Jul 03 Javascript
微信小程序仿朋友圈发布动态功能
Jul 15 Javascript
微信小程序new Date()方法失效问题解决方法
Jul 29 Javascript
JS实现扫码枪扫描二维码功能
Jan 03 Javascript
微信小程序实现带放大效果的轮播图
May 26 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
回首过去10年中最搞笑的10部动漫,哪一部让你节操尽碎?
2020/03/03 日漫
php缩放图片(根据宽高的等比例缩放)实例介绍
2013/06/09 PHP
探讨:如何使用PHP实现计算两个日期间隔的年、月、周、日数
2013/06/13 PHP
php批量删除数据库下指定前缀的表以prefix_为例
2014/08/24 PHP
symfony表单与页面实现技巧
2015/01/26 PHP
CI框架中$this-&gt;load-&gt;library()用法分析
2016/05/18 PHP
静态html文件执行php语句的方法(推荐)
2016/11/21 PHP
javascript引用对象的方法代码
2007/08/13 Javascript
jquery.jstree 增加节点的双击事件代码
2010/07/27 Javascript
jquery实现兼容浏览器的图片上传本地预览功能
2013/10/14 Javascript
Node.js中使用计时器定时执行函数详解
2014/08/15 Javascript
浅谈jQuery.easyui的datebox格式化时间
2015/06/25 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
js实现图片轮播效果
2015/12/19 Javascript
js实现带农历和八字等信息的日历特效
2016/05/16 Javascript
ES6中的数组扩展方法
2016/08/26 Javascript
原生js实现ajax方法(超简单)
2016/09/20 Javascript
JS实现拖动滚动条评分的效果代码分享
2016/09/29 Javascript
javascript 动态样式添加的简单实现
2016/10/11 Javascript
Canvas实现动态的雪花效果
2017/02/13 Javascript
微信小程序如何实现全局重新加载
2019/06/05 Javascript
Node.js利用Express实现用户注册登陆功能(推荐)
2020/10/26 Javascript
[03:11]完美世界DOTA2联赛PWL DAY8集锦
2020/11/09 DOTA
Python按行读取文件的简单实现方法
2016/06/22 Python
用Eclipse写python程序
2018/02/10 Python
python Opencv将图片转为字符画
2021/02/19 Python
购买限量版收藏品、珠宝和礼品:Bradford Exchange
2016/09/23 全球购物
十佳大学生村官事迹
2014/01/09 职场文书
大学生就业自我推荐信
2014/05/10 职场文书
学雷锋志愿者活动方案
2014/08/21 职场文书
财务工作失职检讨书
2014/11/21 职场文书
师德标兵事迹材料
2014/12/19 职场文书
鲁迅故里导游词
2015/02/05 职场文书
歌剧魅影观后感
2015/06/05 职场文书
股东协议书范本2016
2016/03/21 职场文书
SQL试题 使用窗口函数选出连续3天登录的用户
2022/04/24 Oracle