前言

一个月前还是用vue做微信H5,后面公司业务发展,入坑小程序,做了几款小程,跑了不少坑, 也会陆续在后面几节跟大家分享。
在这节给大家分享这个 小程序图片轮播实现方案

初步的实现思路

我要实现的效果

能看到 左右两边如果有图,会显示一部分出来,本来也想用 小程序自带的swiper 组件,无法达到,左右两边 看到上(下)图片的效果,无法改变他组件原来的设置(坑)

在开始之前,先想想h5是怎么实现的,用原生写,可以在某个固定框的盒子里,再用一个div 包住 x 张图,然后改变 ontouchmove 时改变 left(或者translateX) ,判断用户手指滑动足够距离,就滑到下(上)一张,
最后判断到最后一张或者第一张,不滑动就好(在这里不做无缝滚动)。
jquery,vue 很多库都能够实现

我们只要 实现了第一张图的滑动,记录这个偏移量 tranX1 = 0 + offsetX, 第二张的滑动距离 tranX2 = tranX1 + offsetX ,第三张的滑动距离 tranX3 = tranX2 + offsetX ...
相反方向 也就 递减 tranX1 = tranX2 - offsetX ...
然后判断临界值就OK了
了解了大概的滑动过程现在就可以掀起袖子干了~

具体技术实现

写了个 swiper 的方法,用原形链继承的方式,与小程序的page({})里面代码尽量分开, 用惯了Vue的双向绑定,特别讨厌小程序的 this.setData 而且是异步的(坑),this有时候要用变量保留,
先定义了几个变量,初始化一些必要参数,
记录 touch 过程中 滑动开始的坐标,滑动过程中,和滑动结束时的坐标,

构造 swiper 函数里面

opt 配置
swiperIndex 用于记录 滑动到的图片索引,默认值为0
singleOffsetX 滑一张的tranX 偏移量
boxTranslateX 盒子容器总偏移量 默认0
_x_start (单位px)记录touchstart里的e.touchs[0].pageX
_y_start (单位px)记录touchstart里的e.touchs[0].pageY
_x_move (单位px)记录touchsmove里的e.touchs[0].pageX
_x_offset 临时变量,记住 _x_move-_x_start 手指移动距离
_x_end (单位px)记录touchend里的 e.changedTouches[0].pageX
_x_realOffset (单位px)临时变量,根据临界值 图片真实移动
screenWidth = 750 屏幕宽度默认 iphone6 750rpx
screenHeight = 1210 屏幕高度默认 iphone6 1210rpx
pixelRatio 根据微信api里 systemInfo设备屏幕宽度 计算比例
maxTranX 根据图片的数量计算最大偏移量,用于临界判断
width 盒子的总宽度(用于view 上面绑定 单位:rpx )根据图片数量计算盒子的总宽度 = 首末两边(100)x 2+ 图片与图片之间的间距(60)* (图片数量 -1)+ 图片宽度 x 图片数量

(this.width = 100 2 + (this.opt.imgLength - 1) 60 + 550 * this.opt.imgLength)

然后执行函数 computedScreenRatio 根据宽转换比例

代码如下

'use strict';
var swiper = function(opt){
// 保存设置
this.opt =opt
// 当前 移动块停留索引
this.swiperIndex = 0
// 盒子容器总偏移量
this.boxTranslateX = 0
// 每移动一张图会增加的偏移量
this.singleOffsetX = -610
// 触摸
this._x_start = 0
this._y_start = 0
// 移动
this._x_move = 0
// 离开
this._x_end = 0
// 偏移量
this._x_offset = 0
// move 过程中真实偏移
this._x_realOffset = 0 this.screenWidth = 750
this.screenHeight = 1210
this.pixelRatio = 2
// rpx
this.maxTranX = this.singleOffsetX * (this.opt.imgLength -1 )
// 容器宽度 width 100 是两边靠墙
this.width = 100 * 2 + (this.opt.imgLength - 1) *60 + 550 * this.opt.imgLength // 计算宽转换比例
this.computedScreenRatio(opt.systemInfo)
}

rpx(responsive pixel): 可以根据屏幕宽度进行自适应。规定屏幕宽为750rpx。如在 iPhone6

上,屏幕宽度为375px,共有750个物理像素,则750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。

iphone6 1rpx = 0.5px , iphone5 1rpx = 0.42px 根据宽度做兼容

// 计算宽转换比例
swiper.prototype.computedScreenRatio = function (systemInfo){
this.pixelRatio = systemInfo.pixelRatio
this.screenWidth = systemInfo.screenWidth
this.screenHeight = systemInfo.screenHeight
//this.singleOffsetX = -610
// 奇怪的i5 按照算法会 多偏移2 px
if (systemInfo.model.indexOf('iPhone 5') > -1 ){
this.singleOffsetX = -(610 * (this.screenWidth / 750) -2 ).toFixed()
}
else{
this.singleOffsetX = -610 * (this.screenWidth / 750)
}
this.maxTranX = this.singleOffsetX * (this.opt.imgLength - 1)
// 回调绑定vm ,渲染盒子宽度
this.opt.success && this.opt.success(this.width)
}

