微信小程序实现图片自适应(支持多图)


Posted in Javascript onJanuary 25, 2017

大家都知道微信小程序图片自适应,是一个比较常见的需求,平时我们在WEBView中,只需要设置max-width:100%.在微信里面虽然widthFix也能实现,但有一个缺陷就是图片的宽度值要大于或者等于设定的值,否则就会发生拉伸变形,本文通过另外一种来适应。

首先我们来看看图片组件给的一些说明:

属性名 类型 默认值 说明
src String 图片资源地址
mode String 'scaleToFill' 图片裁剪、缩放的模式
binderror HandleEvent 当错误发生时,发布到 AppService 的事件名,事件对象event.detail = {errMsg: 'something wrong'}
bindload HandleEvent 当图片载入完毕时,发布到 AppService 的事件名,事件对象event.detail = {height:'图片高度px', width:'图片宽度px'}

注:image组件默认宽度300px、高度225px

mode 有 13 种模式,其中 4 种是缩放模式,9 种是裁剪模式。

模式 说明
scaleToFill 不保持纵横比缩放图片,使图片的宽高完全拉伸至填满 image 元素
aspectFit 保持纵横比缩放图片,使图片的长边能完全显示出来。也就是说,可以完整地将图片显示出来。
aspectFill 保持纵横比缩放图片,只保证图片的短边能完全显示出来。也就是说,图片通常只在水平或垂直方向是完整的,另一个方向将会发生截取。
widthFix 宽度不变,高度自动变化,保持原图宽高比不变

如果说要有一种比较合适的方案,大概是widthFix,然而上面这些模式中,所要求的前提是需要给图片标签设定一个宽度值或者一个高度值。但有时候我们根本不想限定图片的宽高,我们需要的是图片自身能够根据自身的大小来适配。

而widthFix模式就要求你必须先设定一个宽度值,如果出来的图片比给定的width小呢?此时图片则会发生拉伸的现象。 (常见应用在文章中,因为文章中的插图有可能比默认的宽小,比如常见的表情)。

其实上面的标签中,图片为我们预留了一个函数bindLoad。下面看看我是怎么支持自适应的。

有一个前提,就是多图的时候,你需要知道这个图片是处于所有中的位置index,我们通过这个位置来保存图片的宽度和高度。

<image src="http://ww4.sinaimg.cn/bmiddle/006q8Q6bjw1fbwucs1cctj30t80t8myh.jpg" bindLoad="imageLoad" style="width:{{imageSize[0].width}}rpx; height:{{imageSize[0].height}}rpx" data-index="0" mode="scaleToFill"/>
<image src="http://ww4.sinaimg.cn/bmiddle/006q8Q6bjw1fbwucs1cctj30t80t8myh.jpg" bindLoad="imageLoad" style="width:{{imageSize[1].width}}rpx; height:{{imageSize[1].height}}rpx" data-index="1" mode="scaleToFill"/>
var px2rpx = 2, windowWidth=375;
page({
 data:{
 imageSize:{}
 },
 onLoad:function(options){
 wx.getSystemInfo({
 success: function(res) {
 windowWidth = res.windowWidth;
 px2rpx = 750 / windowWidth;
 }
 })
 },
 imageLoad:function(e){
 //单位rpx
 var originWidth = e.detail.width*px2rpx, 
 originHeight = e.detail.height*px2rpx,
 ratio = originWidth/originHeight;
 var viewWidth = 710,viewHeight//设定一个初始宽度
 //当它的宽度大于初始宽度时,实际效果跟mode=widthFix一致
 if(originWidth>= viewWidth){
 //宽度等于viewWidth,只需要求出高度就能实现自适应
 viewHeight = viewWidth/ratio;
 }else{
 //如果宽度小于初始值,这时就不要缩放了
 viewWidth = originWidth;
 viewHeight = originHeight;
 }
 var imageSize = this.data.imageSize;
 imageSize[e.target.dataset.index] = {
 width:viewWidth,
 height:viewHeight
 }
 this.setData({
 imageSize:imageSize
 })
 }
})

如果我们的图片中不仅限定了宽度,还限定了高度值,比如我们限定max-height之类的。那我们的imageLoad函数则要调整为根据他们的宽高比来输出。

imageLoad:function(e){
 var originWidth = e.detail.width * px2rpx,
 originHeight=e.detail.height *px2rpx,
 ratio = originWidth/originHeight ;
 var viewWidth = 220,viewHeight = 165, viewRatio = viewWidth/viewHeight;
 if(ratio>=viewRatio){
 if(originWidth>=viewWidth){
 viewHeight = viewWidth/ratio;
 }else{
 viewWidth = originWidth;
 viewHeight = originHeight
 }
 }else{
 if(originWidth>=viewWidth){
 viewWidth = viewRatio*originHeight
 }else{
 viewWidth = viewRatio*originWidth;
 viewHeight = viewRatio*originHeight;
 }
 }
 var image = this.data.imageSize;
 image[e.target.dataset.index]={
 width:viewWidth,
 height:viewHeight
 }
 this.setData({
 imageSize:image
})
},

附录:小图预览,进入全屏模式。

用预览图片的API,wx.previewImage(OBJECT)以下是对应的代码,样式部分,自行布局。

html代码:

<view class="wrap">
 <image wx:for="{{pictures}}" wx:key="unique" src="{{item}}" data-index="{{index}}" bindtap="previewImage"></image>
