小程序如何在不同设备上自适应生成海报的实现方法


Posted in Javascript onAugust 20, 2019

小程序canvas的API并没有像其他的一样支持小程序独有的 rpx 自适应尺寸单位,在绘制内容时所应用的单位仍然是 px,那么如何实现不同尺寸屏幕的自适应呢?

我们的在开发中常用的参考屏幕尺寸(iPhone6)为:375*667;

那么想要适应其他尺寸的屏幕时只需按照iPhone6的绘制大小按比例进行换算即可:

获取系统屏幕尺寸

先利用wx.getSystemInfo (获取系统信息)的API获取屏幕宽度,然后除iPhone6的屏幕宽度,即可得到相对单位

// 在onLoad中调用
const that = this
wx.getSystemInfo({
 success: function (res) {
  console.log(res)
  that.setData({
   model: res.model,
   screen_width: res.windowWidth/375,
   screen_height: res.windowHeight
  })
 }
})

在绘制方法中将参数乘以相对单位即可实现自适应

这里的rpx是相对不同屏幕宽度的相对单位,测量出得实际宽度,就是实际测出的px像素值*rpx就可以了;之后无论实在iPhone5,iPhone6,iPhone7...都可以进行自适应。

这里的html也要动态的设置宽和高

<canvas canvas-id="PosterCanvas" style="width:{{screen_width*375+'px'}}; height:{{screen_height*1.21+'px'}}"></canvas>
drawPoster(){
  let ctx = wx.createCanvasContext('PosterCanvas'),that=this.data;
  console.log('手机型号' + that.model,'宽'+that.screen_width*375,'高'+ that.screen_height)
  let rpx = that.screen_width
  //这里的rpx是相对不同屏幕宽度的相对单位,实际的宽度测量,就是实际测出的px像素值*rpx就可以了;之后无论实在iPhone5,iPhone6,iPhone7...都可以进行自适应。
  ctx.setFillStyle('#1A1A1A')
  ctx.fillRect(0, 0, rpx * 375, that.screen_height * 1.21)
  ctx.fillStyle = "#E8CDAA";
  ctx.setFontSize(29*rpx)
  ctx.font = 'normal 400 Source Han Sans CN';
  ctx.fillText('Hi 朋友', 133*rpx,66*rpx)
  ctx.fillText('先领礼品再买车', 84*rpx, 119*rpx)
  ctx.drawImage('../../img/sell_index5.png', 26*rpx, 185*rpx, 324*rpx, 314*rpx)
  ctx.drawImage('../../img/post_car2x.png', 66 * rpx, 222 * rpx, 243 * rpx, 145 * rpx)
  ctx.setFontSize(16*rpx)
  ctx.font = 'normal 400 Source Han Sans CN';
  ctx.fillText('长按扫描获取更多优惠', 108*rpx, 545*rpx)
  ctx.drawImage('../../img/code_icon2x.png', 68 * rpx, 575 * rpx, 79 * rpx, 79 * rpx)
  ctx.drawImage('../../img/code2_icon2x.png', 229 * rpx, 575 * rpx, 79 * rpx, 79 * rpx)
  ctx.setStrokeStyle('#666666')
  ctx.setLineWidth(1*rpx)
  ctx.lineTo(187*rpx,602*rpx)
  ctx.lineTo(187*rpx, 630*rpx)
  ctx.stroke()
  ctx.fillStyle = "#fff"
  ctx.setFontSize(13 * rpx)
  ctx.fillText('xxx科技汽车销售公司', 119 * rpx, 663 * rpx)
  ctx.fillStyle = "#666666"
  ctx.fillText('朝阳区·望京xxx科技大厦', 109 * rpx, 689 * rpx)
  ctx.setFillStyle('#fff')
  ctx.draw()
 },

如果图片是线上地址 ctx.drawImage()会出错,不能画出图片

因为会访问一个get请求,是一个异步操作,还没等到get返回就执行了tx.draw()绘制画布。 解决方案 就只在 wx.downloadFile()中成功下载了图片在进行绘制画布。

wx.downloadFile({

url: that.data.url,
 success(res) {
  if (res.statusCode === 200) {
   // 活动
   ctx.drawImage(res.tempFilePath, 66 * rpx, 222 * rpx, 243 * rpx, 145 * rpx)
   // 二维码
   ctx.draw()
  }
 }
})

保存到相册

很简单就是在画完图片之后的draw回调函数里调用canvasToTempFilePath()生产一个零时内存里的链接,然后在调用saveImageToPhotosAlbum()就可以了;其中牵扯到授权,如果你第一次拒绝了授权,你第二次进入的时候在iphone手机上是不会再次提醒你授权的,这时就需要你手动调用了;以下附上代码!

ctx.draw(true, ()=>{

// console.log('画完了')
  wx.canvasToTempFilePath()({
   x: 0,
   y: 0,
   width: rpx * 375,
   height: that.screen_height * 1.21,
   canvasId: 'PosterCanvas',
   success: function (res) {
    // console.log(res.tempFilePath);
    wx.saveImageToPhotosAlbum({
     filePath: res.tempFilePath,
     success: (res) => {
      console.log(res)
     },
     fail: (err) => { }
    })

   }
  }) 
 })

