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


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 相关文章推荐
Prototype Array对象 学习
Jul 19 Javascript
JavaScript中valueOf函数与toString方法深入理解
Dec 02 Javascript
js中array的sort()方法使用介绍
Feb 20 Javascript
JS实现动态给图片添加边框的方法
Apr 01 Javascript
JavaScript数组的一些奇葩行为
Jan 25 Javascript
谈一谈jQuery核心架构设计
Mar 28 Javascript
JS填写银行卡号每隔4位数字加一个空格
Dec 19 Javascript
JS打开摄像头并截图上传示例
Feb 18 Javascript
weui框架实现上传、预览和删除图片功能代码
Aug 24 Javascript
vue 国际化 vue-i18n 双语言 语言包
Jun 07 Javascript
JavaScript设计模式之构造函数模式实例教程
Jul 02 Javascript
JavaScript动态添加数据到表单并提交的几种方式
Jun 26 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
PHP应用JSON技巧讲解
2013/02/03 PHP
php+xml编程之xpath的应用实例
2015/01/24 PHP
php微信公众平台开发类实例
2015/04/01 PHP
摘自织梦CMS的HTTP文件下载类
2015/08/08 PHP
php析构函数的简单使用说明
2015/08/24 PHP
php实现的递归提成方案实例
2015/11/14 PHP
基于PHP实现商品成交时发送短信功能
2016/05/11 PHP
JavaScript 特殊字符
2007/04/05 Javascript
FireFox中textNode分片的问题
2007/04/10 Javascript
js捕获鼠标右键菜单中的粘帖事件实现代码
2013/04/01 Javascript
jQuery中bind与live的用法及区别小结
2014/01/27 Javascript
Jquery利用mouseenter和mouseleave实现鼠标经过弹出层且可以点击
2014/02/12 Javascript
jquery.Ajax()方法调用Asp.Net后台的方法解析
2014/02/13 Javascript
浅谈jquery点击label触发2次的问题
2016/06/12 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
从零开始学习Node.js系列教程三:图片上传和显示方法示例
2017/04/13 Javascript
浅谈webpack编译vue项目生成的代码探索
2017/12/11 Javascript
微信小程序中的店铺评分组件及vue中用svg实现的评分显示组件
2018/11/16 Javascript
vue-loader中引入模板预处理器的实现
2019/09/04 Javascript
Vue调用后端java接口的实例代码
2019/10/28 Javascript
微信小程序实现音乐播放器
2019/11/20 Javascript
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
2021/02/15 Javascript
[01:30:55]VG vs Mineski Supermajor 败者组 BO3 第三场 6.6
2018/06/07 DOTA
pandas 使用apply同时处理两列数据的方法
2018/04/20 Python
如何使用Python自动生成报表并以邮件发送
2020/10/15 Python
解决HTML5手机端页面缩放的问题
2017/10/27 HTML / CSS
JD Sports芬兰:英国领先的运动鞋和运动服饰零售商
2018/11/16 全球购物
Opodo意大利:欧洲市场上领先的在线旅行社
2019/10/24 全球购物
线程问题:wait()方法是定义在哪个类里面
2015/07/07 面试题
网吧消防安全制度
2014/01/28 职场文书
影子教师研修方案
2014/06/14 职场文书
经营理念口号
2014/06/21 职场文书
公司2014年度工作总结
2014/12/10 职场文书
社区活动总结
2015/02/04 职场文书
童年读书笔记
2015/06/26 职场文书
会计继续教育培训心得体会
2016/01/19 职场文书