</view>

JS

Page({
 data: {
 pictures: [
 'https://p0.meituan.net/movie/ea4ac75173a8273f3956e514a4c78018253143.jpeg',
 'https://p0.meituan.net/movie/5d4fa35c6d1215b5689257307c461dd2541448.jpeg',
 'https://p0.meituan.net/movie/0c49f98a93881b65b58c349eed219dba290900.jpg',
 'https://p1.meituan.net/movie/45f98822bd15082ae3932b6108b17a01265779.jpg',
 'https://p1.meituan.net/movie/722de9a7b0c1f9c262162d87eccaec7c451290.jpg',
 'https://p0.meituan.net/movie/cb9be5bbedb78ce2ef8e83c93f83caca474393.jpg',
 'https://p1.meituan.net/movie/a852b992cdec15319c717ba9fa9b7a35406466.jpg',
 'https://p1.meituan.net/movie/dc1f94811793e9c653170cba7b05bf3e484939.jpg'
 ]
 },
 previewImage: function(e){
 var that = this,
 index = e.currentTarget.dataset.index,
 pictures = this.data.pictures;
 wx.previewImage({
 current: pictures[index],
 urls: pictures
 })
 }
})

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
jQuery的实现原理的模拟代码 -3 事件处理
Aug 03 Javascript
Javascript 面向对象(一)(共有方法,私有方法,特权方法)
May 23 Javascript
Javascript变量的作用域和作用域链详解
Apr 02 Javascript
JavaScript学习总结之JS、AJAX应用
Jan 29 Javascript
JavaScript预解析及相关技巧分析
Apr 21 Javascript
详解AngularJS 路由 resolve用法
Apr 24 Javascript
微信小程序组件 marquee实例详解
Jun 23 Javascript
JS仿QQ好友列表展开、收缩功能(第二篇)
Jul 07 Javascript
jquery对table做排序操作的实例演示
Aug 10 jQuery
webpack4 升级迁移的实现
Sep 12 Javascript
vue-cli 打包使用history模式的后端配置实例
Sep 20 Javascript
在Vue.js中使用TypeScript的方法
Mar 19 Javascript
js遮罩效果制作弹出注册界面效果
Jan 25 #Javascript
assert()函数用法总结(推荐)
Jan 25 #Javascript
canvas知识总结
Jan 25 #Javascript
基于JavaScript实现自定义滚动条
Jan 25 #Javascript
基于javascript实现数字英文验证码
Jan 25 #Javascript
js阻止移动端页面滚动的两种方法
Jan 25 #Javascript
servlet+jquery实现文件上传进度条示例代码
Jan 25 #Javascript
You might like
dedecms系统的广告设置代码 基础版本
2010/04/09 PHP
php中的常用魔术方法总结
2013/08/02 PHP
PHP临时文件的安全性分析
2014/07/04 PHP
PHP利用APC模块实现文件上传进度条的方法
2015/01/26 PHP
php内嵌函数用法实例
2015/03/20 PHP
php实现的pdo公共类定义与用法示例
2017/07/19 PHP
js生成动态表格并为每个单元格添加单击事件的方法
2014/04/14 Javascript
使用Node.js给图片加水印的方法
2016/11/15 Javascript
实例解析Array和String方法
2016/12/14 Javascript
jquery自定义插件结合baiduTemplate.js实现异步刷新(附源码)
2016/12/22 Javascript
纯原生js实现贪吃蛇游戏
2020/04/16 Javascript
VUE利用vuex模拟实现新闻点赞功能实例
2017/06/28 Javascript
详解vue 模拟后台数据(加载本地json文件)调试
2017/08/25 Javascript
node.js文件上传重命名以及移动位置的示例代码
2018/01/19 Javascript
JavaScript中利用Array filter() 方法压缩稀疏数组
2018/02/24 Javascript
取消Bootstrap的dropdown-menu点击默认关闭事件方法
2018/08/10 Javascript
vue倒计时刷新页面不会从头开始的解决方法
2020/03/03 Javascript
[02:05]2014DOTA2西雅图国际邀请赛 BBC第二天小组赛总结
2014/07/11 DOTA
[40:55]DOTA2上海特级锦标赛主赛事日 - 2 败者组第二轮#4Newbee VS Fnatic
2016/03/03 DOTA
python 生成目录树及显示文件大小的代码
2009/07/23 Python
详解Django中Request对象的相关用法
2015/07/17 Python
django框架如何集成celery进行开发
2017/05/24 Python
Python求两个圆的交点坐标或三个圆的交点坐标方法
2018/11/07 Python
python实现定时发送qq消息
2019/01/18 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
Python bytes string相互转换过程解析
2020/03/05 Python
Python通过socketserver处理多个链接
2020/03/18 Python
基于python实现FTP文件上传与下载操作(ftp&amp;sftp协议)
2020/04/01 Python
如何在Python对Excel进行读取
2020/06/04 Python
python+selenium自动化实战携带cookies模拟登陆微博
2021/01/19 Python
让IE可以变相支持CSS3选择器
2010/01/21 HTML / CSS
英国手工布艺沙发在线购买:Sofas & Stuff
2018/03/02 全球购物
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
大学新生军训方案
2014/05/03 职场文书
2015年新农村建设工作总结
2015/05/22 职场文书
详解Python为什么不用设计模式
2021/06/24 Python