拒绝授权后再次提醒授权的代码

mpvue.saveImageToPhotosAlbum({

filePath: __path,
  success(res) {
   mpvue.showToast({
   title: '保存成功',
   icon: 'success',
   duration: 800,
   mask:true
   });
   },
  fail(res) {
    if (res.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || res.errMsg === "saveImageToPhotosAlbum:fail auth deny" || res.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {

   mpvue.showModal({
      title: '提示',
      content: '需要您授权保存相册',
      showCancel: false,
      success:modalSuccess=>{
       mpvue.openSetting({
        success(settingdata) {
         // console.log("settingdata", settingdata)
         if (settingdata.authSetting['scope.writePhotosAlbum']) {
          mpvue.showModal({
           title: '提示',
           content: '获取权限成功,再次点击图片即可保存',
           showCancel: false,
          })
         } else {
          mpvue.showModal({
           title: '提示',
           content: '获取权限失败,将无法保存到相册哦~',
           showCancel: false,
          })
         }
        },
        fail(failData) {
         console.log("failData",failData)
        },
        complete(finishData) {
         console.log("finishData", finishData)
        }
       })
      }
     })
   }
   }
 });

至此就算完了,能帮到你就给点个赞吧!

示例如下

小程序如何在不同设备上自适应生成海报的实现方法

代码如下

https://gitee.com/jgl1210/lajifenlei

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

Javascript 相关文章推荐
JS读取cookies信息(记录用户名)
Jan 10 Javascript
jQuery实现的Div窗口震动特效
Jun 09 Javascript
js使用DOM操作实现简单留言板的方法
Apr 10 Javascript
JS中Eval解析JSON字符串的一个小问题
Feb 21 Javascript
jquery ezUI 双击行记录弹窗查看明细的实现方法
Jun 01 Javascript
微信小程序 教程之条件渲染
Oct 18 Javascript
浅谈EasyUI常用控件的禁用方法
Nov 09 Javascript
Bootstrap table两种分页示例
Dec 23 Javascript
详解基于Bootstrap+angular的一个豆瓣电影app
Jun 26 Javascript
react-router4 嵌套路由的使用方法
Jul 24 Javascript
Vue.js项目模板搭建图文教程
Sep 20 Javascript
JavaScript使用localStorage存储数据
Sep 25 Javascript
使用 Vue 实现一个虚拟列表的方法
Aug 20 #Javascript
基于vue手写tree插件的那点事儿
Aug 20 #Javascript
详解基于原生JS验证表单组件xy-form
Aug 20 #Javascript
详解微信小程序图片地扯转base64解决方案
Aug 18 #Javascript
wx-charts 微信小程序图表插件的具体使用
Aug 18 #Javascript
微信小程序canvas绘制圆角base64图片的实现
Aug 18 #Javascript
Node.js从字符串生成文件流的实现方法
Aug 18 #Javascript
You might like
PHP VS ASP
2006/10/09 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
php中让人头疼的浮点数运算分析
2016/10/10 PHP
JavaScript 面向对象编程(2) 定义类
2010/05/18 Javascript
LazyLoad 延迟加载(按需加载)
2010/05/31 Javascript
JS打印gridview实现原理及代码
2013/02/05 Javascript
jquery导航制件jquery鼠标经过变色效果示例
2013/12/05 Javascript
IE6-IE9中tbody的innerHTML不能赋值的解决方法
2014/06/05 Javascript
自己动手写的javascript前端等待控件
2015/10/30 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
基于BootStrap Metronic开发框架经验小结【七】数据的导入、导出及附件的查看处理
2016/05/12 Javascript
js原生实现FastClick事件的实例
2016/11/20 Javascript
jQuery实现的简单在线计算器功能
2017/05/11 jQuery
jquery append与appendTo方法比较
2017/05/24 jQuery
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
微信小程序自定义导航栏实例代码
2019/04/05 Javascript
node删除、复制文件或文件夹示例代码
2019/08/13 Javascript
js正则匹配多个全部数据问题
2019/12/20 Javascript
webpack的 rquire.context用法实现工程自动化的方法
2020/02/07 Javascript
node.js中 redis 的安装和基本操作示例
2020/02/10 Javascript
[04:30]显微镜下的DOTA2第五期——拉比克
2013/09/26 DOTA
python操作gmail实例
2015/01/14 Python
python遍历类中所有成员的方法
2015/03/18 Python
初学Python函数的笔记整理
2015/04/07 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
python 并发编程 非阻塞IO模型原理解析
2019/08/20 Python
Python 执行矩阵与线性代数运算
2020/08/01 Python
定义css设备类型-Media Queries图表简介及使用方法
2013/01/21 HTML / CSS
选购国际女性时装设计师品牌:IFCHIC(支持中文)
2018/04/12 全球购物
涉外文秘个人求职的自我评价
2013/10/07 职场文书
酒吧总经理岗位职责
2013/12/10 职场文书
演讲比赛获奖感言
2014/02/02 职场文书
超市食品安全承诺书
2015/04/29 职场文书
母亲去世追悼词
2015/06/23 职场文书
如何撰写创业策划书
2019/06/27 职场文书
教你使用Ubuntu搭建DNS服务器
2022/09/23 Servers