扯一下小程序

  • bindtouchstart : ontouchstart
  • bindtouchmove: ontouchmve
  • bindtouchend : ontouchend 一样是有e.touches e.changedTouches

下面是从滑动开始到结束的处理过程代码分析

keepStartX(touchstart): 记录开始状态 比较简单就不讲了

moveBox (touchend)是一个手指滑动,所有图片(盒子)跟着手指滑动的过程

  • 1.手指向右滑,_x_offset > 0 ,滑向上一张图
  • 2.手指向左滑,_x_offset < 0 ,滑向下一张图
  • 按逻辑来说,手指水平方向上pageX 的距离, 图片盒子就应该跟着向(左)或者向右偏移一样的量, 但是 从最后一张 开始 向左滑,后面已经没有图了,(或者 从第一张图开始已经向右滑,前面已经没有图了 ),这时候就要做临界值判断了,结果就有手指滑动距离 _x_offset ,还有盒子滑动应该滑的准确距离 lastTranX

touchEnd

computedTranX:

  • 根据 滑动方向,临界值 计算出 手指滑动时,盒子的应该滑动的方向与距离 tranX (注: 这里tranX 从第一张开始是0 ,偏移量是负数,所以_x_realOffset永远是 <0 )

计算最后手指离开的坐标,_x_realOffset用来保存计算 真实的在x方向上的距离R

// bindtouchstart
swiper.prototype.keepStartX = function(e, callback){
this._x_start = e.touches[0].pageX
this._y_start = e.touches[0].pageY
callback && callback()
}
// bindtouchmove
/*
函数说明 moveBox
@params e 事件
@params {function} callback 图片盒子的偏移量改变,绑定到vm 上面,视图发生变化
*/
swiper.prototype.moveBox = function (e, callback) {
this._x_move = e.touches[0].pageX
this._x_offset = this._x_move - this._x_start
var lastTranX = this.computedTranX(this._x_offset)
this._x_realOffset = lastTranX
callback && callback(lastTranX)
}
/*
函数说明 根剧移动偏移量临界值计算出真实位移用
滑下一张 判断是否超出临界值,超出则等于临界值
若不超过则偏移量 = 手指(touch)移动距离 + 当前盒子偏移量
*/
swiper.prototype.computedTranX = function ( offsetX ){
// 滑向上一张
if( offsetX > 0 ){
return offsetX + this.boxTranslateX
}
// 滑动下一张
else if (offsetX < 0 ){
if ( Math.abs(offsetX - this.boxTranslateX) > Math.abs(this.maxTranX - 50) ){
return this.maxTranX
}else{
return offsetX + this.boxTranslateX
}
}
} // bindtouchend
swiper.prototype.ontouchEnd = function(e, callback){ // 记录手指离开屏幕的坐标
this._x_end = e.changedTouches[0].pageX
this._x_realOffset = this._x_end - this._x_start
// 判断滑动距离超过 指定值 轮播一张图
var canExchangeImgFromOffset = Math.abs(this._x_realOffset) >= 50 ? true : false
// 滑动距离达到 换图的要求
if ( canExchangeImgFromOffset ){
// 变量说明 计算总偏移
var lastTotalTranlateX ;
// 滑向上一张
if (this._x_offset > 0) {
console.log('// 滑向上一张')
// 判断是否已经在第一张图,若不是,则滑动上一张
if (Math.abs(this.boxTranslateX) > 0) {
// lastTotalTranlateX 递增
// this.singleOffsetX 为负数 -- 得 +
this.swiperIndex -= 1
lastTotalTranlateX = this.boxTranslateX - this.singleOffsetX
}
else {
// 已在第一张图 ,动画恢复原位
this.swiperIndex = 0
lastTotalTranlateX = 0
}
}
// 滑向下一张
else {
console.log('// 滑向下一张')
if ( Math.abs(this.boxTranslateX) < Math.abs(this.maxTranX) ) {
// lastTotalTranlateX 递增
this.swiperIndex += 1
lastTotalTranlateX = this.boxTranslateX + this.singleOffsetX
} else {
console.log('到底图了')
this.swiperIndex = this.opt.imgLength -1
lastTotalTranlateX = this.maxTranX
}
}
this.boxTranslateX = lastTotalTranlateX
/* callback 说明
@参数1 是否执行动画
@参数2 若参数1为true, 则盒子的tranX 应该变成 lastTotalTranlateX,动画飞到对应的图
小程序 执行 wx.createAnimation
*/
callback && callback(true, lastTotalTranlateX)
// reset 所有 与touch 相关参数
this.resetParams()
}
else{
callback && callback(false)
// reset 所有 与touch 相关参数
this.resetParams()
}
}
源码地址 https://gitee.com/adfasdfasdfas/XiaoChengXu-swiper-LunBodemo

本文转载于:猿2048⇒https://www.mk2048.com/blog/blog.php?id=h0i2cbh0cib

