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


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 相关文章推荐
javascript 常用关键字列表集合
Dec 04 Javascript
JavaScript 面向对象与原型
Apr 10 Javascript
JavaScript汉诺塔问题解决方法
Apr 21 Javascript
yui3的AOP(面向切面编程)和OOP(面向对象编程)
May 01 Javascript
JavaScript点击按钮后弹出透明浮动层的方法
May 11 Javascript
关于js里的this关键字的理解
Aug 17 Javascript
AngularJS 控制器 controller的详解
Oct 17 Javascript
vue 虚拟dom的patch源码分析
Mar 01 Javascript
jQuery实现炫丽的3d旋转星空效果
Jul 04 jQuery
JS实现从对象获取对象中单个键值的方法示例
Jun 05 Javascript
jQuery Datatables 动态列+跨列合并实现代码
Jan 30 jQuery
小程序实现侧滑删除功能
Jun 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
CodeIgniter错误mysql_connect(): No such file or directory解决方法
2014/09/06 PHP
基于递归实现的php树形菜单代码
2014/11/19 PHP
php解析base64数据生成图片的方法
2016/12/06 PHP
Firefox window.close()的使用注意事项
2009/04/11 Javascript
jQuery 自定义函数写法分享
2012/03/30 Javascript
JS操作select下拉框动态变动(创建/删除/获取)
2013/06/02 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
2014/05/05 Javascript
JavaScript中几种排序算法的简单实现
2015/07/29 Javascript
Jquery跨域获得Json的简单实例
2016/05/18 Javascript
chrome浏览器如何断点调试异步加载的JS
2016/09/05 Javascript
jQuery实现邮箱下拉列表自动补全功能
2016/09/08 Javascript
详解js的六大数据类型
2016/12/27 Javascript
JS中闭包的经典用法小结(2则示例)
2016/12/28 Javascript
JS 实现 ajax 异步浏览器兼容问题
2017/01/21 Javascript
Bootstrap笔记之缩略图、警告框实例详解
2017/03/09 Javascript
Vue.js项目部署到服务器的详细步骤
2017/07/17 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
微信小程序实现导航栏选项卡效果
2020/06/19 Javascript
详解webpack2异步加载套路
2018/09/14 Javascript
在vscode 中设置 vue模板内容的方法
2020/09/02 Javascript
[52:20]DOTA2-DPC中国联赛正赛 SAG vs XGBO3 第一场 3月5日
2021/03/11 DOTA
Python中针对函数处理的特殊方法
2014/03/06 Python
python递归实现快速排序
2018/08/18 Python
python实现诗歌游戏(类继承)
2019/02/26 Python
详解Python中的format格式化函数的使用方法
2019/11/20 Python
django框架中间件原理与用法详解
2019/12/10 Python
四方通行旅游网:台湾订房、出国旅游
2017/09/20 全球购物
马来西亚演唱会订票网站:StubHub马来西亚
2018/10/18 全球购物
会计主管岗位职责
2014/01/03 职场文书
采购类个人求职的自我评价
2014/02/18 职场文书
个人公开承诺书
2014/03/28 职场文书
设计大赛策划方案
2014/06/13 职场文书
给客户的感谢信
2015/01/21 职场文书
我的长征观后感
2015/06/09 职场文书
2016年3月份红领巾广播稿
2015/12/21 职场文书
面试中老生常谈的MySQL问答集锦夯实基础
2022/03/13 MySQL