小程序图片轮播特效swiper(纯手打)的更多相关文章

  1. 微信小程序的轮播图swiper问题

    微信小程序的轮播图swiper,调用后,怎样覆盖系统的 点,达到自己想要的效果 不多说,先上一图望大家多给意见: 这个是效果图: 微信小程序效果图就成这样子: <view class=" ...

  2. 原生js和jquery实现图片轮播特效

    本文给大家分享的是使用原生JS和JQ两种方法分别实现相同的图片轮播特效,十分的实用,也非常方便大家对比学习原生js和jQuery,有需要的小伙伴可以参考下. 1)首先是页面的结构部分对于我这种左右切换 ...

  3. 原生js和jquery实现图片轮播特效(转)

    本文给大家分享的是使用原生JS和JQ两种方法分别实现相同的图片轮播特效,十分的实用,也非常方便大家对比学习原生js和jQuery,有需要的小伙伴可以参考下. 1)首先是页面的结构部分对于我这种左右切换 ...

  4. 微信小程序3D轮播图

    <!-- 轮播图 --> <swiper previous-margin='50px' next-margin='50px' bindchange="swiperChang ...

  5. 【自定义轮播图】微信小程序自定义轮播图无缝滚动

    先试试效果,可以通过设置参数调整样式 微信小程序中的轮播图可以直接使用swiper组件,如下: <swiper indicator-dots="{{indicatorDots}}&qu ...

  6. 微信小程序 - 3d轮播图组件(基础)

    <!-- 目前仅支持data数据源来自banner,请看测试案例 ################ 以上三种形式轮播: 1. basic 2. 3d 3. book basic即普通轮播 3d即 ...

  7. jQuery图片轮播特效

    效果预览:http://hovertree.com/texiao/jquery/51/ 这款特效有缩略图,包含文字说明和链接,可以自动播放,也可以手动切换. 使用的jQuery库版本为1.12.3 , ...

  8. 微信小程序--图片相关问题合辑

    图片上传相关文章 微信小程序多张图片上传功能 微信小程序开发(二)图片上传 微信小程序上传一或多张图片 微信小程序实现选择图片九宫格带预览 ETL:微信小程序之图片上传 微信小程序wx.preview ...

  9. 基于jQuery带进度条全屏图片轮播代码

    基于jQuery带进度条全屏图片轮播代码.这是一款基于jQuery实现的oppo手机官网首页带进度条全屏图片轮播特效.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div ...

随机推荐

  1. net core or Linux

    某用户执行net core sdk 版本不生效 sudo chmod +x /home/username/netcore3.1sdk/dotnet //某个用户执行新版本net core sdk

  2. Windows原理深入学习系列-访问控制列表-关于安全描述符的补充

    这是[信安成长计划]的第 20 篇文章 0x00 目录 0x01 安全描述符的结构 0x02 两个结构的不同点 0x03 真正的查询方案 0x04 参考文章 0x01 安全描述符的结构 在上一篇文章中 ...

  3. Jmeter---压力模式

    需求 下面有3个场景,思考一下在jmeter里面如何设计 场景1:有一个项目,500用户同时登录,响应时间能达到多少场景2:考勤打卡,最大吞吐量能达到多少(每秒最大能完成多少笔打卡业务)场景3:银行业 ...

  4. application.properties文件常用配置

    项目一直在用properties文件写配置,因为配置不是自己来写所以也从来没有研究过各个配置的含义,所以对很多配置也是一知半解,只是知道可以这样用,但是不知道为什么能这样用.自己抽空找了一下资料做个记 ...

  5. MySQL从卸载到安装!图文详细版(你想知道的全都有!!)

    2. MySQL的下载.安装.配置 2.1 MySQL的四大版本 MySQL Community Server社区版本,开源免费,自由下载,但不提供官方技术支持,适用于大多数普通用户. MySQL E ...

  6. MySQL配置主从分离

    主服务器 192.168.176.110 从服务器 192.168.176.120 主数据库操作(ip:192.168.176.110)  配置MySQL主服务器的配置文件 [root@localho ...

  7. 微服务8:通信之RPC实践篇(附源码)

    ★微服务系列 微服务1:微服务及其演进史 微服务2:微服务全景架构 微服务3:微服务拆分策略 微服务4:服务注册与发现 微服务5:服务注册与发现(实践篇) 微服务6:通信之网关 微服务7:通信之RPC ...

  8. JS 邮箱的验证(正则)

    /^([a-zA-Z\d])(\w|\-)+@[a-zA-Z\d]+\.[a-zA-Z]{2,4}$/

  9. SINAMICS S120的核心控制单元CU320使用教程,电机模块接线

    SINAMICS是西门子公司新一代的驱动产品,它正在逐步取代现有的MASTERDRIVES及SIMODRIVE系列的驱动系统.SINAMICS S120是集V/f控制.矢量控制和伺服控制于一体的多轴驱 ...

  10. 百度Paddle速查_CPU和GPU的mnist预测训练_模型导出_模型导入再预测_导出onnx并预测

    需要做点什么 方便广大烟酒生研究生.人工智障炼丹师算法工程师快速使用百度PaddelPaddle,所以特写此文章,默认使用者已有基本的深度学习概念.数据集概念. 系统环境 python 3.7.4 p ...