Commit 3f5cb448 吴良建

第一次提交

0 个父辈
正在显示 186 个修改的文件 包含 14223 行增加0 行删除
node_modules/
unpackage/
dist/**
package/android/HBuilder-Integrate-AS/simpleDemo/src/main/assets/apps/**
package/android/HBuilder-Integrate-AS/simpleDemo/release/**
.project
.DS_Store
.hbuilderx/
.vite/
<script>
import common from '@/utils/common.js'
import http from '@/utils/http.js'
import app_config from '@/utils/app.js'
import loginHelper from '@/utils/loginHelper.js'
import {
transformImageCodeToUri
} from "@/utils/image_utils.js";
export default {
data() {
return {
common,
timer: null
}
},
onLaunch: async function() {
console.log('App Launch')
// #ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary") //关闭横屏
var code = common.getChannelCode();
app_config.app_info.PromoterId = code;
console.log(app_config.app_info.PromoterId);
// #endif
//获取导航栏高度
uni.getSystemInfo({
success: (e) => {
// #ifdef APP-PLUS
if (e.statusBarHeight === 0) {
common.statusBarH = 33
} else {
common.statusBarH = e.statusBarHeight
}
// #endif
// #ifdef H5
common.statusBarH = 10
// #endif
// #ifdef MP-WEIXIN
common.statusBarH = e.statusBarHeight + 20
// #endif
// if (e.platform === 'android' || e.platform === 'ios') {
// common.customBarH = e.statusBarHeight + 55
// } else {
// common.customBarH = e.statusBarHeight + 50
// }
}
})
//获取配置
// let local_ic = await uni.getStorageSync('info_config_key')
// if (local_ic.length > 0) {
// common.info_config = JSON.parse(local_ic)
// }
// console.debug('---0000------', common.info_config)
// let ic_res = await http.gql({
// query: 'query{info_config}'
// })
// let info_config = ic_res.data.info_config
// if (info_config) {
// common.info_config = info_config
// await uni.setStorageSync('info_config_key', JSON.stringify(info_config))
// console.log(common.info_config);
// } else {
// console.debug('---获取后台配置失败---')
// }
},
onShow: function() {
console.log('App Show')
// 检查当前上网环境
uni.getNetworkType({
complete: function(res) {
if (res.networkType == "none") {
setTimeout(() => {
uni.showToast({
icon: "none",
title: "网络异常,请检查网络设置!",
duration: 2000,
position: "bottom",
});
}, 200);
}
},
});
this.antoLogin();
this.timer = setInterval(this.antoLogin, 9 * 60 * 1000)
},
onHide: function() {
console.log('App Hide')
clearInterval(this.timer)
},
methods: {
async antoLogin() {
var appToken = loginHelper.getAppToken() || ""
console.log("antoLogin " + JSON.stringify(appToken))
if (appToken) {
var mac_code = uni.getSystemInfoSync().deviceId
var time = new Date().getTime() + ""
let query_data = `mutation{
ydn_auto_login(token:${JSON.stringify(appToken)},mac_code:${JSON.stringify(mac_code)},t:${JSON.stringify(time)})
}`;
console.log(query_data)
let result = await http.gql({
query: query_data
})
console.log(result)
if (result && result.data && result.data.ydn_auto_login) {
if (!result.data.ydn_auto_login.Error) {
result.data.ydn_auto_login.Result.FaceImageCode = transformImageCodeToUri(result.data
.ydn_auto_login.Result
.FaceImageCode);
loginHelper.login(result.data.ydn_auto_login
.Result,result.data.ydn_auto_login.AppToken)
} else {
loginHelper.logout()
}
}
} else {
loginHelper.logout()
}
}
}
}
</script>
<style>
/*每个页面公共css */
</style>
<template>
<view>
<!-- <web-view :src="url" fullscreen='false'></web-view> -->
</view>
</template>
<script>
import {
default as app_config
} from '@/utils/app.js';
import common from '@/utils/common.js'
import loginHelper from '../utils/loginHelper.js'
var wv; //计划创建的webview
var nwating;
export default {
name: "customWebview",
data() {
return {
url: this.src
};
},
props: {
src: {
type: String,
default: () => ""
},
top: {
type: Number,
default: () => 0
},
height: {
type: Number,
default: () => uni.getSystemInfoSync().windowHeight
}
},
created() {
uni.$on("loginStatus", function(arg) {
if(arg) {
wv.reload()
console.log("loginStatus:" + arg)
}
})
let appInfo = app_config.app_info;
let header = {
AppVersion: encodeURI(JSON.stringify(appInfo))
}
// #ifdef APP-PLUS
nwating = plus.nativeUI.showWaiting();
wv = plus.webview.create("", "normal_h5-webview", {
additionalHttpHeaders: {
header: header,
},
plusrequire: "none", //禁止远程网页使用plus的API,有些使用mui制作的网页可能会监听plus.key,造成关闭页面混乱,可以通过这种方式禁止
'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
top: this.top,
height: this.height
})
let pages = getCurrentPages()
let currentPage = pages[pages.length - 1]
var currentWebview = currentPage.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
currentWebview.append(wv);
console.log(header)
wv.loadURL(this.url, header);
wv.addEventListener('loaded', function () {
// wv.evalJS("$(\".header\").hide();");
console.log("load---")
nwating.close();
wv.show();
}, false);
var _this = this;
wv.overrideUrlLoading({
effect: "touchstart",
mode: "allow",
match: "^https:\/\/app\.ydniu\.com\/experts\/(kl8|sd|pl3|ssq|dlt|pl5|zq)\?zqe&app_header=true$"
// exclude: "redirect"
}, (e) => {
console.log('----请求拦截了------', e.url + "--" + _this.url)
if (e.url === _this.url) {
console.log("reload")
wv.reload();
} else if (e.url.indexOf("login") !== -1) {
// 前端检测到未登录,需要登录,说明当前登录信息已经失效,清除登录信息
loginHelper.logout()
console.log('-------拦截请求login', e.url)
uni.navigateTo({
url: `/pages/login_pwd/login_pwd`
})
} else if ((e.url.indexOf("?zq") !== -1 || e.url.indexOf("user/payment") !== -1) && e.url
.startsWith("http")) {
console.log('-------拦截请求?zq', e.url)
let tempData = {
url: e.url
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else if (e.url.indexOf("?ydn_back") !== -1 ||
e.url === 'https://app.ydniu.com/' ||
e.url === 'https://app.ydniu.com' ||
e.url === 'https://app.ydniu.com/sports' ||
e.url.startsWith("https://app.ydniu.com/?")) {
console.log('-------拦截请求ydn_back', e.url)
uni.navigateBack({})
} else if (e.url.startsWith("weixin") || e.url.startsWith("alipay")) {
console.log('-------拦截请求weixin', e.url)
plus.runtime.openURL(e.url, err => {
uni.showToast({
title: '打开失败!请检查是否已安装',
icon: 'none'
});
});
} else if (e.url.startsWith("ydncp")) {
var urlStr = e.url.substring("ydncp:".length, e.url.length);
let tempData = {
url: e.url,
}
uni.navigateTo({
url:'/pages/notitle_webview/notitle_webview'
})
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
console.log('-------拦截请求tempData', e.url)
let tempData = {
url: e.url,
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
}
console.log('----请求拦截了End------', e.url)
})
// #endif
},
mounted() {
},
methods: {
onRefreshInfo(data) {
console.log(data)
this.url = data
nwating = plus.nativeUI.showWaiting();
wv.loadURL(this.url)
}
}
}
</script>
<style>
</style>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<script>
var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
CSS.supports('top: constant(a)'))
document.write(
'<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
(coverSupport ? ', viewport-fit=cover' : '') + '" />')
</script>
<title></title>
<!--preload-links-->
<!--app-context-->
</head>
<body>
<div id="app"><!--app-html--></div>
<script type="module" src="/main.js"></script>
</body>
</html>
import App from './App'
// #ifndef VUE3
import Vue from 'vue'
Vue.config.productionTip = false
App.mpType = 'app'
try {
function isPromise(obj) {
return (
!!obj &&
(typeof obj === "object" || typeof obj === "function") &&
typeof obj.then === "function"
);
}
// 统一 vue2 API Promise 化返回格式与 vue3 保持一致
uni.addInterceptor({
returnValue(res) {
if (!isPromise(res)) {
return res;
}
return new Promise((resolve, reject) => {
res.then((res) => {
if (res[0]) {
reject(res[0]);
} else {
resolve(res[1]);
}
});
});
},
});
} catch (error) { }
const app = new Vue({
...App
})
app.$mount()
// #endif
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
return {
app
}
}
// #endif
\ No newline at end of file
{
"name" : "ydnApp",
"appid" : "__UNI__B008CD1",
"description" : "一定牛",
"versionName" : "1.0.0",
"versionCode" : "100",
"transformPx" : false,
/* 5+App特有相关 */
"app-plus" : {
"usingComponents" : true,
"nvueStyleCompiler" : "uni-app",
"compilerVersion" : 3,
"splashscreen" : {
"alwaysShowBeforeRender" : true,
"waiting" : true,
"autoclose" : true,
"delay" : 0
},
/* 模块配置 */
"modules" : {},
/* 应用发布信息 */
"distribute" : {
/* android打包配置 */
"android" : {
"permissions" : [
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
"<uses-feature android:name=\"android.hardware.camera\"/>",
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
]
},
/* ios打包配置 */
"ios" : {},
/* SDK配置 */
"sdkConfigs" : {}
}
},
/* 快应用特有相关 */
"quickapp" : {},
/* 小程序特有相关 */
"mp-weixin" : {
"appid" : "",
"setting" : {
"urlCheck" : false
},
"usingComponents" : true
},
"mp-alipay" : {
"usingComponents" : true
},
"mp-baidu" : {
"usingComponents" : true
},
"mp-toutiao" : {
"usingComponents" : true
},
"uniStatistics" : {
"enable" : false
},
"vueVersion" : "2"
}
{
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "首页",
"enablePullDownRefresh": false
}
}, {
"path": "pages/mine/mine",
"style": {
"navigationBarTitleText": "我的",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}, {
"path": "pages/open/open",
"style": {
"navigationBarTitleText": "开奖",
"enablePullDownRefresh": false
}
}, {
"path": "pages/expert/expert",
"style": {
"navigationBarTitleText": "专家",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
},
{
"path": "pages/notitle_webview/notitle_webview",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}, {
"path": "pages/normal_webview/normal_webview",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
},
{
"path": "pages/logout/logout",
"style": {
"navigationBarTitleText": "账号注销",
"enablePullDownRefresh": false,
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#FFFFFF"
}
},
{
"path": "pages/login_pwd/login_pwd",
"style": {
"navigationBarTitleText": "账号登录",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}, {
"path": "pages/login_yzm/login_yzm",
"style": {
"navigationBarTitleText": "验证码登录",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
,{
"path" : "pages/settings/settings",
"style" :
{
"navigationBarTitleText": "设置",
"enablePullDownRefresh": false,
"backgroundColor": "#000000"
}
}
,{
"path" : "pages/xingqu/xingqu",
"style" :
{
"navigationBarTitleText": "选择感兴趣的内容",
"enablePullDownRefresh": false,
"navigationStyle": "custom",
"backgroundColor": "#F5F5F5"
}
}
,{
"path" : "pages/suggest/suggest",
"style" :
{
"navigationBarTitleText": "提建议",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
,{
"path" : "pages/security_center/security_center",
"style" :
{
"navigationBarTitleText": "安全中心",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
,{
"path" : "pages/number_book/number_book",
"style" :
{
"navigationBarTitleText": "号码本",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/bind_card/bind_card",
"style" :
{
"navigationBarTitleText": "",
"enablePullDownRefresh": false,
"navigationStyle": "custom"
}
}
],
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "一定牛",
"navigationBarBackgroundColor": "#F8F8F8",
"backgroundColor": "#F8F8F8"
},
"tabBar": {
"backgroundColor": "#F8F8F8",
"selectedColor": "#0a1b31",
"color": "#999999",
"list": [{
"text": "首页",
"iconPath": "static/tab_icons/bottom_home_normal.webp",
"selectedIconPath": "static/tab_icons/bottom_home_press.webp",
"pagePath": "pages/index/index"
},
{
"text": "开奖",
"iconPath": "static/tab_icons/bottom_open_normal.webp",
"selectedIconPath": "static/tab_icons/bottom_open_press.webp",
"pagePath": "pages/open/open"
},
{
"text": "专家",
"iconPath": "static/tab_icons/bottom_talk_normal.webp",
"selectedIconPath": "static/tab_icons/bottom_talk_press.webp",
"pagePath": "pages/expert/expert"
},
{
"text": "我的",
"iconPath": "static/tab_icons/bottom_user_normal.webp",
"selectedIconPath": "static/tab_icons/bottom_user_press.webp",
"pagePath": "pages/mine/mine"
}
]
},
"uniIdRouter": {}
}
<template>
<view style="background-color: #f5f5f5; height: 100vh;">
<view class="title_bg" :style="'padding-top:' + (common.statusBarH + 10)+ 'px; '">
<image style="width: 40rpx; height: 40rpx;" src='../../static/common/icon_back.png' @click="onBack()">
</image>
<text style="color: white; font-size: 36rpx; font-weight: 700; margin-left: 15rpx;">绑定身份证</text>
<image style="width: 40rpx; height: 40rpx;">
</image>
</view>
<view :style="'height: ' + titleHeight + 'px'"></view>
<view style="font-size: 32rpx; color: #393939; padding: 20rpx; margin-bottom: 3rpx; background-color: white;">
<text>用于实名认证,修改个人信息.非常非常重要。</text>
</view>
<view class="item">
<text class="text1">&nbsp;&nbsp;&nbsp;名:</text>
<view class="input-class">
<input placeholder="请填写真实姓名"/>
</view>
</view>
<view class="item">
<text class="text1">身份证:</text>
<view class="input-class" >
<input type="idcard" :value="idCard" placeholder="请填写身份证号" />
</view>
</view>
<button :class="userInfo.IdCard ? 'un-button-class' : 'button-class'">{{userInfo.IdCard ? "无法修改" : "修改"}}</button>
</view>
</template>
<script>
import common from '@/utils/common.js'
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
titleHeight: 60,
common,
idCard: "",
userInfo: {}
}
},
onReady() {
var this_ = this
uni.createSelectorQuery()
.in(this)
.select('.title_bg')
.boundingClientRect((rect) => {
if (rect) {
this_.titleHeight = rect.height
console.log("rect.height:" + rect.height)
}
})
.exec();
this.userInfo = loginHelper.getUserInfo()
this.idCard = this.userInfo.IdCard
},
methods: {
}
}
</script>
<style>
.title_bg {
background: linear-gradient(90deg, #FF6F38 0%, #FFA04B 100%);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24rpx;
padding-right: 24rpx;
padding-bottom: 20rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
.item {
display: flex;
align-items: center;
padding: 20rpx;
background-color: white;
}
.text1 {
color: #393939;
font-size: 32rpx;
}
.input-class {
border: 2px solid #F39801;
border-radius: 6rpx;
background-color: white;
flex: 1;
padding: 15rpx;
}
.button-class {
margin: 30rpx;
background-color: #F39801;
}
.un-button-class {
margin: 30rpx;
background-color: #7a7a7a;
}
</style>
<template>
<view>
<view :style="'height:' + common.statusBarH + 'px;'"></view>
<v-tabs class="tab_c" v-model="current" :tabs="tabs" @change="changeTab" :fixed="true" line-height="8rpx"
line-color="#04764E" color="#AAAAAA" activeColor="#04764E" height="88rpx"></v-tabs>
<customWebview :src="tabsUrl[current]" :top="webview_top" :height="webview_height" ref="Webview">
</customWebview>
</z-swiper>
</view>
</template>
<script>
import customWebview from '../../components/customWebview.vue'
import common from '@/utils/common.js'
export default {
components: {
customWebview
},
data() {
return {
common,
tabs: ["快乐8", "福彩3D", "排列3", "双色球", "大乐透", "排列5", "足球"],
current: 0,
webview_top: 0,
webview_height: uni.getSystemInfoSync().windowHeight,
tabsUrl: [
'https://app.ydniu.com/experts/kl8?zqe&app_header=true',
'https://app.ydniu.com/experts/sd?zqe&app_header=true',
'https://app.ydniu.com/experts/pl3?zqe&app_header=true',
'https://app.ydniu.com/experts/ssq?zqe&app_header=true',
'https://app.ydniu.com/experts/dlt?zqe&app_header=true',
'https://app.ydniu.com/experts/pl5?zqe&app_header=true',
'https://app.ydniu.com/experts/zq?zqe&app_header=true'
]
}
},
onLoad() {
this.webview_top = 88
this.webview_height = uni.getSystemInfoSync().safeArea.bottom - this.webview_top
},
methods: {
changeTab(index) {
console.log('当前选中的项:' + index)
var ref = this.$refs.Webview
this.current = index
console.log(this.$refs.Webview)
ref.onRefreshInfo(this.tabsUrl[this.current])
}
}
}
</script>
<style>
.tab_c {
/* position: fixed; */
z-index: 999;
}
</style>
<template>
<view class="content">
<image class="logo" src="/static/logo.png"></image>
<view class="text-area">
<text class="title">{{title}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
title: 'Hello'
}
},
onLoad() {
},
methods: {
}
}
</script>
<style>
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
.text-area {
display: flex;
justify-content: center;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
</style>
<template>
<view>
<view class="head-bg" :style="{'padding-top': statusBarHeight +'px'}">
<view style="align-items: center; display: flex; width: 100v; height: 5vh;">
<image src="../../static/common/icon_back.png" style="width: 34rpx; height: 34rpx; padding: 25rpx;"
v-on:click="onBack()" />
<text style="margin-left: 10rpx; color: white; align-self: center; font-size: 40rpx;">账号密码登陆</text>
</view>
</view>
<view class="input-group" style="margin-left: 35rpx; margin-right: 35rpx;">
<view class="input-row border">
<input class="m-input" type="text" clearable focus v-model="username" placeholder="请输入用户名/手机号"
style="padding-top: 20rpx; padding-bottom: 20rpx;" />
<view style=" height: 1px; background: #C6C6C6; "></view>
</view>
<view class="input-row border" style="padding-top: 10rpx;">
<input type="password" displayable v-model="password" placeholder="请输入密码"
style="padding-top: 20rpx; padding-bottom: 20rpx;" />
<view style=" height: 1px; background: #C6C6C6; "></view>
</view>
</view>
<view style="margin-top: 15rpx; margin-left: 35rpx;" @click="gotoCodeLogin()">
<text style="color: #4169E1; font-size: 28rpx;">切换验证码登陆</text>
</view>
<view class="btn-row">
<button style="background-color: transparent; color: white; " :loading="loginBtnLoading" @tap="bindLogin">
登录
</button>
</view>
<view style=" margin-left: 35rpx; display: flex; margin-top: 35rpx; align-items: center;">
<view @click="checkboxSelected()" :checked="agreeState"
:class="agreeState === true ? 'checkbox-check' : 'checkbox-uncheck'" />
<text style="font-size: 28rpx; color: #333333;">阅读并同意</text>
<text style="color: #4d90ff; font-size: 28rpx;" @click="onUserAgreement()">用户协议</text>
<text style="font-size: 28rpx; color: #333333;"></text>
<text style="color: #4d90ff; font-size: 28rpx;" @click="onPrivacyPolicy()">隐私政策</text>
</view>
</view>
</template>
<script>
import {
transformImageCodeToUri
} from "@/utils/image_utils.js";
import {
default as http
} from "@/utils/http.js";
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
agreeState: false,
username: "",
password: "",
loginBtnLoading: false,
}
},
methods: {
async bindLogin() {
if (this.username.length < 3) {
uni.showToast({
icon: "none",
title: "账号最短为 3 个字符",
});
return;
}
if (this.password.length < 4) {
uni.showToast({
icon: "none",
title: "密码最短为 4 个字符",
});
return;
}
if (!this.agreeState) {
uni.showToast({
icon: "none",
title: "您还没有同意用户协议",
});
return;
}
this.loginBtnLoading = true;
let query_data = `mutation{
ydn_login(name:${JSON.stringify(this.username)},pass:${JSON.stringify(this.password)})
}`;
let result = await http.gql({
query: query_data
})
this.loginBtnLoading = false;
//处理返回请求
console.log("result:" + JSON.stringify(result))
if (result && result.data && result.data.ydn_login) {
if (!result.data.ydn_login.Error) {
result.data.ydn_login.Result.FaceImageCode = transformImageCodeToUri(result.data.ydn_login
.Result
.FaceImageCode);
loginHelper.login(result.data.ydn_login.Result , result.data.ydn_login.AppToken)
console.log("login")
uni.navigateBack();
return
} else {
uni.showToast({
icon: "none",
title: result.data.ydn_login.Error,
});
}
} else {
uni.showToast({
icon: "none",
title: "登录异常",
});
return;
}
},
onBack() {
uni.navigateBack()
},
gotoCodeLogin() {
uni.redirectTo({
url: '/pages/login_yzm/login_yzm'
})
},
checkboxSelected(e) {
this.agreeState = !this.agreeState;
},
onUserAgreement() {
let tempData = {
url: 'http://www.qianhaiyilan.cn/ppolicy_user.html',
title: "用户协议"
}
uni.navigateTo({
url: `/pages/normal_webview/normal_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
},
onPrivacyPolicy() {
let tempData = {
url: 'http://www.qianhaiyilan.cn/ppolicy_app.html',
title: "隐私政策"
}
uni.navigateTo({
url: `/pages/normal_webview/normal_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
}
}
}
</script>
<style>
</style>
<style>
.login-type-btn.act {
color: #ecab80;
border-bottom: solid 1px #ecab80;
}
.send-code-btn {
width: 120px;
text-align: center;
background-color: #ecab80;
color: #ffffff;
margin: 12px;
padding: 4px;
}
.action-row {
display: flex;
flex-direction: row;
justify-content: center;
margin-top: 15px;
}
.oauth-row {
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.oauth-image {
position: relative;
width: 50px;
height: 50px;
border: 1px solid #dddddd;
border-radius: 50px;
background-color: #ffffff;
}
.oauth-image image {
width: 30px;
height: 30px;
margin: 10px;
}
.oauth-image button {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
opacity: 0;
}
.btn-row {
margin-top: 15px;
margin-left: 35rpx;
margin-right: 35rpx;
background: linear-gradient(to right, #58B8FF, #32CDFF);
border-radius: 15rpx;
}
.head-bg {
flex-direction: column;
background: url('~@/static/login/head_zm.webp');
background-color: transparent;
background-repeat: no-repeat;
background-size: 50% 100%;
width: 100vh;
height: 15vh;
display: flex;
}
.uni-status-bar {
// width: 750rpx;
height: 20px;
// height: var(--status-bar-height);
}
.checkbox-check {
background-image: url(../../static/common/authsdk_checkbox_checked_bg.png);
background-repeat: no-repeat;
background-size: cover;
margin-right: 15rpx;
width: 35rpx;
height: 35rpx;
}
.checkbox-uncheck {
background-image: url(../../static/common/authsdk_checkbox_uncheck_bg.png);
width: 35rpx;
height: 35rpx;
margin-right: 15rpx;
background-repeat: no-repeat;
background-size: cover;
}
.m-input::input-placeholder {
color: #0000EE;
}
</style>
<template>
<view>
<view class="head-bg" :style="{'padding-top': statusBarHeight +'px'}">
<view style="align-items: center; display: flex; width: 100vh; height: 5vh;">
<image src="../../static/common/icon_back.png" style="width: 34rpx; height: 34rpx; padding: 25rpx;"
v-on:click="onBack()" />
<text style="margin-left: 10rpx; color: white; font-size: 40rpx;">验证码登陆</text>
</view>
</view>
<view class="input-group" style="margin-left: 35rpx; margin-right: 35rpx;">
<view class="input-row border">
<input class="m-input" type="text" clearable focus v-model="phoneNumber" placeholder="请输入手机号"
style="padding-top: 20rpx; padding-bottom: 20rpx;" />
<view style=" height: 1px; background: #C6C6C6; "></view>
</view>
<view class="input-row border" style=" display: flex; padding-top: 30rpx; padding-bottom: 20rpx;">
<input type="number" displayable v-model="phone_code" placeholder="请输入验证码" />
<button size="mini" style="background-color: #787878; font-size: 20; color: #FFFFFF; "
@click="getPhoneCode()" :disabled="disabled">{{phoneCodeStr}}</button>
</view>
<view style="height: 1px; background: #C6C6C6;"></view>
</view>
<view style="margin-top: 15rpx; margin-left: 35rpx;" @click="gotoAccountLogin()">
<text style="color: #4169E1; font-size: 28rpx;">切换密码登陆</text>
</view>
<view class="btn-row">
<button style="background-color: transparent; color: white; " :loading="loginBtnLoading" @tap="bindLogin">
登录
</button>
</view>
<view style=" margin-left: 35rpx; display: flex; margin-top: 35rpx; align-items: center;">
<view @click="checkboxSelected()" :checked="agreeState"
:class="agreeState === true ? 'checkbox-check' : 'checkbox-uncheck'" />
<text style="font-size: 28rpx; color: #333333;">阅读并同意</text>
<text style="color: #4d90ff; font-size: 28rpx;" @click="onUserAgreement()">用户协议</text>
<text style="font-size: 28rpx; color: #333333;"></text>
<text style="color: #4d90ff; font-size: 28rpx;" @click="onPrivacyPolicy()">隐私政策</text>
</view>
</view>
</template>
<script>
import {
transformImageCodeToUri
} from "@/utils/image_utils.js";
import {
default as http
} from "@/utils/http.js";
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
disabled: false,
phoneCodeStr: "获取验证码",
phoneCodeTime: 60,
statusBarHeight: uni.getSystemInfoSync().statusBarHeight,
phoneNumber: "",
password: "",
phone_code: "",
loginBtnLoading: false,
timer: null,
agreeState: false,
}
},
methods: {
async getPhoneCode() {
var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
var this_ = this;
if (this.phoneNumber.length != 11) {
uni.showToast({
icon: "none",
title: "请输入手机号码",
});
return;
}
if (!myreg.test(this.phoneNumber)) {
uni.showToast({
icon: "none",
title: "电话号码格式不对",
});
return;
}
this.phoneCodeTime = 60;
this.timer = setInterval(() => {
console.log(this_.phoneCodeTime)
if (this_.phoneCodeTime <= 0) {
clearInterval(this_.timer);
this_.phoneCodeStr = "获取验证码";
this_.disabled = false;
} else {
this_.phoneCodeStr = this_.phoneCodeTime + "s";
this_.phoneCodeTime--;
this_.disabled = true;
}
}, 1000);
this_.disabled = true;
let query_data = `query{
getMobileCode(mobile:${JSON.stringify(this.phoneNumber)},type:7)
}`;
let result = await http.gql({
query: query_data
})
console.info(result);
//处理返回请求
if (result && result.data && result.data.getMobileCode) {
if (result.data.getMobileCode.Error) {
clearInterval(this.timer);
this_.disabled = false;
uni.showToast({
icon: "none",
title: result.data.getMobileCode.Error,
});
} else {
}
} else {
clearInterval(this.timer);
this_.disabled = false;
uni.showToast({
icon: "none",
title: "请求异常",
});
return;
}
},
async bindLogin() {
if (this.phoneNumber.length < 11) {
uni.showToast({
icon: "none",
title: "请输入手机号码",
});
return;
}
var myreg = /^(((13[0-9]{1})|(15[0-9]{1})|(18[0-9]{1})|(17[0-9]{1}))+\d{8})$/;
if (!myreg.test(this.phoneNumber)) {
uni.showToast({
icon: "none",
title: "电话号码格式不对",
});
return;
}
if (this.phone_code.length <= 0) {
uni.showToast({
icon: "none",
title: "请输入验证码",
});
return;
}
if (!this.agreeState) {
uni.showToast({
icon: "none",
title: "您还没有同意用户协议",
});
return;
}
this.loginBtnLoading = true;
let query_data = `mutation{
ydn_sms_login(mobile:${JSON.stringify(this.phoneNumber)},code:${JSON.stringify(this.phone_code)},type:"web")
}`;
let result = await http.gql({
query: query_data
})
this.loginBtnLoading = false;
console.info(result);
//处理返回请求
if (result && result.data && result.data.ydn_sms_login) {
if (result.data.ydn_sms_login.Error) {
uni.showToast({
icon: "none",
title: result.data.ydn_sms_login.Error,
});
} else {
result.data.ydn_sms_login.Result.FaceImageCode = transformImageCodeToUri(result.data
.ydn_sms_login.Result
.FaceImageCode);
loginHelper.login(result.data.ydn_sms_login.Result,result.data.ydn_sms_login.AppToken)
uni.navigateBack();
}
} else {
uni.showToast({
icon: "none",
title: "登录异常",
});
return;
}
},
onBack() {
uni.navigateBack()
},
gotoAccountLogin() {
uni.redirectTo({
url: '/pages/login_pwd/login_pwd'
})
},
onUserAgreement() {
let tempData = {
url: 'http://www.qianhaiyilan.cn/ppolicy_user.html',
title: "用户协议"
}
uni.navigateTo({
url: `/pages/normal_webview/normal_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
},
onPrivacyPolicy() {
let tempData = {
url: 'http://www.qianhaiyilan.cn/ppolicy_app.html',
title: "隐私政策"
}
uni.navigateTo({
url: `/pages/normal_webview/normal_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
},
checkboxSelected(e) {
this.agreeState = !this.agreeState;
}
}
}
</script>
<style>
.action-row {
display: flex;
flex-direction: row;
justify-content: center;
margin-top: 15rpx;
}
.btn-row {
margin-top: 15rpx;
margin-left: 35rpx;
margin-right: 35rpx;
background: linear-gradient(to right, #FDB559, #FF7E31);
border-radius: 15rpx;
}
.head-bg {
flex-direction: column;
background-image: url('~@/static/login/head.png');
background-size: 50% 100%;
width: 100vh;
height: 15vh;
display: flex;
background-color: transparent;
background-repeat: no-repeat;
}
.checkbox-check {
background-image: url(../../static/common/authsdk_checkbox_checked_bg.png);
background-repeat: no-repeat;
background-size: cover;
margin-right: 15rpx;
width: 30rpx;
height: 30rpx;
}
.checkbox-uncheck {
background-image: url(../../static/common/authsdk_checkbox_uncheck_bg.png);
width: 30rpx;
height: 30rpx;
margin-right: 15rpx;
background-repeat: no-repeat;
background-size: cover;
}
</style>
<template>
<view style="padding-left: 4%; padding-right: 4%; padding-top: 4%;">
<view style="display: flex; ">
<text space="emsp" style="font-size: 35rpx;">手机号</text>
<text style="margin-left: 25rpx; font-size: 35rpx;">{{phoneNume}}</text>
</view>
<view style="height: 2rpx; background-color: #eeeeee; margin-top: 5rpx; margin-bottom: 20rpx;"></view>
<view style="display: flex; align-items: center;">
<text space="emsp" style="font-size: 35rpx;">密 码</text>
<input style="font-size: 35rpx; margin-left: 25rpx;" password type="text" v-model="pwd"
placeholder="请输入密码" />
</view>
<view style="height: 2rpx; background-color: #eeeeee; margin-top: 5rpx; margin-bottom: 20rpx;"></view>
<view style="align-content: center; width: 100%;">
<text style="color: #D4383D; font-size: 22rpx;">账号注销后该账户下所有信息将被清除</text>
</view>
<button style="margin-top: 8%; background-color: #2a0d5c; border-radius: 13rpx; color: white;"
@click="bindLogout()">确实注销</button>
</view>
</template>
<script>
import http from "@/utils/http";
import loginHelper from '../../utils/loginHelper.js'
export default {
data() {
return {
pwd: "",
phoneNume: ""
}
},
onLoad: function(){
console.info("onLoad")
this.phoneNume = "******" + loginHelper.getUserInfo().Mobile.substring(7);
},
methods: {
bindLogout() {
{
this.logoutLogin();
}
},
async logoutLogin() {
if (this.pwd.length <= 0) {
uni.showToast({
icon: "none",
title: "请输入密码",
});
return;
}
let query_data = `mutation{
info_update_user(user:{ user_status:"-1"})
{
error
success
error_type
}
}`;
console.info(query_data);
let result = await http.gql({
query: query_data
})
this.loginBtnLoading = false;
console.info(result);
//处理返回请求
if (result && result.data && result.data.info_update_user &&
!result.data.info_update_user.error) {
loginHelper.logout();
uni.navigateBack();
} else {
uni.showToast({
icon: "none",
title: "注销异常",
});
return;
}
}
}
}
</script>
<style>
</style>
<template>
<view style="background-color: white;
justify-content: center; height: 100vh; align-items: center;">
<view class="qh-u-header">
<view style="display: flex; justify-content: space-between; align-items: center; width: 100%;">
<text style="flex: 1;"></text>
<text class="qh-u-title">我的</text>
<text style="flex: 1; color: white; text-align: end; margin-right: 30rpx; margin-top: 30rpx;"
@click="gotoSettings()">
设置
</text>
</view>
<view
style="background-color: white; border-radius: 20rpx;
margin-left: 34rpx; margin-right: 34rpx;
display: flex; padding-top: 34rpx; padding-bottom: 61rpx; width: 92%; margin-top: 40rpx; align-items: center; justify-content: space-between;">
<image :src="headIcon"
style="background-color: transparent; width: 104rpx; height: 104rpx; border-radius: 52rpx; margin-left: 35rpx;"
@error="imageError" @click="bindLogin()"></image>
<view style="margin-left: 20rpx; flex-grow: 1;" @click="bindLogin()">
<view>
<text style="font-size: 36rpx; color: #333333; font-weight: 600;">
{{ this.hasLogin ? this.userName : '登陆/注册' }}</text>
<image v-show="isShowVip" style="width: 64rpx; height: 32rpx;"
src="../../static/mine/icon_user_vip.webp"></image>
</view>
<view style="margin-top: 15rpx;">
<text style="font-size: 26rpx; color: #999999;">欢迎来到一定牛</text>
</view>
</view>
<view v-show="hasLogin"
style="display: flex; flex-direction: column; justify-content: center; align-items: center; margin-right: 30rpx;">
<view style="align-items: center; display: flex; margin-bottom: 12rpx;">
<image style="width: 36rpx; height: 36rpx;" src="../../static/mine/ydniub.webp"></image>
<text class="niubi-text">{{getNiubi()}}</text>
</view>
<view class="chongzhi-text" @click="chongZhiNiubi()">
<text>充值牛币</text>
</view>
</view>
</view>
</view>
<view style="margin-top: 60rpx;
display: flex;
flex-direction: row;
justify-content: space-between; margin-left: 30rpx; margin-right: 30rpx;
padding: 30rpx; ">
<view class="data-item" v-for="(item, index) in dataItem" @click="dataClick(index)">
<image class="data-iv" :src="item.icon"></image>
<text class="data-text">{{item.name}}</text>
</view>
</view>
<view class="mine-member">
<view style="padding: 30rpx; display: flex; align-items: center; flex-direction: column;">
<view @click="gotoOpenVip()">
<text class="mine—member-btn">{{vipStateText}}</text>
</view>
<view>
<text class="mine-member-time">{{getVipTime()}}</text>
</view>
</view>
</view>
<view v-show="isShowCpsApple" style="margin-left: 30rpx; margin-right: 30rpx;" @click="toGoHeHuoRen()">
<image style="height: 196rpx; width: 100%; margin-top: 30rpx;
" src="../../static/mine/pic_person_shenqinghehuoren.webp"></image>
</view>
<view v-show="isShowCpsLl" style="
display: flex;
flex-direction: row;
justify-content: space-between; margin-left: 30rpx; margin-right: 30rpx;
padding: 30rpx; ">
<view class="data-item" v-for="(item, index) in cpsDataItem" @click="dataClick(index + 4)">
<image class="data-iv" :src="item.icon"></image>
<text class="data-text">{{item.name}}</text>
</view>
</view>
<view style="margin-top: 20rpx; display: flex; flex-direction: row;">
<view class="mine-xingqu" @click="dataClick(8)">
<view style="display: flex; align-items: center;">
<image style="width: 48rpx; height: 48rpx;" src="../../static/mine/ic_person_xingquxuanze.webp">
</image>
<text style="font-size: 30rpx; color: #f5504e; margin-left: 12rpx;">兴趣选择</text>
</view>
<view style="display: flex; align-items: center; margin-top: 12rpx;">
<text class="mine-bottom-text">选择默认打开</text>
<image class="mine-bottom-image" src="../../static/mine/ic_person_in.webp"></image>
</view>
</view>
<view class="mine-share" @click="dataClick(9)">
<view style="display: flex; align-items: center;">
<image style="width: 48rpx; height: 48rpx;"
src="../../static/mine/ic_person_fenxianglinghuiyuan.webp"></image>
<text style="font-size: 30rpx; color: #F5B64E; margin-left: 12rpx;">分享领会员</text>
</view>
<view style="display: flex; align-items: center; margin-top: 12rpx;">
<text class="mine-bottom-text">分享给好友</text>
<image class="mine-bottom-image" src="../../static/mine/ic_person_in.webp"></image>
</view>
</view>
</view>
<view style="margin-top: 20rpx; display: flex; flex-direction: row;">
<view class="mine-jianyi" @click="dataClick(10)">
<view style="display: flex; align-items: center;">
<image style="width: 48rpx; height: 48rpx;" src="../../static/mine/ic_person_tijianyi.webp"></image>
<text style="font-size: 30rpx; color: #4E8EF5; margin-left: 12rpx;">提建议</text>
</view>
<view style="display: flex; align-items: center; margin-top: 12rpx;">
<text class="mine-bottom-text">可定制您的需求</text>
<image class="mine-bottom-image" src="../../static/mine/ic_person_in.webp"></image>
</view>
</view>
<view class="mine-kefu" @click="dataClick(11)">
<view style="display: flex; align-items: center;">
<image style="width: 48rpx; height: 48rpx;" src="../../static/mine/ic_person_zaixiankefu.webp">
</image>
<text style="font-size: 30rpx; color: #5D4EF5; margin-left: 12rpx;">在线客服</text>
</view>
<view style="display: flex; align-items: center; margin-top: 12rpx;">
<text class="mine-bottom-text">客服接待服务</text>
<image class="mine-bottom-image" src="../../static/mine/ic_person_in.webp"></image>
</view>
</view>
</view>
<view v-show="isShowVip" style="display: flex; justify-content: center; margin-top: 24rpx; ">
<view style="font-size: 24rpx;">
<text>会员专属客服微信:</text>
<text style="text-decoration:underline" @click="clip_board(weixin)">{{weixin}}</text>
</view>
</view>
</view>
</template>
<script setup>
import common from "../../utils/common";
import loginHelper from "../../utils/loginHelper.js"
import {
default as app_config
} from '../../utils/app.js';
import {
default as http
} from "@/utils/http.js";
import utils from "../../utils/utils";
export default {
data() {
return {
common,
hasLogin: false,
userName: "",
isShowVip: false,
vipStateText: "去开通",
headIcon: loginHelper.defaultHeadIcon,
buttonRect: {},
userInfo: {},
weixin: "ydnkf002",
isShowCpsLl: false,
isShowCpsApple: false,
dataItem: [{
name: "我的订单",
icon: "../../static/mine/ddjl.webp"
},
{
name: "我的关注",
icon: "../../static/mine/wdgz.webp"
},
{
name: "安全中心",
icon: "../../static/mine/aqzx.webp"
},
{
name: "号码本",
icon: "../../static/mine/hmb.webp"
}
],
cpsDataItem: [{
name: "佣金钱包",
icon: "../../static/mine/ic_person_yongjinqianbao.webp"
},
{
name: "用户管理",
icon: "../../static/mine/ic_person_yonghuguanli.webp"
},
{
name: "我的入驻",
icon: "../../static/mine/ic_person_woderuzhu.webp"
},
{
name: "赚佣金",
icon: "../../static/mine/ic_person_zhuanyongjin.webp"
},
]
}
},
methods: {
toGoHeHuoRen() {
if (loginHelper.hasLogin()) {
let tempData = {
url: `${app_config.server_url.app_host}cps/join_rule`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
uni.navigateTo({
url: "/pages/login_pwd/login_pwd",
});
}
},
chongZhiNiubi() {
if (loginHelper.hasLogin()) {
let tempData = {
url: `${app_config.server_url.app_host}user/charge`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
uni.navigateTo({
url: "/pages/login_pwd/login_pwd",
});
}
},
checkUserIsVip() {
if (this.userInfo && this.userInfo.vip_level) {
var obj = Object.values(this.userInfo.vip_level)
console.log(obj)
for (var i = 0; i < obj.length; i++) {
if (typeof obj[i] === 'string') {
var diff = utils.diffCurrentTime(obj[i])
if (diff < 0) {
return true
}
}
}
}
return false
},
getVipTime() {
var result = ""
if (this.userInfo && this.userInfo.vip_level) {
if (this.userInfo.vip_level.v1_end_time) {
var diff = utils.diffCurrentTime(this.userInfo.vip_level.v1_end_time)
if (diff < 0) {
result = this.userInfo.vip_level.v1_end_time
if (diff < -3 * 24 * 60 * 60 * 1000) {
this.vipStateText = "查看"
} else {
this.vipStateText = "去续费"
}
} else {
this.vipStateText = "去开通"
}
}
}
return result
},
getNiubi() {
var result = 0
if (this.userInfo.Virtual_account_Balance) {
result = this.userInfo.Virtual_account_Balance
}
console.log(this.userInfo.Virtual_account_Balance)
return result + "牛币"
},
gotoOpenVip() {
let tempData = {
url: `${app_config.server_url.app_host}user/privileges_info`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
},
dataClick(index) {
if (loginHelper.hasLogin()) {
switch (index) {
case 0:
let tempData = {
url: `${app_config.server_url.app_host}user/orders`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 1:
tempData = {
url: `${app_config.server_url.app_host}user/attention`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 2:
uni.navigateTo({
url: "/pages/security_center/security_center"
})
break
case 3:
uni.navigateTo({
url: '/pages/number_book/number_book'
})
break
case 4: // 佣金钱包
tempData = {
url: `${app_config.server_url.app_host}cps/wallet`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 5: // 用户管理
tempData = {
url: `${app_config.server_url.app_host}cps/users`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 6: // 我的入驻
tempData = {
url: `${app_config.server_url.app_host}cps/apply`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 7: // 赚佣金
tempData = {
url: `${app_config.server_url.app_host}cps/share`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 8: // 兴趣选择
uni.navigateTo({
url: "/pages/xingqu/xingqu"
})
break
case 9: // 分享领会员
tempData = {
url: `${app_config.server_url.app_host}cps/share_vip`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
case 10: // 提建议
uni.navigateTo({
url: '/pages/suggest/suggest'
})
break
case 11:
tempData = {
url: `${app_config.server_url.app_host}user/online_service`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
break
}
} else {
uni.navigateTo({
url: "/pages/login_pwd/login_pwd",
});
}
},
async bindLogin() {
if (!loginHelper.hasLogin()) {
uni.navigateTo({
url: "/pages/login_pwd/login_pwd",
});
}
},
async gotoSettings() {
uni.navigateTo({
url: '/pages/settings/settings'
})
},
imageError(e) {
console.error('image发生error事件,携带值为' + e.detail.errMsg)
},
gotoMember() {
if (loginHelper.hasLogin()) {
let tempData = {
url: `${app_config.server_url.app_host}user/vip?vip_type=1`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
uni.navigateTo({
url: '/pages/login_pwd/login_pwd'
})
}
},
gotoMyOrder() {
if (loginHelper.hasLogin()) {
let tempData = {
url: `${app_config.server_url.app_host}user/orders`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
uni.navigateTo({
url: '/pages/login_pwd/login_pwd'
})
}
},
share() {
let _this = this;
uni.showActionSheet({
itemList: ['分享到微信', '复制链接'],
popover: {
top: _this.buttonRect.top * 2 + _this.buttonRect.height,
left: _this.buttonRect.left + _this.buttonRect.width / 2
},
success: e => {
if (e.tapIndex == 0) {
_this.clip_board("推荐一个很好用的体育APP给你玩,你试试看! http://www.qianhaiyilan.cn/");
plus.runtime.openURL("weixin://");
}
if (e.tapIndex == 1) {
_this.clip_board("推荐一个很好用的体育APP给你玩,你试试看! http://www.qianhaiyilan.cn/");
}
}
});
},
clip_board(value) {
uni.setClipboardData({
data: value,
success: function() {
uni.getClipboardData({
success: function(res) {
console.log(res.data);
uni.showToast({
title: "已复制到剪贴板",
icon: "none",
});
},
});
},
});
},
copyweixin() {
this.clip_board(this.weixin);
},
async requestUserInfo() {
let query_data = `query{
GetLoginedUserInfo
get_logined_virtual_account
}`;
let result = await http.gql({
query: query_data
})
console.info(result);
//处理返回请求
if (result && result.data &&
result.data.GetLoginedUserInfo &&
result.data.get_logined_virtual_account) {
var info = result.data.GetLoginedUserInfo.Result
var account = result.data.get_logined_virtual_account.Result
var userInfo = loginHelper.getUserInfo()
userInfo.Virtual_account_Balance = account.balance
this.userInfo = userInfo
console.log(this.userInfo)
loginHelper.setUserInfo(this.userInfo)
}
}
},
onLoad() {
},
onShow: function() {
this.userInfo = loginHelper.getUserInfo()
if (this.userInfo) {
this.requestUserInfo()
if (this.userInfo.FaceImageCode) {
this.headIcon = this.userInfo.FaceImageCode
} else {
this.headIcon = loginHelper.getDefaultHeadIcon()
}
this.userName = this.userInfo.NickName
this.isShowVip = this.checkUserIsVip()
this.isShowCpsLl = this.userInfo.CpsStatus == 2
} else {
this.headIcon = loginHelper.getDefaultHeadIcon()
loginHelper.logout();
}
this.hasLogin = loginHelper.hasLogin()
if (common.info_config && common.info_config.weixin) {
this.weixin = common.info_config.weixin
}
console.log("onShow:" + this.weixin + "-" + JSON.stringify(this.userInfo))
this.isShowCpsApple = common.info_config.is_show_cps && !this.isShowCpsApple
}
}
</script>
<style scoped>
.qh-content {
background-color: aquamarine;
}
.qh-u-header {
display: flex;
flex-direction: column;
height: 270rpx;
background-color: transparent;
background-image: url('../../static/mine/user_top_bg.webp');
background-size: cover;
align-items: center;
padding-top: 67rpx;
}
.qh-u-title {
color: white;
font-size: 40rpx;
font-weight: 500;
margin-top: 20rpx;
}
.qh-list-c {
background-color: white;
display: flex;
height: 132rpx;
justify-content: space-between;
align-items: center;
}
.list-text {
font-size: 32rpx;
font-weight: 400;
color: #333333;
margin-left: 23rpx;
}
.tip-text {
text-align: center;
font-size: 25rpx;
color: #D8D8D8;
}
.tip-text2 {
text-align: center;
font-size: 25rpx;
color: blue;
}
.data-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.data-text {
color: #191919;
font-size: 28rpx;
margin-top: 12rpx;
text-align: center;
}
.data-iv {
width: 44rpx;
height: 44rpx;
}
.mine-member {
height: 152rpx;
background-color: transparent;
background-image: url('../../static/mine/pic_person_huiyuankaitong.webp');
background-size: contain;
background-repeat: no-repeat;
margin-left: 30rpx;
margin-right: 30rpx;
display: flex;
justify-content: flex-end;
align-items: center;
}
.minemember-btn {
background: linear-gradient(90deg, #F9CF8E 0%, #F7E0BC 100%);
box-shadow: 0px 6px 20px 0px rgba(255, 111, 56, 0.5);
border-radius: 22px;
color: #6D3B10;
font-size: 28rpx;
padding-top: 6rpx;
padding-bottom: 6rpx;
padding-left: 30rpx;
padding-right: 30rpx;
}
.mine-member-time {
font-size: 24rpx;
color: #77726d;
margin-top: 12rpx;
}
.chongzhi-text {
background: linear-gradient(90deg, #FFA04B 0%, #FF6F38 100%);
box-shadow: 0px 6px 20px 0px rgba(255, 111, 56, 0.5);
border-radius: 22px;
font-size: 28rpx;
font-weight: 500;
color: #FFFFFF;
padding-top: 6rpx;
padding-bottom: 6rpx;
padding-left: 30rpx;
padding-right: 30rpx;
}
.niubi-text {
line-height: 36rpx;
text-align: center;
color: #fab001;
font-size: 28rpx;
}
.mine-xingqu {
background-color: transparent;
background-image: url('../../static/mine/pic_person_xingquxuanze.webp');
background-size: contain;
background-repeat: no-repeat;
flex: 1;
margin-left: 30rpx;
margin-right: 15rpx;
padding-right: 40rpx;
padding-left: 40rpx;
padding-top: 28rpx;
padding-bottom: 28rpx;
}
.mine-share {
background-color: transparent;
background-image: url('../../static/mine/pic_person_fenxianglinghuiyuan.webp');
background-size: contain;
background-repeat: no-repeat;
flex: 1;
margin-left: 15rpx;
margin-right: 30rpx;
padding-right: 40rpx;
padding-left: 40rpx;
padding-top: 28rpx;
padding-bottom: 28rpx;
}
.mine-jianyi {
background-color: transparent;
background-image: url('../../static/mine/pic_person_tijianyi.webp');
background-size: contain;
background-repeat: no-repeat;
flex: 1;
margin-left: 30rpx;
margin-right: 15rpx;
padding-right: 40rpx;
padding-left: 40rpx;
padding-top: 28rpx;
padding-bottom: 28rpx;
}
.mine-kefu {
background-color: transparent;
background-image: url('../../static/mine/pic_person_zaixiankefu.webp');
background-size: contain;
background-repeat: no-repeat;
flex: 1;
margin-left: 15rpx;
margin-right: 30rpx;
padding-right: 40rpx;
padding-left: 40rpx;
padding-top: 28rpx;
padding-bottom: 28rpx;
}
.mine-bottom-text {
font-size: 26rpx;
color: #777777;
}
.mine-bottom-image {
width: 36rpx;
height: 36rpx;
}
</style>
<template>
<view>
<web-view :src="url"></web-view>
</view>
</template>
<script>
import { default as app_config } from '@/utils/app.js';
import common from '@/utils/common.js'
var wv;//计划创建的webview
export default {
data() {
return {
app_config,
url: '',
}
},
methods: {
},
onLoad(val) {
let data = JSON.parse(decodeURIComponent(val.info))
this.url = data.url
if (data.title) {
uni.setNavigationBarTitle({
title: data.title
})
}
},
onReady() {
let appInfo = app_config.app_info;
let header = {
AppVersion: encodeURI(JSON.stringify(appInfo))
}
// #ifdef APP-PLUS
var nwating = plus.nativeUI.showWaiting();
wv = plus.webview.create("", "normal_h5-webview", {
additionalHttpHeaders: {
header: header,
},
plusrequire: "none", //禁止远程网页使用plus的API,有些使用mui制作的网页可能会监听plus.key,造成关闭页面混乱,可以通过这种方式禁止
'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
top: common.customBarH,
height: uni.getSystemInfoSync().windowHeight
})
let pages = getCurrentPages()
let currentPage = pages[pages.length - 1]
var currentWebview = currentPage.$getAppWebview() //此对象相当于html5plus里的plus.webview.currentWebview()。在uni-app里vue页面直接使用plus.webview.currentWebview()无效
currentWebview.append(wv);
wv.loadURL(this.url, header);
wv.addEventListener('loaded', function () {
// wv.evalJS("$(\".header\").hide();");
nwating.close();
wv.show();
}, false);
// #endif
}
}
</script>
<style>
</style>
<template>
<view>
<customWebview :src="url" :top="webview_top" :height="webview_height"></customWebview>
</view>
</template>
<script>
import customWebview from '../../components/customWebview.vue'
import {
default as app_config
} from '@/utils/app.js';
import common from '@/utils/common.js'
var wv; //计划创建的webview
export default {
components: {
customWebview
},
data() {
return {
url: '',
webview_top: 0,
webview_height: uni.getSystemInfoSync().windowHeight,
}
},
methods: {
},
onLoad(val) {
let data = JSON.parse(decodeURIComponent(val.info))
this.url = data.url
if (data.title) {
uni.setNavigationBarTitle({
title: data.title
})
}
if (uni.getSystemInfoSync().platform == "ios") {
/*
获取顶部安全区域的高度 安卓的顶部区域为0 ios的是实际大小
*/
let safeTopArea = uni.getSystemInfoSync().platform == 'ios' ? uni.getSystemInfoSync().safeAreaInsets.top :
0;
//获取底部安全区域的高度
let safeBoottom = uni.getSystemInfoSync().safeAreaInsets.bottom;
this.webview_top = - safeTopArea
this.webview_height = uni.getSystemInfoSync().windowHeight + safeBoottom + safeTopArea
console.log(this.webview_top)
} else {
this.webview_top = common.customBarH + uni.getSystemInfoSync().navigationBarHeight,
this.webview_height = uni.getSystemInfoSync().windowHeight
}
},
onReady() {
},
methods : {
}
}
</script>
<style>
</style>
<template>
<view>
<view class="title_bg" :style="'padding-top:' + (common.statusBarH + 10)+ 'px; '">
<image style="width: 40rpx; height: 40rpx;" src='../../static/common/icon_back.png' @click="onBack()">
</image>
<text style="color: white; font-size: 36rpx; font-weight: 700; margin-left: 15rpx;">我的号码本</text>
<image style="width: 40rpx; height: 40rpx;">
</image>
</view>
<view :style="'height: ' + titleHeight + 'px'"></view>
</view>
</template>
<script>
import common from '@/utils/common.js'
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
titleHeight: 60,
common,
idCard: "",
userInfo: {}
}
},
onReady() {
var this_ = this
uni.createSelectorQuery()
.in(this)
.select('.title_bg')
.boundingClientRect((rect) => {
if (rect) {
this_.titleHeight = rect.height
console.log("rect.height:" + rect.height)
}
})
.exec();
this.userInfo = loginHelper.getUserInfo()
},
onLoad() {
},
methods: {
}
}
</script>
<style>
.title_bg {
background: linear-gradient(90deg, #FF6F38 0%, #FFA04B 100%);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24rpx;
padding-right: 24rpx;
padding-bottom: 20rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
</style>
<template>
<view>
</view>
</template>
<script>
export default {
data() {
return {
}
},
methods: {
}
}
</script>
<style>
</style>
<template>
<view style="background-color: #f5f5f5; height: 100vh;">
<view class="title_bg" :style="'padding-top:' + (common.statusBarH + 10)+ 'px; '">
<image style="width: 40rpx; height: 40rpx;" src='../../static/common/icon_back.png' @click="onBack()">
</image>
<text style="color: white; font-size: 36rpx; font-weight: 700; margin-left: 15rpx;">安全中心</text>
<image style="width: 40rpx; height: 40rpx;">
</image>
</view>
<view :style="'height: ' + titleHeight + 'px'"></view>
<view class="data-item" @click="goToShare()">
<text>身份证</text>
<view style="display: flex; justify-content: center; align-items: center;">
<text :class="userInfo.IdCard ? 'text2' : 'text1'">{{userInfo.Mobile ? "已绑定" : "绑定身份证,账号更安全"}}</text>
<image style="width: 28rpx; height: 28rpx; margin-left: 15rpx;" src="../../static/arrow_right.png">
</image>
</view>
</view>
<view class="data-item" @click="goToShare()">
<text>手机</text>
<view style="display: flex; justify-content: center; align-items: center;">
<text :class="userInfo.Mobile ? 'text2' : 'text1'">{{userInfo.Mobile ? "已绑定" : "绑定手机"}}</text>
<image style="width: 28rpx; height: 28rpx; margin-left: 15rpx;" src="../../static/arrow_right.png">
</image>
</view>
</view>
<view class="data-item" @click="goToShare()">
<text>修改密码</text>
<view style="display: flex; justify-content: center; align-items: center;">
<text class="text1">修改登录密码</text>
<image style="width: 28rpx; height: 28rpx; margin-left: 15rpx;" src="../../static/arrow_right.png">
</image>
</view>
</view>
</view>
</template>
<script>
import common from '@/utils/common.js'
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
titleHeight: 80,
common,
userInfo: {}
}
},
onReady() {
var this_ = this
uni.createSelectorQuery()
.in(this)
.select('.title_bg')
.boundingClientRect((rect) => {
if (rect) {
this_.titleHeight = rect.height
console.log("rect.height:" + rect.height)
}
})
.exec();
this.userInfo = loginHelper.getUserInfo()
},
onShow() {
},
methods: {
}
}
</script>
<style>
.title_bg {
background: linear-gradient(90deg, #FF6F38 0%, #FFA04B 100%);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24rpx;
padding-right: 24rpx;
padding-bottom: 20rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
.data-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 110rpx;
background-color: white;
margin-top: 3rpx;
margin-bottom: 3rpx;
padding-left: 30rpx;
padding-right: 30rpx;
}
.text1 {
font-size: 30rpx;
color: #B0B0B0;
}
.text2 {
font-size: 30rpx;
color: #666666;
}
</style>
<template>
<view>
<view class="data-item">
<text>弹窗开关</text>
<switch checked @change="switchChange"></switch>
</view>
<view v-show="isApp" class="data-item" @click="clearCache()">
<text>清理缓存</text>
<view>
<text style="margin-right: 30rpx;">{{currentSize}}</text>
<image style="width: 28rpx; height: 28rpx;" src="../../static/arrow_right.png"></image>
</view>
</view>
<view class="data-item" @click="goToShare()">
<text>好友分享</text>
<image style="width: 28rpx; height: 28rpx;" src="../../static/arrow_right.png"></image>
</view>
<view class="data-item" @click="goToStop()">
<text>店主认证资料</text>
<image style="width: 28rpx; height: 28rpx;" src="../../static/arrow_right.png"></image>
</view>
<view v-show="isApp" class="data-item" @click="showUpdateVersion()">
<text>版本检测和更新</text>
<view>
<text style="font-size: 27rpx; margin-right: 15rpx;">{{this.updateInfoStr}}</text>
<image style="width: 28rpx; height: 28rpx;" src="../../static/arrow_right.png"></image>
</view>
</view>
<button style="background-color: white; margin: 35rpx; color: #469bf4;" @click="bindLogout()">
{{ this.hasLogin ? "退出登录" : '登陆/注册' }}</button>
</view>
</template>
<script>
import {
default as http
} from "@/utils/http.js";
import {
updateUseModal,
compare
} from '@/utils/check_update.js';
import {
default as app_config
} from '@/utils/app.js';
import loginHelper from "../../utils/loginHelper.js"
export default {
data() {
return {
app_config,
hasLogin: false,
updateInfoStr: "已是最新版本",
versionData: null,
versionName: app_config.app_info.AppName,
currentSize: "",
isApp: false
}
},
onShow() {
this.hasLogin = loginHelper.hasLogin()
console.log("onShow");
// #ifdef APP
this.updateVersion();
this.getStorageSize()
this.isApp = true;
// #endif
},
methods: {
goToStop() {
if(this.hasLogin) {
let tempData = {
url: `${app_config.server_url.app_host}eshop/center/adv?zq`
}
uni.navigateTo({
url: `/pages/notitle_webview/notitle_webview?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else {
uni.navigateTo({
url: '/pages/login_pwd/login_pwd',
});
}
},
goToShare() {
},
clearCache() {
let that = this;
let os = plus.os.name;
if (os == 'Android') {
let main = plus.android.runtimeMainActivity();
let sdRoot = main.getCacheDir();
let files = plus.android.invoke(sdRoot, "listFiles");
let len = files.length;
console.log(files, len)
for (let i = 0; i < len; i++) {
let filePath = '' + files[i]; // 没有找到合适的方法获取路径,这样写可以转成文件路径
plus.io.resolveLocalFileSystemURL(filePath, function(entry) {
if (entry.isDirectory) {
entry.removeRecursively(function(entry) { //递归删除其下的所有文件及子目录
that.files = []
uni.showToast({
title: '清除成功',
duration: 2000
});
that.getStorageSize(); // 重新计算缓存
}, function(e) {
console.log(e.message)
});
} else {
entry.remove();
}
}, function(e) {
console.log('文件路径读取失败')
});
}
} else { // ios
plus.cache.clear(function() {
uni.showToast({
title: '清除成功',
duration: 2000
});
that.getStorageSize();
});
}
},
// 获取本地缓存大小
getStorageSize() {
// #ifdef APP
let that = this;
plus.cache.calculate(function(size) {
let sizeCache = parseInt(size);
if (sizeCache == 0) {
that.currentSize = "0B";
} else if (sizeCache < 1024) {
that.currentSize = sizeCache + "B";
} else if (sizeCache < 1048576) {
that.currentSize = (sizeCache / 1024).toFixed(2) + "KB";
} else if (sizeCache < 1073741824) {
that.currentSize = (sizeCache / 1048576).toFixed(2) + "MB";
} else {
that.currentSize = (sizeCache / 1073741824).toFixed(2) + "GB";
}
});
// #endif
},
bindLogout() {
{
loginHelper.logout();
uni.reLaunch({
url: '/pages/mine/mine'
})
}
},
onLogout() {
if (!loginHelper.hasLogin()) {
uni.navigateTo({
url: '/pages/login_pwd/login_pwd',
});
} else {
uni.navigateTo({
url: "/pages/logout/logout",
});
}
},
showUpdateVersion() {
if (this.versionData) {
updateUseModal({
title: "更新",
contents: this.versionData.Version_Content || '',
is_mandatory: false,
url: this.versionData.Package_Url,
platform: 'android',
type: "pkg" // 安装包类型
});
}
},
async updateVersion() {
let appInfo = app_config.app_info;
// #ifdef APP-PLUS
let query_data = `query{
update_app_version(App_Code:${JSON.stringify(appInfo.Version)}) {
App_Code
App_Name
Sys_Code
Sys_Name
Version_Code
Version_Type
Version_Content
Package_Url
Package_Weight
Version_Num
Update_Way
Download_Way
Update_Time
Publish_Time
Sys_Version
Promoter_Id
}
}`;
console.info(query_data);
let result = await http.gql({
query: query_data
})
console.info(result);
//处理返回请求
if (result && result.data && result.data.update_app_version) {
if (result.data.update_app_version.Error) {
uni.showToast({
icon: "none",
title: result.data.update_app_version.Error,
});
} else {
this.versionData = result.data.update_app_version;
if (this.versionData && this.versionData.Package_Url) {
this.updateInfoStr = "更新版本";
} else {
this.updateInfoStr = "已是最新版本";
}
}
}
// #endif
// #ifdef MP-WEIXIN
this.versionName = app_config.app_info.AppName
this.updateInfoStr = appInfo.Version
// #endif
},
switchChange(e) {
}
}
}
</script>
<style>
.data-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 110rpx;
background-color: white;
margin-top: 3rpx;
margin-bottom: 3rpx;
padding-left: 30rpx;
padding-right: 30rpx;
}
</style>
<template>
<view style="background-color: #F5F5F5; min-height: 100vh; height: 100%;">
<view class="title_bg" :style="'padding-top:' + (common.statusBarH + 10)+ 'px; '">
<image style="width: 40rpx; height: 40rpx;" src='../../static/common/icon_back.png' @click="onBack()">
</image>
<text style="color: white; font-size: 36rpx; font-weight: 700;">提建议</text>
<text style="color: white; font-size: 32rpx;" v-on:click="commit()">提交</text>
</view>
<view :style="'height: ' + titleHeight + 'px'"></view>
<view class="input-c">
<textarea class="suggest-input" maxlength="-1" focus placeholder="请具体描述你的问题或建议(至少15字)"
placeholder-style="color:#999999" v-model="suggest_content" />
</view>
<view style="margin-top: 48rpx; margin-left: 22rpx;">
<text style="color: #999999; font-size: 28rpx;">我的建议</text>
</view>
<view v-for="(item, index) in suggestData" class="suggest-item">
<view v-for="(content, index) in item.Data">
<view v-if="!content.IsReply" class="suggest-content-text">
<text>{{content.Content}}</text>
</view>
<view v-else class="suggest-repet-content-text">
<text>{{content.Content}}</text>
<text>{{"回复时间:" + content.InitTime}}</text>
</view>
</view>
</view>
</view>
</template>
<script>
import common from '@/utils/common.js'
import http from "@/utils/http";
export default {
data() {
return {
titleHeight: 80,
common,
suggestData: [],
suggest_content: ""
}
},
async onLoad() {
let query_data = `query{
getMySuggest(pageSize:30,pageIndex:1,typeId:-1,orderExp:"Id desc",time:"Month|3")
}`;
console.log(query_data)
let result = await http.gql({
query: query_data
})
//处理返回请求
if (result && result.data && result.data.getMySuggest &&
result.data.getMySuggest.Result &&
!result.data.getMySuggest.error) {
var array = result.data.getMySuggest.Result.Rows
for (var i = 0; i < array.length; i++) {
this.getMySuggestById(array[i].Id)
}
}
},
onReady() {
var this_ = this
uni.createSelectorQuery()
.in(this)
.select('.title_bg')
.boundingClientRect((rect) => {
if (rect) {
this_.titleHeight = rect.height
}
})
.exec();
},
onShow() {
},
methods: {
onBack() {
uni.navigateBack()
},
async getMySuggestById(id) {
let query_data = `query{
getSuggestById(id:${id})
}`;
console.log(query_data)
let result = await http.gql({
query: query_data
})
//处理返回请求
if (result && result.data && result.data.getSuggestById &&
result.data.getSuggestById.Result &&
!result.data.getSuggestById.error) {
var bean = JSON.parse(result.data.getSuggestById.Result)
this.suggestData.push(bean)
}
},
async commit() {
console.log("commit")
if (this.suggest_content.length < 5) {
uni.showToast({
icon: "none",
title: "最短为 5 个字符",
});
return;
}
let query_data = `mutation{
user_suggest_info(content:${JSON.stringify(this.suggest_content)})
}`;
console.log(query_data)
let result = await http.gql({
query: query_data
})
console.info(result);
//处理返回请求
if (result && result.data && result.data.user_suggest_info &&
!result.data.user_suggest_info.error) {
uni.showToast({
icon: "none",
title: "提交成功",
});
uni.navigateBack()
} else {
uni.showToast({
icon: "none",
title: "提交失败",
});
}
}
}
}
</script>
<style>
.title_bg {
background: linear-gradient(90deg, #FF6F38 0%, #FFA04B 100%);
display: flex;
justify-content: space-between;
align-items: center;
padding-left: 24rpx;
padding-right: 24rpx;
padding-bottom: 20rpx;
position: fixed;
top: 0;
left: 0;
right: 0;
z-index: 999;
}
.input-c {
min-height: 300rpx;
background-color: white;
padding: 20rpx;
}
.suggest-input {
color: #616161;
font-size: 28rpx;
width: 100%;
}
.suggest-item {
padding: 15rpx;
background-color: white;
margin-top: 30rpx;
}
.suggest-content-text {
font-size: 28rpx;
color: #333333;
margin-top: 30rpx;
margin-left: 22rpx;
margin-right: 22rpx;
margin-bottom: 30rpx;
}
.suggest-repet-content-text {
font-size: 24rpx;
color: #999999;
margin-top: 26rpx;
margin-left: 22rpx;
margin-right: 22rpx;
margin-bottom: 26rpx;
display: flex;
flex-direction: column;
}
</style>
<template>
<view style="background-color: #F5F5F5; min-height: 100vh; height: 100%;">
<view :style="'height:' + common.statusBarH + 'px; background-color: white; '"></view>
<view style="display: flex; justify-content: space-between;
padding-top: 16rpx;
padding-left: 30rpx ; padding-right: 30rpx; background-color: white;
padding-bottom: 16rpx;">
<image style="width: 56rpx; height: 56rpx;" src="../../static/close_black.webp" @click="back()"></image>
<text style="color: #333333; font-size: 34rpx; height: 56rpx; line-height: 56rpx; ">选择感兴趣的内容</text>
<image style="width: 56rpx; height: 56rpx;"></image>
</view>
<radio-group @change="radioChange">
<view class="grid-container">
<label v-for="(item, index) in dataArray" class="grid-item">
<image style="width: 72rpx; height: 72rpx;" :src="item.pic"></image>
<text style="color: #333333; margin-top: 20rpx; margin-bottom: 20rpx;">{{item.name}}</text>
<radio :checked="item.checked" :value="item.code"> </radio>
</label>
</view>
</radio-group>
<view
style="display: flex; align-items: center; justify-content: center; margin-top: 20rpx; padding-bottom: 20rpx;">
<text style="font-size: 24rpx; color: #999999;">APP将在每次启动后打开您选择的页面</text>
</view>
</view>
</template>
<script>
import common from '@/utils/common.js'
export default {
data() {
return {
common,
dataArray: []
}
},
onLoad() {
var select = uni.getStorageSync("user_option_code")
if (!select) {
select = 'home'
uni.setStorageSync("user_option_code", select)
}
var array = common.info_config.app_open_option
for (var i = 0; i < array.length; i++) {
array[i].checked = (select === array[i].code)
}
this.dataArray = array
},
methods: {
back() {
uni.navigateBack()
},
radioChange(e) {
var select = e.detail.value
for (var i = 0; i < this.dataArray.length; i++) {
this.dataArray[i].checked = (select === this.dataArray.code)
}
uni.setStorageSync("user_option_code", select)
}
}
}
</script>
<style>
.grid-container {
margin: 40rpx;
display: grid;
grid-template-columns: repeat(3, 1fr);
/* 每列占据 1/3 的宽度 */
grid-gap: 28rpx;
/* 设置列间距 */
}
.grid-item {
border-radius: 6rpx;
background-color: white;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding-top: 40rpx;
padding-bottom: 30rpx;
}
</style>
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
/**
* 这里是uni-app内置的常用样式变量
*
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
*
*/
/**
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
*
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
*/
/* 颜色变量 */
/* 行为相关颜色 */
$uni-color-primary: #007aff;
$uni-color-success: #4cd964;
$uni-color-warning: #f0ad4e;
$uni-color-error: #dd524d;
/* 文字基本颜色 */
$uni-text-color:#333;//基本色
$uni-text-color-inverse:#fff;//反色
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
$uni-text-color-placeholder: #808080;
$uni-text-color-disable:#c0c0c0;
/* 背景颜色 */
$uni-bg-color:#ffffff;
$uni-bg-color-grey:#f8f8f8;
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
/* 边框颜色 */
$uni-border-color:#c8c7cc;
/* 尺寸变量 */
/* 文字尺寸 */
$uni-font-size-sm:12px;
$uni-font-size-base:14px;
$uni-font-size-lg:16;
/* 图片尺寸 */
$uni-img-size-sm:20px;
$uni-img-size-base:26px;
$uni-img-size-lg:40px;
/* Border Radius */
$uni-border-radius-sm: 2px;
$uni-border-radius-base: 3px;
$uni-border-radius-lg: 6px;
$uni-border-radius-circle: 50%;
/* 水平间距 */
$uni-spacing-row-sm: 5px;
$uni-spacing-row-base: 10px;
$uni-spacing-row-lg: 15px;
/* 垂直间距 */
$uni-spacing-col-sm: 4px;
$uni-spacing-col-base: 8px;
$uni-spacing-col-lg: 12px;
/* 透明度 */
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
/* 文章场景相关 */
$uni-color-title: #2C405A; // 文章标题颜色
$uni-font-size-title:20px;
$uni-color-subtitle: #555555; // 二级标题颜色
$uni-font-size-subtitle:26px;
$uni-color-paragraph: #3F536E; // 文章段落颜色
$uni-font-size-paragraph:15px;
## 2.1.2(2023-06-12)
1. [新增]添加`z-index`参数控制层级大小,默认1993
2. [说明]以后该插件只更新`uni_modules`方式的,`zip`方式的不提供更新了
## 2.1.1(2022-09-16)
1. 将插件更新为`uni_modules`方式
## 2.1.0(2022-08-12)
1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下)
```js
export default {
data() {
return {
tabs: [{ id: 1, name: '' }]
}
}
}
```
## 2.0.10(2022-01-27)
1. 更新属性line-animation设置为false可以不要动画,这是好多朋友问到,特此加上
## 2.0.9(2020-10-12)
1. 修复 v-tabs 第一次可能出现第一个标签显示不完整的情况
2. 修改了 pages/tabs/order 示例文件
## 2.0.8(2020-09-21)
1. 修复添加 fixed 属性后,滚动条无效
2. 修复选项很少的情况下,下划线计算计算错误
3. 新增 paddingItem 属性,设置选项左右边距(上下边距需要设置 height 属性,或者设置 padding 属性)
## 2.0.7(2020-09-17)
1. 紧急修复 bug,横向滑动不了的情况
## 2.0.6(2020-09-16)
1. 新增 fixed 属性,是否固定在顶部,示例地址:pages/tabs/tabs-static
2. 优化之前的页面结构
## 2.0.5(2020-09-09)
1. 修复 width 错误,dom 加载的时候没有及时获取到 data 属性导致的 。
## 2.0.4(2020-08-29)
1. 优化异步改变 tabs 后,下划线不初始化问题
2. github 地址上有图 2 的源码,需要的自行下载,页面路径:pages/tabs/order.vue
## 2.0.3(2020-08-20)
1. 优化 节点查询 和 选中渲染
2. 优化支付宝中 createSelectorQuery() 的影响
**特别说明:**
> 支付宝中平铺方法和其他方法不能在一个页面中出现,不然有一个显示错误(具体什么原因没查到,有好心的人发现了,望告知一下,感谢
## 2.0.2(2020-08-19)
1. 优化 change 事件触发机制
## 2.0.1(2020-08-16)
1. 修改默认高度为 70rpx
2. 新增属性 bgColor,可设置背景颜色,默认 #fff
3. 新增整个 tab 的 padding 属性,默认 0
## 2.0.0(2020-08-13)
1. 全新的 v-tabs 2.0
2. 支持 H5 小程序 APP
3. 属性高度可配置
## 1.3.2(2020-07-21)
1. 新增 auto 的配置,是否平铺 tab
2. 修复文档上的错误示例(感谢 lushgwe@163.com 的反馈)
## 1.3.0(2020-07-05)
1. 新增 padding 的可配置
2. 修复 v-model 双向绑定问题
3. 修复初始化下划线没定位的为题
## 1.2.0(2020-06-19)
1. 添加注释
2. 修复 bug
## 1.1.8(2020-06-11)
1. 添加 change 事件
2. 修复插件内容问题
3. 修复下划线不居中问题
## 1.1.6(2020-06-11)
1. 添加 change 事件
2. 修复插件内容问题
## 1.1.4(2020-06-11)
1. 添加 change 事件
2. 修复插件内容问题
## 1.1.2(2020-06-11)
1. 添加 change 事件
## 1.1.1(2020-06-09)
1. 修复小程序端选中的下划线不显示问题
2. 新增 tab 高度设置
3. lineHeight 修改为只支持 String 方式
## 1.1.0(2020-06-09)
1. 修复小程序端选中的下划线不显示问题
2. 新增 tab 高度设置
3. lineHeight 修改为只支持 String 方式
## 1.0.0(2020-06-04)
1. 更新插件1.0.0
\ No newline at end of file
<template>
<view :id="elId" class="v-tabs">
<scroll-view
id="scrollContainer"
:scroll-x="scroll"
:scroll-left="scroll ? scrollLeft : 0"
:scroll-with-animation="scroll"
:style="{ position: fixed ? 'fixed' : 'relative', zIndex }"
>
<view
class="v-tabs__container"
:style="{
display: scroll ? 'inline-flex' : 'flex',
whiteSpace: scroll ? 'nowrap' : 'normal',
background: bgColor,
height,
padding
}"
>
<view
:class="['v-tabs__container-item', { disabled: !!v.disabled }]"
v-for="(v, i) in tabs"
:key="i"
:style="{
color: current == i ? activeColor : color,
fontSize: current == i ? fontSize : fontSize,
fontWeight: bold && current == i ? 'bold' : '',
justifyContent: !scroll ? 'center' : '',
flex: scroll ? '' : 1,
padding: paddingItem
}"
@click="change(i)"
>
{{ field ? v[field] : v }}
</view>
<view
v-if="!pills"
:class="['v-tabs__container-line', { animation: lineAnimation }]"
:style="{
background: lineColor,
width: lineWidth + 'px',
height: lineHeight,
borderRadius: lineRadius,
left: lineLeft + 'px',
transform: `translateX(-${lineWidth / 2}px)`
}"
></view>
<view
v-else
:class="['v-tabs__container-pills', { animation: lineAnimation }]"
:style="{
background: pillsColor,
borderRadius: pillsBorderRadius,
left: pillsLeft + 'px',
width: currentWidth + 'px',
height
}"
></view>
</view>
</scroll-view>
<view
class="v-tabs__placeholder"
:style="{
height: fixed ? height : '0',
padding
}"
></view>
</view>
</template>
<script>
/**
* v-tabs
* @property {Number} value 选中的下标
* @property {Array} tabs tabs 列表
* @property {String} bgColor = '#fff' 背景颜色
* @property {String} color = '#333' 默认颜色
* @property {String} activeColor = '#2979ff' 选中文字颜色
* @property {String} fontSize = '28rpx' 默认文字大小
* @property {String} activeFontSize = '28rpx' 选中文字大小
* @property {Boolean} bold = [true | false] 选中文字是否加粗
* @property {Boolean} scroll = [true | false] 是否滚动
* @property {String} height = '60rpx' tab 的高度
* @property {String} lineHeight = '10rpx' 下划线的高度
* @property {String} lineColor = '#2979ff' 下划线的颜色
* @property {Number} lineScale = 0.5 下划线的宽度缩放比例
* @property {String} lineRadius = '10rpx' 下划线圆角
* @property {Boolean} pills = [true | false] 是否胶囊样式
* @property {String} pillsColor = '#2979ff' 胶囊背景色
* @property {String} pillsBorderRadius = '10rpx' 胶囊圆角大小
* @property {String} field 如果是对象,显示的键名
* @property {Boolean} fixed = [true | false] 是否固定
* @property {String} paddingItem = '0 22rpx' 选项的边距
* @property {Boolean} lineAnimation = [true | false] 下划线是否有动画
* @property {Number} zIndex = 1993 默认层级
*
* @event {Function(current)} change 改变标签触发
*/
export default {
props: {
value: {
type: Number,
default: 0
},
tabs: {
type: Array,
default () {
return []
}
},
bgColor: {
type: String,
default: '#fff'
},
padding: {
type: String,
default: '0'
},
color: {
type: String,
default: '#333'
},
activeColor: {
type: String,
default: '#2979ff'
},
fontSize: {
type: String,
default: '28rpx'
},
activeFontSize: {
type: String,
default: '32rpx'
},
bold: {
type: Boolean,
default: true
},
scroll: {
type: Boolean,
default: true
},
height: {
type: String,
default: '70rpx'
},
lineColor: {
type: String,
default: '#2979ff'
},
lineHeight: {
type: String,
default: '10rpx'
},
lineScale: {
type: Number,
default: 0.5
},
lineRadius: {
type: String,
default: '10rpx'
},
pills: {
type: Boolean,
default: false
},
pillsColor: {
type: String,
default: '#2979ff'
},
pillsBorderRadius: {
type: String,
default: '10rpx'
},
field: {
type: String,
default: ''
},
fixed: {
type: Boolean,
default: false
},
paddingItem: {
type: String,
default: '0 22rpx'
},
lineAnimation: {
type: Boolean,
default: true
},
zIndex: {
type: Number,
default: 1993
}
},
data () {
return {
elId: '',
lineWidth: 30,
currentWidth: 0, // 当前选项的宽度
lineLeft: 0, // 滑块距离左侧的位置
pillsLeft: 0, // 胶囊距离左侧的位置
scrollLeft: 0, // 距离左边的位置
containerWidth: 0, // 容器的宽度
current: 0 // 当前选中项
}
},
watch: {
value (newVal) {
this.current = newVal
this.$nextTick(() => {
this.getTabItemWidth()
})
},
current (newVal) {
this.$emit('input', newVal)
},
tabs (newVal) {
this.$nextTick(() => {
this.getTabItemWidth()
})
}
},
methods: {
// 产生随机字符串
randomString (len) {
len = len || 32
let $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678' /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
let maxPos = $chars.length
let pwd = ''
for (let i = 0; i < len; i++) {
pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
}
return pwd
},
// 切换事件
change (index) {
const isDisabled = !!this.tabs[index].disabled
if (this.current !== index && !isDisabled) {
this.current = index
this.$emit('change', index)
}
},
// 获取左移动位置
getTabItemWidth () {
let query = uni
.createSelectorQuery()
// #ifndef MP-ALIPAY
.in(this)
// #endif
// 获取容器的宽度
query
.select(`#scrollContainer`)
.boundingClientRect((data) => {
if (!this.containerWidth && data) {
this.containerWidth = data.width
}
})
.exec()
// 获取所有的 tab-item 的宽度
query
.selectAll('.v-tabs__container-item')
.boundingClientRect((data) => {
if (!data) {
return
}
let lineLeft = 0
let currentWidth = 0
if (data) {
for (let i = 0; i < data.length; i++) {
if (i < this.current) {
lineLeft += data[i].width
} else if (i == this.current) {
currentWidth = data[i].width
} else {
break
}
}
}
// 当前滑块的宽度
this.currentWidth = currentWidth
// 缩放后的滑块宽度
this.lineWidth = currentWidth * this.lineScale * 1
// 滑块作移动的位置
this.lineLeft = lineLeft + currentWidth / 2
// 胶囊距离左侧的位置
this.pillsLeft = lineLeft
// 计算滚动的距离左侧的位置
if (this.scroll) {
this.scrollLeft = this.lineLeft - this.containerWidth / 2
}
})
.exec()
}
},
mounted () {
this.elId = 'xfjpeter_' + this.randomString()
this.current = this.value
this.$nextTick(() => {
this.getTabItemWidth()
})
}
}
</script>
<style lang="scss" scoped>
.v-tabs {
width: 100%;
box-sizing: border-box;
overflow: hidden;
::-webkit-scrollbar {
display: none;
}
&__container {
min-width: 100%;
position: relative;
display: inline-flex;
align-items: center;
white-space: nowrap;
overflow: hidden;
&-item {
display: flex;
align-items: center;
height: 100%;
position: relative;
z-index: 10;
// padding: 0 11px;
transition: all 0.3s;
white-space: nowrap;
&.disabled {
opacity: 0.5;
color: #999;
}
}
&-line {
position: absolute;
bottom: 0;
}
&-pills {
position: absolute;
z-index: 9;
}
&-line,
&-pills {
&.animation {
transition: all 0.3s linear;
}
}
}
}
</style>
{
"id": "v-tabs",
"displayName": "自定义 tab 选项卡 2",
"version": "2.1.2",
"description": "自定义 tab ,支持多种样式,支持 h5 小程序 app",
"keywords": [
"v-tabs",
"tab",
"选项卡"
],
"repository": "https://github.com/xfjpeter/uni-plugins",
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"type": "component-vue",
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": "1207791534"
},
"declaration": {
"ads": "无",
"data": "无",
"permissions": "无"
},
"npmurl": ""
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "n"
},
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "n",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "y",
"快手": "y",
"飞书": "y",
"京东": "y"
},
"快应用": {
"华为": "u",
"联盟": "u"
}
}
}
}
}
\ No newline at end of file
## 插件说明
> 这是 `v-tabs` 插件的升级版本,参数上有很大变动,支持 `H5` `小程序` `手机端`,如果是在之前的插件上升级的话,请注意参数的变更,触发的事件没有变更。
## 使用说明
### 1、最基本用法
- 视图文件
```html
<v-tabs v-model="current" :tabs="tabs" @change="changeTab"></v-tabs>
```
- 脚本文件
```js
export default {
data() {
return {
current: 0,
tabs: ['军事', '国内', '新闻新闻', '军事', '国内', '新闻', '军事', '国内', '新闻']
}
},
methods: {
changeTab(index) {
console.log('当前选中的项:' + index)
}
}
}
```
### 2、平铺整个屏幕
- 视图文件
```html
<v-tabs v-model="activeTab" :scroll="false" :tabs="['全部', '进行中', '已完成']"></v-tabs>
```
- 脚本文件
```js
export default {
data() {
return {
activeTab: 0
}
}
}
```
### 3、胶囊用法
- 视图文件
```html
<v-tabs v-model="current" :tabs="tabs" :pills="true" line-height="0" activeColor="#fff" @change="changeTab"></v-tabs>
```
- 脚本文件
```js
data() {
return {
current: 2,
tabs: [
'军事',
'国内',
'新闻新闻',
'军事',
'国内',
'新闻',
'军事',
'国内',
'新闻',
],
},
methods: {
changeTab(index) {
console.log('当前选中索引:' + index)
}
}
}
```
## 文档说明
### 1、属性说明
| 参数 | 类型 | 默认值 | 说明 |
| :---------------: | :-----: | :-------: | :-----------------------------------------------------------------------: |
| tabs | Array | [] | 控制 tab 的列表 |
| value | Number | 0 | 必传(双向绑定的值) |
| color | String | '#333' | 默认文字颜色 |
| activeColor | String | '#2979ff' | 选中文字的颜色 |
| fontSize | String | '28rpx' | 默认文字大小(rpx 或 px)(弃用) |
| bold | Boolean | true | 是否加粗选中项 |
| scroll | Boolean | true | 是否显示滚动条,平铺设置 false |
| height | String | '70rpx' | tab 高度(rpx 或 px) |
| lineHeight | String | '10rpx' | 滑块高度(rpx 或 px) |
| lineColor | String | '#2979ff' | 滑块的颜色 |
| lineScale | Number | 0.5 | 滑块宽度缩放值 |
| lineRadius | String | '10rpx' | 滑块圆角宽度(rpx 或 px) |
| pills | Boolean | false | 是否开启胶囊 |
| pillsColor | String | '#2979ff' | 胶囊背景颜色(rpx 或 px) |
| pillsBorderRadius | String | '10rpx' | 胶囊圆角宽度(rpx 或 px) |
| field | String | '' | 如果 tabs 子项是对象,输入需要展示的键名 |
| bgColor | String | '#fff' | 背景色,支持 linear-gradient 渐变 |
| padding | String | '0' | 整个 tab padding 属性 |
| fixed | Boolean | false | 是否固定在顶部 |
| paddingItem | String | '0 22rpx' | 选项的边距(设置上下不生效,需要设置高度) |
| lineAnimation | Boolean | true | 是否需要 line 和 pills 的动画,在隐藏页面后默认移动到第一个的时候比较实用 |
| zIndex | Number | 1993 | 控制 tab 的层级,默认1993 |
### 1.1 `tabs`参数展开说明
#### 1.1.1 当`tabs`仅仅是单纯的数组时候,没有什么特别的地方
```js
export default {
data() {
return {
tabs: ['全部', '待付款', '待消费', '已完成', '已评价', '已过期', '已退款']
}
}
}
```
#### 1.1.2 当`tabs`使用的数组对象的方式,特定参数需要注意一下
- `disabled` 参数,可以控制按钮是否可以点击
```js
export default {
data() {
return {
tabs: [
{ id: 1, name: '待付款', disabled: false },
{ id: 2, name: '待收货', disabled: false },
{ id: 3, name: '待评价', disabled: false },
{ id: 4, name: '退款/售后', disabled: true },
{ id: 5, name: '我的订单', disabled: false }
]
}
}
}
```
### 2、事件说明
| 名称 | 参数 | 说明 |
| :----: | :---: | :--------------------------------: |
| change | index | 改变选中项触发, index 选中项的下标 |
## 更新日志
### 2.1.1(2022-09-16)
1. 将插件更新为`uni_modules`方式
### 2022-08-12
1. 增加`disable`参数,控制是否可以点击,只能应用在数组对象中,见[disabled 的用法](#112-当tabs使用的数组对象的方式特定参数需要注意一下)
```js
export default {
data() {
return {
tabs: [{ id: 1, name: '' }]
}
}
}
```
### 2022-01-27
1. 更新属性`line-animation`设置为`false`可以不要动画,这是好多朋友问到,特此加上
### 2020-09-24
1. 修复 `v-tabs` 第一次可能出现第一个标签显示不完整的情况
2. 修改了 `pages/tabs/order` 示例文件
### 2020-09-21
1. 修复添加 `fixed` 属性后,滚动条无效
2. 修复选项很少的情况下,下划线计算计算错误
3. 新增 `paddingItem` 属性,设置选项左右边距(上下边距需要设置 `height` 属性,或者设置 `padding` 属性)
**写在最后:**
欢迎各位老铁反馈 bug ,本人后端 PHP 一枚,只是应为感兴趣前端,自己琢磨,自己搞。如果你在使用的过程中有什么不合理,需要优化的,都可以在下面评论(或加我 QQ: 1207791534),本人看见后回复、修正,感谢。
### 2020-09-17
1. 紧急修复 bug,横向滑动不了的情况
### 2020-09-16
1. 新增 `fixed` 属性,是否固定在顶部,示例地址:`pages/tabs/tabs-static`
2. 优化之前的页面结构
**注意:**
1. 使用 `padding` 属性的时候,尽量不要左右边距,会导致下划线位置不对
2. 如果不绑定 `v-model` 会导致 `change` 事件改变的时候,下划线不跟随问题
### 2020-09-09
1. 修复 `width` 错误,dom 加载的时候没有及时获取到 `data` 属性导致的。
### 2020-08-29
1. 优化异步改变 `tabs` 后,下划线不初始化问题
2. `github` 地址上有图 2 的源码,需要的自行下载,页面路径:`pages/tabs/order`
### 2020-08-20
1. 优化 `节点查询``选中渲染`
2. 优化支付宝中 `createSelectorQuery()` 的影响
### 2020-08-19
1. 优化 `change` 事件触发机制
### 2020-08-16
1. 修改默认高度为 `70rpx`
2. 新增属性 `bgColor`,可设置背景颜色,默认 `#fff`
3. 新增整个 `tab``padding` 属性,默认 `0`
### 2020-08-13
1. 全新的 `v-tabs 2.0`
2. 支持 `H5` `小程序` `APP`
3. 属性高度可配置
## 预览
![v-tabs 2.0.1.gif](https://tva1.sinaimg.cn/large/007S8ZIlgy1ghsv40mj76g30ai0i2tsd.gif)
![v-tabs 2.0.2.gif](https://img-cdn-aliyun.dcloud.net.cn/stream/plugin_screens/42f3a920-a674-11ea-8a24-ffee00625e2e_1.png?v=1597912963)
MIT License
Copyright (c) 2022 zebra-ui
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
<p align="center">
<img alt="logo" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/logo.png" width="220" style="margin-bottom: 10px;">
</p>
<h1 align="center">ZebraSwiper</h1>
<p align="center">基于uniapp,全面对标swiper,并实现全端兼容。</p>
<p align="center">
🔥 <a href="https://swiper.zebraui.com/">文档网站</a>
&nbsp;
&nbsp;
🚀 <a href="https://zebraui.com/" target="_blank">zebraUI组件库</a>
</p>
## 介绍
[zebra-swiper](https://github.com/zebra-ui/zebra-uniapp-swiper) 是基于uniapp开发的一款移动端轮播组件,已实现swiper组件90%的功能。
[uniapp](https://uniapp.dcloud.io/README)[swiper](https://uniapp.dcloud.io/component/swiper)组件存在很大的局限性,无法完成一些复杂的轮播效果。
而zebra-swiper不仅可以实现一些3D轮播效果,还可以通过参数来定义你想要的效果。
## 特性
- 全面对标swiper,并实现全端兼容
- 兼容多端,小程序也可以实现3D轮播效果
- 可自定义3D效果
- 多种示例,总有一种适合你
## 安装
### npm方式
```bash
npm i @zebra-ui/swiper
```
```js
// pages.json
{
"easycom": {
"^z-(.*)": "@zebra-ui/swiper/components/z-$1/z-$1.vue"
},
"pages": [...],
"globalStyle": {...}
}
```
### uni_modules方式
[插件市场](https://ext.dcloud.net.cn/plugin?id=7273)直接导入即可
## 手机预览
<div>
<img alt="wx" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/wx.jpg" width="200" />
<img alt="ali" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/ali.jpg" width="200" />
<img alt="h5" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/h5.png" width="200" />
</div>
## 预览
<div style="display:flex;flex-wrap:wrap;margin-top:30px;">
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif1.gif" width="300" style="margin:20px;" />
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif2.gif" width="300" style="margin:20px;" />
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif3.gif" width="300" style="margin:20px;" />
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif4.gif" width="300" style="margin:20px;" />
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif5.gif" width="300" style="margin:20px;" />
<img alt="gif" src="https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/gif/gif6.gif" width="300" style="margin:20px;" />
</div>
## 群
QQ群:947159437
![image](https://assets-1256020106.cos.ap-beijing.myqcloud.com/zebra-swiper/zebra-swiper-group-code.png)
\ No newline at end of file
## 2.2.6(2023-02-20)
`2023-02-20`
**Feat**
- `panorama`全景切换效果新增`stretch`参数,用于控制slide之间的距离。
**Fix**
- 修复字节小程序3D样式失效的问题。
- 修复`panorama`切换效果参数无效的问题。
- 修复`autoHeight`高度自适应使用报错的问题。(`autoHeight`选项可以正常使用,且在大多数场景下可以正确获取高度)
## 2.2.5(2022-11-10)
`2022-11-10`
**Feat**
- `cards`卡片切换效果新增`perSlideRotate``perSlideOffset`参数用于控制卡片的偏移距离及旋转角度。
- 微信小程序中默认使用虚拟节点渲染,即`virtualHost`: `true`
**Fix**
- 修复`pagination`选项开启后,动态控制`swiper`禁用或启用报错的问题。
- 修复支付宝小程序3D样式失效的问题。
## 2.2.4(2022-09-23)
`2022-09-23`
**Feat**
- 新增`noSwiping`参数控制是否禁止触摸。当禁止触摸开启时,不可通过滑动切换。可通过自动切换,`slideTo`等方法切换。
**Fix**
- 修复`vue3``app`触摸无效的问题。
- 新增触摸事件`touchcancel`
## 2.2.3(2022-07-26)
`2022-07-26`
**Feat**
- 卡片切换效果`cards`新增`rotate`参数,用于控制卡片切换时是否发生旋转。
**Fix**
- 修复微信小程序使用`zebra-swiper`时,页面无法滚动。
- 修复`app`报错`toJSON`的问题。
- 修复`swiper``vue3`中无法自动播放的问题。
## 2.2.2(2022-07-01)
`2022-07-01`
**Feat**
- 兼容`PC`浏览器端。
- 初步兼容`VUE3`
**Fix**
- 修复使用`zebra-swiper`时,页面无法滚动。(`zebra-swiper`将不再默认阻止事件冒泡)。
## 2.2.1(2022-03-31)
`2022-03-31`
**Feat**
- 新增`changeDirection`方法,该方法用于动态改变swiper方向。
- `z-swiper-item`新增`swiperItemWidth` `swiperItemHeight` 属性,用于在swiper无法正确获取宽高的情况下设置swiper的宽高(如快手小程序)。
**Fix**
- 消除快手小程序itemPropWxs的警告。
## 2.2.0(2022-03-21)
`2022-03-21`
**本次更新调整了组件的整体架构及组件入口逻辑。主要为性能优化,不涉及新功能。**
不兼容性更新:
- `z-swiper``customStyle` 由字符串类型更改为Object类型(与`z-swiper-item`保持一致)。
- `z-swiper-item` 删除了加载的效果。
**Fix**
- 修复因数据改变而无法正确触发更新的问题。
- 修复方法 `disable` `enable` 提示未定义的问题。
**Perf**
- 组件首次渲染速度优化。
- loop模式处理数据后才开始加载swiper,确保数据的一致性。
- 部分同步方法更改为异步,体验更流畅。
## 2.1.4(2022-03-05)
`2022-03-05`
**Feat**
- 高级案例加入开屏页。[点击预览](https://swiper.zebraui.com/h5/pages/demos/paper/index)
**Fix**
- 修复百度小程序高度计算错误的问题。
## 2.1.3(2022-03-03)
`2022-03-03`
**Feat**
- 新增高级案例模块。
- 高级案例加入环游地球。[点击预览](https://swiper.zebraui.com/h5/pages/demos/travel-slider/index)
- 微信小程序,qq小程序使用wxs赋值样式。
## 2.1.2(2022-03-02)
`2022-03-02`
本次改版涉及所有开启loop的功能。请更新后删除手动拼接的数据。
**Feat**
- loop无限循环模式无需再手动拼接数据。
## 2.1.1(2022-03-01)
`2022-03-01`
**Fix**
- 修复字节小程序轮播内容不显示的问题。
- 修复字节小程序获取位置信息错误的问题。
**Docs**
- [文档新增事件。](https://swiper.zebraui.com/basic/events/)
## 2.1.0(2022-02-27)
`2022-02-27`
更新须知
使用组件时,需在z-swiper标签上以`v-model`的形式传入list数据,也就是要循环的列表数据,该属性为强制性,不加会导致意外错误。例:
之前的方式:
```vue
<z-swiper>
<z-swiper-item v-for="(item,index) in list" :key="index">
<image class="image" :src="item" mode="aspectFill">
</image>
</z-swiper-item>
</z-swiper>
```
现在的方式:
```vue
<z-swiper v-model="list"> //这里传入的需和下方循环的保持一致
<z-swiper-item v-for="(item,index) in list" :key="index">
<image class="image" :src="item" mode="aspectFill">
</image>
</z-swiper-item>
</z-swiper>
```
这个操作也为swiper接管数据操作铺垫,对后续很多新功能非常有用,也为loop无限循环的痛点提供了解决方案。
**Fix**
- 修复数据为空时报错。
- 修复请求数据时swiper提前初始化的问题。
**Feat**
- 新增滚动条功能。
## 2.0.1(2022-02-25)
`2022-02-25`
**Fix**
- 修复插槽内容class样式不生效问题。
**Feat**
- 新增缩略图功能。
## 2.0.0(2022-02-24)
`2022-02-24`
**Feat**
- 该版本为破坏性改版,无法兼容1.0。
- 代码重构,使用模块化将功能分割,大幅提升性能,方便后续维护。
- 全面对标swiper组件,并实现全端兼容。小程序也可实现炫酷的轮播效果。
- 所有切换效果全部支持loop无限循环。
- 新增全景切换效果。
- 新增轮播块功能,可自定义显示数量。
- 新增进度条指示器。
## 1.0.7(2022-01-25)
`2022-01-25`
**Feat**
- 新增轮播切换器功能,可使用默认切换或自定义切换。
- 示例项目新增切换器的使用及自定义切换器。
## 1.0.6(2022-01-24)
`2022-01-24`
**Chore**
- 示例项目新增指示器的使用及自定义指示器。
## 1.0.5(2022-01-21)
`2022-01-21`
**Docs**
- README.md新增手机预览,包含微信,支付宝小程序码,H5二维码。
## 1.0.4(2022-01-20)
`2022-01-20`
**Style**
- 示例项目首页px统一修改为rpx。
## 1.0.3(2022-01-19)
`2022-01-19`
**Fix**
- 修复轮播设置为纵向时,高度错误的问题。
- 修复在百度小程序中样式错乱的问题。
## 1.0.2(2022-01-18)
`2022-01-18`
**Docs**
- README.md新增gif预览图
- 修复因未知原因引起的uni_modules组件上传错误的问题。
`2022-01-14`
### [v1.0.1](https://github.com/zebra-ui/zebra-uniapp-swiper)
**Feature**
- 新增zebra-swiper,zebra-swiper-item组件。
- 新增多种3D切换效果。包括渐变,方块,3D流,翻转,卡片,创意性等多种切换效果。
- 新增[示例项目](https://swiper.zebraui.com),包含多种切换效果示例。
<template>
<!-- #ifndef MP-WEIXIN || MP-QQ -->
<view :class="['swiper-slide',slideClass]" :style="[itemStyle,customStyle]" @click.stop="onClickSlide">
<!-- #endif -->
<!-- #ifdef MP-WEIXIN || MP-QQ -->
<view :class="['swiper-slide',slideClass]" :style="[itemStyle,customStyle]" @click.stop="onClickSlide"
:swiperItemTransform="wxsItemTransform" :change:swiperItemTransform="zSwiperWxs.wxsItemTransformObserver">
<!-- #endif -->
<slot></slot>
</view>
</template>
<!-- #ifdef MP-WEIXIN || MP-QQ -->
<script src="../../wxs/z-swiper-wxs.wxs" module="zSwiperWxs" lang="wxs"></script>
<!-- #endif -->
<script>
import {
ChildrenMixin
} from '../../libs/mixins/relation.js';
import {
getRect
} from '../../libs/utils/utils.js';
export default {
name: "z-swipe-item",
// #ifdef MP-WEIXIN
options: {
virtualHost: true
},
// #endif
mixins: [ChildrenMixin('zSwipe')],
props: {
customStyle: {
type: Object,
default: () => {
return {};
}
},
swiperItemWidth: {
type: [String, Number],
default: 0
},
swiperItemHeight: {
type: [String, Number],
default: 0
},
},
data() {
return {
wxsItemTransform: "",
itemStyle: {},
offsetLeft: 0,
offsetTop: 0,
itemClass: [],
width: 0,
height: 0,
};
},
mounted() {
this.getSize();
},
computed: {
slideClass() {
return this.itemClass.join(" ");
}
},
watch: {
swiperItemWidth: {
handler(val) {
if (val) {
this.$set(this.itemStyle, 'width', this.unitFormat(val, "rpx"))
}
},
immediate: true
},
swiperItemHeight: {
handler(val) {
if (val) {
this.$set(this.itemStyle, 'height', this.unitFormat(val, "rpx"))
}
},
immediate: true
}
},
methods: {
unitFormat(val, type) {
if (type == "rpx") {
if (val.includes("rpx") || val.includes("px")) {
return val;
} else {
return val + 'px';
}
}
if (type == "number") {
if (val.includes("rpx")) {
return uni.upx2px(parseInt(val.replace("rpx", "")))
} else if (!val.includes("rpx") && val.includes("px")) {
return parseInt(val.replace("px", ""))
} else {
return val;
}
}
},
onClickSlide(event) {
this.$emit("click", {
event,
index: this.index
});
this.parent.swiper.updateClickedSlide(this.index);
this.parent.swiper.emit("slideClick", this.index);
},
transform(value) {
// #ifndef MP-WEIXIN || MP-QQ
this.$set(this.itemStyle, 'transform', value)
// #endif
// #ifdef MP-WEIXIN || MP-QQ
this.wxsItemTransform = value
// #endif
},
transition(value) {
// #ifdef MP-BAIDU
this.$set(this.itemStyle, 'transitionDuration', `${value}ms`)
// #endif
// #ifndef MP-BAIDU
this.$set(this.itemStyle, 'transition-duration', `${value}ms`)
// #endif
},
willChange(value) {
this.$set(this.itemStyle, 'will-change', value)
},
css(value) {
Object.keys(value).forEach((item) => {
this.$set(this.itemStyle, item, value[item])
})
},
transitionEnd(callback, duration) {
setTimeout(callback, duration)
},
getSize() {
const query = uni.createSelectorQuery().in(this);
return new Promise((resolve, reject) => {
query.select('.swiper-slide').boundingClientRect(data => {
if (this.swiperItemWidth) {
this.width = this.unitFormat(this.swiperItemWidth, "number");
this.height = data.height;
}
if (this.swiperItemHeight) {
this.width = data.width;
this.height = this.unitFormat(this.swiperItemHeight, "number");
}
if (!this.swiperItemWidth && !this.swiperItemHeight) {
this.width = data.width;
this.height = data.height;
}
resolve({
width: this.width,
height: this.height
})
}).exec();
})
},
addClass(value) {
this.itemClass = Array.from(new Set([...this.itemClass, ...value.split(" ")]));
},
removeClass(value) {
this.itemClass = this.itemClass.filter(item => !value.split(" ").includes(item));
},
hasClass(value) {
return this.itemClass.includes(value);
},
nextAll() {
return this.parent.children.filter((item) => {
return item.index > this.index
})
},
prevAll() {
return this.parent.children.filter((item) => {
return item.index < this.index
}).reverse()
},
}
}
</script>
<style scoped lang="scss">
@import '../../libs/core.scss';
</style>
<template>
<view :id="'swiper'+_uid"
:class="['swiper',contentClass,containerClasses,options.direction === 'vertical'?'swiper-vertical':'']"
:style="[customStyle]">
<!-- #ifndef MP-WEIXIN || MP-QQ -->
<view :class="['swiper-wrapper']" :style="[wrapperStyle]" @click="onClickWrapper" @touchstart="onTouchStart"
@touchmove="onTouchMove" @touchend="onTouchEnd" @touchcancel="onTouchEnd">
<!-- #endif -->
<!-- #ifdef MP-WEIXIN || MP-QQ -->
<view :class="['swiper-wrapper']" :style="[wrapperStyle]" @click="onClickWrapper"
@touchstart="zSwiperWxs.onTouchStartWxs" @touchmove="zSwiperWxs.onTouchMoveWxs"
@touchend="zSwiperWxs.onTouchEndWxs" @touchcancel="zSwiperWxs.onTouchEndWxs"
:swiperTransform="wxsTransform" :change:swiperTransform="zSwiperWxs.wxsTransformObserver">
<!-- #endif -->
<slot></slot>
<!-- 在loop模式下,为group填充空白slide -->
<template v-if="loopBlankShow">
<z-swiper-item v-for="(item,index) in loopBlankNumber" :key="index">
</z-swiper-item>
</template>
<template v-if="cubeShadowShowWrapper">
<view class="swiper-cube-shadow" :style="[cubeShadowStyle]"></view>
</template>
</view>
<template v-if="cubeShadowShowRoot">
<view class="swiper-cube-shadow" :style="[cubeShadowStyle]"></view>
</template>
<slot name="indicator"></slot>
<template v-if="showIndicators">
<view :class="['swiper-pagination',paginationClass]" :style="[paginationStyle]">
<template v-if="paginationType == 'bullets'">
<view v-for="(item,index) in paginationContent" :key="index"
:class="[item.classContent.join(' ')]" :style="[item.styleContent]"
@click="paginationItemClick(index)">
</view>
</template>
<template v-if="paginationType == 'fraction'">
<text :class="paginationContent.currentClass">{{paginationContent.text}}</text>/<text
:class="paginationContent.totalClass">{{paginationContent.total}}</text>
</template>
<template v-if="paginationType == 'progressbar'">
<text :class="paginationContent.progressbarFillClass"
:style="[paginationContent.styleContent]"></text>
</template>
</view>
</template>
<template v-if="(showPrevButton||showPrevButtonSlot)">
<view :class="['swiper-button-prev',prevClass]" @click="prevClick">
<view v-if="!showPrevButtonSlot" class="zebra-icon zebra-icon-circle_chevron_left"></view>
<slot v-else name="pre-button"></slot>
</view>
</template>
<template v-if="(showNextButton||showNextButtonSlot)">
<view :class="['swiper-button-next',nextClass]" @click="nextClick">
<view v-if="!showNextButtonSlot" class="zebra-icon zebra-icon-circle_chevron_right"></view>
<slot v-else name="next-button"></slot>
</view>
</template>
<template v-if="scrollbarShow">
<view :class="['swiper-scrollbar',scrollbarClass]" :style="[scrollbarStyle]"
@click.stop="onClickScrollbar" @touchstart.stop="onTouchStartScrollbar"
@touchmove.stop.prevent="onTouchMoveScrollbar" @touchend.stop="onTouchEndScrollbar">
<view class="swiper-scrollbar-drag" :style="[scrollbarItemStyle]">
</view>
</view>
</template>
</view>
</template>
<!-- #ifdef MP-WEIXIN || MP-QQ -->
<script src="../../wxs/z-swiper-wxs.wxs" module="zSwiperWxs" lang="wxs"></script>
<!-- #endif -->
<script>
import {
getAllRect,
getRect
} from '../../libs/utils/utils.js';
// vue2
import {
getParams
} from '../../libs/vue2/get-params.js';
import {
initSwiper,
mountSwiper
} from '../../libs/vue2/init-swiper.js';
import {
needsScrollbar,
needsNavigation,
needsPagination,
uniqueClasses,
extend,
} from '../../libs/vue2/utils.js';
import {
renderLoop,
calcLoopedSlides
} from '../../libs/vue2/loop.js';
import {
getChangedParams
} from '../../libs/vue2/get-changed-params.js';
import {
updateSwiper
} from '../../libs/vue2/update-swiper.js';
import {
renderVirtual,
updateOnVirtualData
} from '../../libs/vue2/virtual.js';
//mixin
import {
ParentMixin
} from '../../libs/mixins/relation.js';
export default {
name: "z-swipe",
// #ifdef MP-WEIXIN
options: {
virtualHost: true
},
// #endif
mixins: [
ParentMixin('zSwipe')
],
// #ifdef VUE3
emits: ['update:modelValue', 'touch-start', 'touch-move', 'touch-end', 'transitionend', 'slideClick',
'_beforeBreakpoint',
'_containerClasses',
'_slideClass',
'_slideClasses', '_swiper',
'activeIndexChange', 'afterInit', 'autoplay', 'autoplayStart', 'autoplayStop', 'autoplayPause',
'autoplayResume', 'beforeDestroy', 'beforeInit', 'beforeLoopFix', 'beforeResize', 'beforeSlideChangeStart',
'beforeTransitionStart', 'breakpoint', 'changeDirection', 'click', 'disable', 'doubleTap', 'doubleClick',
'destroy', 'enable', 'fromEdge', 'hashChange', 'hashSet', 'imagesReady', 'init', 'keyPress',
'lazyImageLoad', 'lazyImageReady', 'lock', 'loopFix', 'momentumBounce', 'navigationHide', 'navigationShow',
'observerUpdate', 'orientationchange', 'paginationHide', 'paginationRender', 'paginationShow',
'paginationUpdate', 'progress', 'reachBeginning', 'reachEnd', 'realIndexChange', 'resize', 'scroll',
'scrollbarDragEnd', 'scrollbarDragMove', 'scrollbarDragStart', 'setTransition', 'setTranslate',
'slideChange', 'slideChangeTransitionEnd', 'slideChangeTransitionStart', 'slideNextTransitionEnd',
'slideNextTransitionStart', 'slidePrevTransitionEnd', 'slidePrevTransitionStart',
'slideResetTransitionStart', 'slideResetTransitionEnd', 'sliderMove', 'sliderFirstMove',
'slidesLengthChange', 'slidesGridLengthChange', 'snapGridLengthChange', 'snapIndexChange', 'swiper', 'tap',
'toEdge', 'touchEnd', 'touchMove', 'touchMoveOpposite', 'touchStart', 'transitionEnd', 'transitionStart',
'unlock', 'update', 'zoomChange', 'beforeMount'
],
// #endif
props: {
customStyle: {
type: Object,
default: () => {
return {};
}
},
options: {
type: Object,
default: () => {
return {}
}
},
// #ifdef VUE2
value: {
type: Array,
default: () => {
return []
}
},
// #endif
// #ifdef VUE3
modelValue: {
type: Array,
default: () => {
return []
}
}
// #endif
},
data() {
return {
wxsTransform: "",
wrapperStyle: {},
contentClass: '',
nextElClass: [],
prevElClass: [],
paginationElClass: [],
paginationItemElClass: [],
loopBlankShow: false,
loopBlankNumber: 0,
cubeShadowShowWrapper: false,
cubeShadowShowRoot: false,
cubeShadowStyle: {},
eventsListeners: {},
showPrevButton: false,
showPrevButtonSlot: false,
showNextButton: false,
showNextButtonSlot: false,
showIndicators: false,
paginationContent: [],
paginationType: '',
paginationStyle: {},
scrollbarElClass: [],
scrollbarStyle: {},
scrollbarItemStyle: {},
rectInfo: null,
// vue2
containerClasses: 'swiper',
virtualData: null,
firstLoad: true,
originalDataList: [],
loopUpdateData: false
};
},
computed: {
// #ifdef VUE3
value() {
return this.modelValue
},
// #endif
// #ifdef VUE3
_uid() {
return this._.uid
},
// #endif
nextClass() {
return this.nextElClass.join(" ");
},
prevClass() {
return this.prevElClass.join(" ");
},
paginationClass() {
return this.paginationElClass.join(" ");
},
paginationItemClass() {
return this.paginationItemElClass.join(" ");
},
scrollbarClass() {
return this.scrollbarElClass.join(" ");
},
scrollbarShow() {
return needsScrollbar(this.options)
}
},
created() {
const {
params: swiperParams,
passedParams
} = getParams(this.options);
this.swiperElRef = 'swiper';
this.swiperParams = swiperParams;
this.oldPassedParamsRef = passedParams;
let slidesRef = this.slidesRef;
swiperParams.onAny = (event, ...args) => {
// #ifdef MP
// 字节小程序此处报错,因此无法使用v-on监听事件
// #ifndef MP-TOUTIAO
this.$emit(event, {}, ...args.filter((item, index) => {
return index > 0
}));
// #endif
// #endif
// #ifndef MP
this.$emit(event, ...args);
// #endif
};
Object.assign(swiperParams.on, {
_containerClasses(swiper, classes) {
this.containerClasses = classes;
},
});
this.$watch(() => {
return {
value: this.value,
options: this.options
}
}, (val) => {
// virtual模式处理
if (this.swiperParams && this.swiperParams.virtual) {
if (!this.virtualData && val.options.virtual.slides.length) {
this.swiperParams.virtual.slides = val.options.virtual.slides;
// this.swiperParams.virtual.slides = val.value;
const extendWith = {
cache: false,
slides: val.options.virtual.slides,
// slides: val.value,
renderExternal: data => {
console.log("最终数据", data)
this.virtualData = data;
this.$emit("input", data.slides);
// updateOnVirtualData(this.swiper);
},
renderExternalUpdate: false
};
extend(this.swiperParams.virtual, extendWith);
// this.$emit("input", [val.options.virtual.slides[0]]);
// this.virtualData = [val.options.virtual.slides[0]];
this.loadSwiper();
// console.log(this.swiper)
}
// extend(swiperRef.originalParams.virtual, extendWith);
}
// loop模式处理
if (this.swiperParams && this.swiperParams.loop) {
if (this.originalDataList.length && (this.originalDataList.toString() == val.value
.toString())) {
this.loopUpdateData = true;
// 百度小程序watch晚于子组件加载
// #ifdef MP-BAIDU
if (this.firstLoad) {
this.loadSwiper();
}
// #endif
} else {
this.loopUpdateData = false;
let slides = renderLoop(this, this.swiperParams, this.value);
if (this.swiperParams.loop && !this.loopUpdateData && slides.data.toString() !=
val.value.toString()) {
this.loopUpdateData = true;
// #ifdef VUE2
this.$emit("input", slides.data)
// #endif
// #ifdef VUE3
this.$emit("update:modelValue", slides.data)
// #endif
return
}
}
}
if (this.swiper && !this.firstLoad) {
if (this.virtualData && val.options.virtual.type == "cut") {
const style = this.swiper.isHorizontal() ? {
[this.swiper.rtlTranslate ? 'right' :
'left'
]: `${this.virtualData.offset}px`
} : {
top: `${this.virtualData.offset}px`
};
this.children
// .filter((slide, index) => index >= this.virtualData.from && index <= this
// .virtualData
// .to)
.map(slide => {
slide.css(style)
// if (!slide.props) slide.props = {};
// if (!slide.props.style) slide.props.style = {};
// slide.props.swiperRef = swiperRef;
// slide.props.style = style;
// return h(slide.type, {
// ...slide.props
// }, slide.children);
});
}
this.updateSwiper(val.value, val.options, this.children);
}
}, {
deep: true,
immediate: true
})
this.$watch(() => {
return this.$data
}, (val) => {
if (this.swiper && this.swiper.native) {
Object.assign(this.swiper.native, {
val
});
}
}, {
deep: true
})
this.$watch(() => {
return this.virtualData
}, (val) => {
if (this.swiper && this.virtualData) {
updateOnVirtualData(this.swiper);
}
}, {
deep: true
})
uni.$on("childrenReady" + this._uid, async (children) => {
children.dataSwiperSlideIndex = children.index;
if (this.children.length == this.value.length) {
Promise.all(this.children.map((item) => {
return item.getSize();
})).then((res) => {
if (this.swiperParams && this.swiperParams.loop) {
if (this.originalDataList.length && (this.originalDataList
.toString() == this.value
.toString())) {
if (this.firstLoad) {
this.loadSwiper();
}
} else {
return
}
} else {
if (this.firstLoad) {
this.loadSwiper();
}
}
this.updateSwiper(this.value, this.options, this.children);
})
}
})
},
// #ifdef VUE2
beforeDestroy() {
if (this.swiper && !this.swiper.destroyed) {
this.swiper.destroy(true, false);
}
},
// #endif
// #ifdef VUE3
beforeUnmount() {
if (this.swiper && !this.swiper.destroyed) {
this.swiper.destroy(true, false);
}
},
// #endif
methods: {
loadSwiper() {
let swiperParams = this.swiperParams;
this.slidesRef = this.children;
this.oldSlidesRef = this.slidesRef;
let swiperRef = initSwiper(swiperParams, {
...this.$data,
...this.$props,
swiperElId: 'swiper' + this._uid,
emit: this.emit.bind(this),
updateData: this.updateData.bind(this),
getRect: this.getRect.bind(this),
getRectScrollbar: this.getRectScrollbar.bind(this),
willChange: this.willChange.bind(this),
transform: this.transform.bind(this),
transition: this.transition.bind(this),
scrollbarTransform: this.scrollbarTransform.bind(this),
scrollbarTransition: this.scrollbarTransition.bind(this),
scrollbarItemTransform: this.scrollbarItemTransform.bind(this),
scrollbarItemTransition: this.scrollbarItemTransition.bind(this),
addClass: this.addClass.bind(this),
removeClass: this.removeClass.bind(this),
addPaginationClass: this.addPaginationClass.bind(this),
removePaginationClass: this.removePaginationClass.bind(this),
addScrollbarClass: this.addScrollbarClass.bind(this),
removeScrollbarClass: this.removeScrollbarClass.bind(this),
setCss: this.setCss.bind(this),
css: this.setCss.bind(this),
paginationCss: this.setPaginationCss.bind(this),
scrollbarCss: this.scrollbarCss.bind(this),
scrollbarItemCss: this.scrollbarItemCss.bind(this),
addNextElClass: this.addNextElClass.bind(this),
addPrevElClass: this.addPrevElClass.bind(this),
removeNextElClass: this.removeNextElClass.bind(this),
removePrevElClass: this.removePrevElClass.bind(this),
cubeShadowCss: this.cubeShadowCss.bind(this),
cubeShadowTransform: this.cubeShadowTransform.bind(this),
cubeShadowTransition: this.cubeShadowTransition.bind(this),
});
this.swiper = swiperRef;
swiperRef.loopCreate = () => {};
swiperRef.loopDestroy = () => {};
if (swiperParams.loop) {
swiperRef.loopedSlides = calcLoopedSlides(this.slidesRef, swiperParams);
}
if (!this.swiper) return;
mountSwiper({
el: this.swiperElRef,
nextEl: this.nextElRef,
prevEl: this.prevElRef,
paginationEl: this.paginationElRef,
scrollbarEl: this.scrollbarElRef,
swiper: this.swiper,
},
this.swiperParams,
);
this.$emit('swiper');
this.firstLoad = false;
},
updateSwiper(value, options, children) {
this.swiper.slides = children;
this.slidesRef = children;
let initializedRef = this.initializedRef;
let swiperRef = this.swiper;
let slidesRef = this.slidesRef;
let oldPassedParamsRef = this.oldPassedParamsRef;
let oldSlidesRef = this.oldSlidesRef;
let breakpointChanged = this.breakpointChanged;
let nextElRef = this.nextElRef;
let prevElRef = this.prevElRef;
let paginationElRef = this.paginationElRef;
let scrollbarElRef = this.scrollbarElRef;
// set initialized flag
if (!initializedRef && swiperRef) {
swiperRef.emitSlidesClasses();
initializedRef = true;
}
// watch for params change
const {
passedParams: newPassedParams
} = getParams(options);
const changedParams = getChangedParams(
newPassedParams,
oldPassedParamsRef,
slidesRef,
oldSlidesRef,
);
this.oldPassedParamsRef = newPassedParams;
this.oldSlidesRef = slidesRef;
if (
(changedParams.length || breakpointChanged) &&
swiperRef &&
!swiperRef.destroyed
) {
updateSwiper({
swiper: swiperRef,
slides: slidesRef,
passedParams: newPassedParams,
changedParams,
nextEl: nextElRef,
prevEl: prevElRef,
scrollbarEl: scrollbarElRef,
paginationEl: paginationElRef,
});
}
breakpointChanged = false;
},
emit(event, data) {
this.$emit(event, ...data)
},
async getRect() {
let rectInfo = await getRect(this, '.swiper');
this.rectInfo = rectInfo;
return rectInfo;
},
async getRectScrollbar() {
let rectInfo = await getRect(this, '.swiper-scrollbar');
return rectInfo;
},
updateData(value) {
Object.keys(value).forEach((item) => {
this.$set(this, item, value[item])
})
},
willChange(value) {
this.$set(this.wrapperStyle, 'will-change', value)
},
transform(value) {
// #ifndef MP-WEIXIN || MP-QQ
this.$set(this.wrapperStyle, 'transform', value)
// #endif
// #ifdef MP-WEIXIN || MP-QQ
this.wxsTransform = value;
// #endif
},
transition(value) {
// #ifdef MP-BAIDU
this.$set(this.wrapperStyle, 'transitionDuration', `${value}ms`)
// #endif
// #ifndef MP-BAIDU
this.$set(this.wrapperStyle, 'transition-duration', `${value}ms`)
// #endif
},
setCss(value) {
Object.keys(value).forEach((item) => {
this.$set(this.wrapperStyle, item, value[item])
})
},
scrollbarTransform(value) {
this.$set(this.scrollbarStyle, 'transform', value)
},
scrollbarTransition(value) {
this.$set(this.scrollbarStyle, 'transitionDuration', `${value}ms`)
},
scrollbarItemTransform(value) {
this.$set(this.scrollbarItemStyle, 'transform', value)
},
scrollbarItemTransition(value) {
this.$set(this.scrollbarItemStyle, 'transitionDuration', `${value}ms`)
},
addClass(value) {
// #ifdef MP-ALIPAY || MP-TOUTIAO
this.contentClass = Array.from(new Set([...this.contentClass.split(" "), ...value.split(" ")])).join(" ");
// #endif
// #ifndef MP-ALIPAY || MP-TOUTIAO
this.contentClass = Array.from(new Set([...this.contentClass, ...value.split(" ")]));
// #endif
},
removeClass(value) {
// #ifdef MP-ALIPAY || MP-TOUTIAO
this.contentClass = this.contentClass.split(" ").filter(item => !value.split(" ").includes(item)).join(
" ");
// #endif
// #ifndef MP-ALIPAY || MP-TOUTIAO
this.contentClass = this.contentClass.filter(item => !value.split(" ").includes(item));
// #endif
},
addPaginationClass(value) {
this.paginationElClass = Array.from(new Set([...this.paginationElClass, ...value.split(" ")]));
},
removePaginationClass(value) {
this.paginationElClass = this.paginationElClass.filter(item => !value.split(" ").includes(item));
},
addScrollbarClass(value) {
this.scrollbarElClass = Array.from(new Set([...this.scrollbarElClass, ...value.split(" ")]));
},
removeScrollbarClass(value) {
this.scrollbarElClass = this.scrollbarElClass.filter(item => !value.split(" ").includes(item));
},
setPaginationCss(value) {
Object.keys(value).forEach((item) => {
this.$set(this.paginationStyle, item, value[item])
})
},
scrollbarCss(value) {
Object.keys(value).forEach((item) => {
this.$set(this.scrollbarStyle, item, value[item])
})
},
scrollbarItemCss(value) {
Object.keys(value).forEach((item) => {
this.$set(this.scrollbarItemStyle, item, value[item])
})
},
addNextElClass(value) {
this.nextElClass = Array.from(new Set([...this.nextElClass, ...value.split(" ")]));
},
addPrevElClass(value) {
this.prevElClass = Array.from(new Set([...this.prevElClass, ...value.split(" ")]));
},
removeNextElClass(value) {
this.nextElClass = this.nextElClass.filter(item => !value.split(" ").includes(item));
},
removePrevElClass(value) {
this.prevElClass = this.prevElClass.filter(item => !value.split(" ").includes(item));
},
setSwiperOn(event, callback) {
if (!this.eventsListeners[event]) this.eventsListeners[event] = {};
this.eventsListeners[event] = callback;
},
paginationItemClick(index) {
this.swiper.emit("paginationItemClick", index)
},
prevClick() {
this.swiper.emit("prevClick");
},
nextClick() {
this.swiper.emit("nextClick");
},
onTouchStart(event) {
this.swiper.onTouchStart(event);
},
onTouchStartSwiperWxs(event) {
this.swiper.onTouchStart(event);
},
onTouchMove(event) {
this.swiper.onTouchMove(event);
},
onTouchMoveSwiperWxs(event) {
this.swiper.onTouchMove(event);
},
onTouchEnd(event) {
this.swiper.onTouchEnd(event);
},
onTouchEndSwiperWxs(event) {
this.swiper.onTouchEnd(event);
},
onClickWrapper(event) {
this.$emit("click", event);
},
onClickScrollbar(event) {
this.$emit("scrollbarClick", event);
},
onTouchStartScrollbar(event) {
this.swiper.emit('touchStartScrollbar', event);
},
onTouchMoveScrollbar(event) {
this.swiper.emit('touchMoveScrollbar', event);
},
onTouchEndScrollbar(event) {
this.swiper.emit('touchEndScrollbar', event);
},
cubeShadowCss(value) {
Object.keys(value).forEach((item) => {
this.$set(this.cubeShadowStyle, item, value[item])
})
},
cubeShadowTransform(value) {
this.$set(this.cubeShadowStyle, 'transform', value)
},
cubeShadowTransition(value) {
this.$set(this.cubeShadowStyle, 'transitionDuration', `${value}ms`)
},
}
}
</script>
<style scoped lang="scss">
@import '../../libs/core.scss';
@import "../../static/css/iconfont.css";
.swiper {
&__prev--button {
position: absolute;
left: 30rpx;
top: 50%;
display: flex;
color: #1989fa;
font-size: 44rpx;
z-index: 10;
}
&__prev--button--disable {
position: absolute;
left: 30rpx;
top: 50%;
display: flex;
color: #1989fa;
font-size: 44rpx;
opacity: .35;
z-index: 10;
}
&__next--button {
position: absolute;
right: 30rpx;
top: 50%;
display: flex;
color: #1989fa;
font-size: 44rpx;
z-index: 10;
}
&__next--button--disable {
position: absolute;
right: 30rpx;
top: 50%;
display: flex;
color: #1989fa;
font-size: 44rpx;
opacity: .35;
z-index: 10;
}
}
</style>
<!-- uni_modules发布插件时,components中必须有一个和父级名称一致的组件,否则提示指定目录不存在,这样做的具体原因未知。故此文件为无用文件,仅做为上传插件时消除错误使用。 -->
<template>
</template>
<script>
</script>
<style>
</style>
import Swiper from "./libs/core.js";
import Autoplay from './modules/autoplay/autoplay.js';
import FreeMode from './modules/free-mode/free-mode.js';
import EffectFade from './modules/effect-fade/effect-fade.js';
import EffectCube from './modules/effect-cube/effect-cube.js';
import EffectCoverflow from './modules/effect-coverflow/effect-coverflow.js';
import EffectFlip from './modules/effect-flip/effect-flip.js';
import EffectCards from './modules/effect-cards/effect-cards.js';
import EffectCreative from './modules/effect-creative/effect-creative.js';
import EffectPanorama from './modules/effect-panorama/effect-panorama.js';
import EffectCarousel from './modules/effect-carousel/effect-carousel.js';
import Navigation from './modules/navigation/navigation.js';
import Pagination from './modules/pagination/pagination.js';
import Thumbs from './modules/thumbs/thumbs.js';
import Scrollbar from './modules/scrollbar/scrollbar.js';
import Virtual from './modules/virtual/virtual.js';
import WillChange from './modules/will-change/will-change.js';
export {
default as Swiper,
default
}
from './libs/core.js';
const modules = [Autoplay, FreeMode, EffectFade, EffectCube, EffectCoverflow, EffectFlip, EffectCards, EffectCreative,
EffectPanorama, EffectCarousel, Navigation, Pagination, Thumbs, Scrollbar, WillChange, Virtual
];
Swiper.use(modules);
function checkOverflow() {
const swiper = this;
const {
isLocked: wasLocked,
params
} = swiper;
const {
slidesOffsetBefore
} = params;
if (slidesOffsetBefore) {
const lastSlideIndex = swiper.slides.length - 1;
const lastSlideRightEdge = swiper.slidesGrid[lastSlideIndex] + swiper.slidesSizesGrid[lastSlideIndex] +
slidesOffsetBefore * 2;
swiper.isLocked = swiper.size > lastSlideRightEdge;
} else {
swiper.isLocked = swiper.snapGrid.length === 1;
}
if (params.allowSlideNext === true) {
swiper.allowSlideNext = !swiper.isLocked;
}
if (params.allowSlidePrev === true) {
swiper.allowSlidePrev = !swiper.isLocked;
}
if (wasLocked && wasLocked !== swiper.isLocked) {
swiper.isEnd = false;
}
if (wasLocked !== swiper.isLocked) {
swiper.emit(swiper.isLocked ? 'lock' : 'unlock');
}
}
export default {
checkOverflow
};
function prepareClasses(entries, prefix) {
const resultClasses = [];
entries.forEach(item => {
if (typeof item === 'object') {
Object.keys(item).forEach(classNames => {
if (item[classNames]) {
resultClasses.push(prefix + classNames);
}
});
} else if (typeof item === 'string') {
resultClasses.push(prefix + item);
}
});
return resultClasses;
}
export default function addClasses() {
const swiper = this;
const {
classNames,
params,
rtl,
$el,
device,
support
} = swiper; // prettier-ignore
const suffixes = prepareClasses(['initialized', params.direction, {
'pointer-events': !support.touch
}, {
'free-mode': swiper.params.freeMode && params.freeMode.enabled
}, {
'autoheight': params.autoHeight
}, {
'rtl': rtl
}, {
'grid': params.grid && params.grid.rows > 1
}, {
'grid-column': params.grid && params.grid.rows > 1 && params.grid.fill === 'column'
}, {
'android': device.android
}, {
'ios': device.ios
}, {
'css-mode': params.cssMode
}, {
'centered': params.cssMode && params.centeredSlides
}], params.containerModifierClass);
classNames.push(...suffixes);
$el.addClass([...classNames].join(' '));
swiper.emitContainerClasses();
}
\ No newline at end of file
import addClasses from './addClasses.js';
import removeClasses from './removeClasses.js';
export default {
addClasses,
removeClasses
};
\ No newline at end of file
export default function removeClasses() {
const swiper = this;
const {
$el,
classNames
} = swiper;
$el.removeClass(classNames.join(' '));
swiper.emitContainerClasses();
}
\ No newline at end of file
import {
extend,
now,
deleteProps
} from '../shared/utils.js';
import {
getSupport
} from '../shared/get-support.js';
import {
getDevice
} from '../shared/get-device.js';
import {
getBrowser
} from '../shared/get-browser.js';
import moduleExtendParams from './moduleExtendParams.js';
import eventsEmitter from './events-emitter.js';
import update from './update/index.js';
import translate from './translate/index.js';
import transition from './transition/index.js';
import defaults from './defaults.js';
import classes from './classes/index.js';
import checkOverflow from './check-overflow/index.js';
import slide from './slide/index.js';
import loop from './loop/index.js';
import grabCursor from './grab-cursor/index.js';
import events from './events/index.js';
import {
getRect
} from './utils/utils.js';
const prototypes = {
eventsEmitter,
update,
checkOverflow,
slide,
loop,
translate,
transition,
grabCursor,
events,
classes
};
const extendedDefaults = {};
class Swiper {
constructor(...args) {
const swiper = this;
let params;
let el;
let native;
if (args.length === 1 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -1) ===
'Object') {
params = args[0];
} else if (args.length === 2 && args[0].constructor && Object.prototype.toString.call(args[0]).slice(8, -
1) ===
'Object') {
params = args[0];
native = args[1];
} else {
[el, params, native] = args;
}
if (!params) params = {};
params = extend({}, params);
if (el && !params.el) params.el = el;
// Swiper Instance
swiper.__swiper__ = true;
swiper.support = getSupport();
swiper.device = getDevice({
userAgent: params.userAgent
});
swiper.browser = getBrowser();
swiper.eventsListeners = {};
swiper.eventsAnyListeners = [];
swiper.modules = [...swiper.__modules__];
swiper.native = native;
if (params.modules && Array.isArray(params.modules)) {
swiper.modules.push(...params.modules);
}
const allModulesParams = {};
swiper.modules.forEach(mod => {
mod({
swiper,
extendParams: moduleExtendParams(params, allModulesParams),
on: swiper.on.bind(swiper),
once: swiper.once.bind(swiper),
off: swiper.off.bind(swiper),
emit: swiper.emit.bind(swiper)
});
}); // Extend defaults with modules params
const swiperParams = extend({}, defaults, allModulesParams); // Extend defaults with passed params
swiper.params = extend({}, swiperParams, extendedDefaults, params);
swiper.originalParams = extend({}, swiper.params);
swiper.passedParams = extend({}, params); // add event listeners
if (swiper.params && swiper.params.on) {
Object.keys(swiper.params.on).forEach(eventName => {
swiper.on(eventName, swiper.params.on[eventName]);
});
}
if (swiper.params && swiper.params.onAny) {
swiper.onAny(swiper.params.onAny);
} // Save Dom lib
Object.assign(swiper, {
enabled: swiper.params.enabled,
el,
// Classes
classNames: [],
// Slides
slides: [],
slidesGrid: [],
snapGrid: [],
slidesSizesGrid: [],
// isDirection
isHorizontal() {
return swiper.params.direction === 'horizontal';
},
isVertical() {
return swiper.params.direction === 'vertical';
},
// Indexes
activeIndex: 0,
realIndex: 0,
//
isBeginning: true,
isEnd: false,
// Props
translate: 0,
previousTranslate: 0,
progress: 0,
velocity: 0,
animating: false,
// Locks
allowSlideNext: swiper.params.allowSlideNext,
allowSlidePrev: swiper.params.allowSlidePrev,
// Touch Events
touchEvents: function touchEvents() {
const touch = ['touchstart', 'touchmove', 'touchend', 'touchcancel'];
const desktop = ['pointerdown', 'pointermove', 'pointerup'];
swiper.touchEventsTouch = {
start: touch[0],
move: touch[1],
end: touch[2],
cancel: touch[3]
};
swiper.touchEventsDesktop = {
start: desktop[0],
move: desktop[1],
end: desktop[2]
};
return swiper.support.touch || !swiper.params.simulateTouch ? swiper.touchEventsTouch :
swiper.touchEventsDesktop;
}(),
touchEventsData: {
isTouched: undefined,
isMoved: undefined,
allowTouchCallbacks: undefined,
touchStartTime: undefined,
isScrolling: undefined,
currentTranslate: undefined,
startTranslate: undefined,
allowThresholdMove: undefined,
// Form elements to match
focusableElements: swiper.params.focusableElements,
// Last click time
lastClickTime: now(),
clickTimeout: undefined,
// Velocities
velocities: [],
allowMomentumBounce: undefined,
isTouchEvent: undefined,
startMoving: undefined
},
// Clicks
allowClick: true,
// Touches
allowTouchMove: swiper.params.allowTouchMove,
touches: {
startX: 0,
startY: 0,
currentX: 0,
currentY: 0,
diff: 0
},
// Images
imagesToLoad: [],
imagesLoaded: 0,
virtualList: [],
virtualIndexList: [],
});
swiper.emit('_swiper'); // Init
if (swiper.params.init) {
swiper.init();
} // Return app instance
return swiper;
}
enable() {
const swiper = this;
if (swiper.enabled) return;
swiper.enabled = true;
if (swiper.params.grabCursor) {
swiper.setGrabCursor();
}
swiper.emit('enable');
}
disable() {
const swiper = this;
if (!swiper.enabled) return;
swiper.enabled = false;
if (swiper.params.grabCursor) {
swiper.unsetGrabCursor();
}
swiper.emit('disable');
}
setProgress(progress, speed) {
const swiper = this;
progress = Math.min(Math.max(progress, 0), 1);
const min = swiper.minTranslate();
const max = swiper.maxTranslate();
const current = (max - min) * progress + min;
swiper.translateTo(current, typeof speed === 'undefined' ? 0 : speed);
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
emitContainerClasses() {
const swiper = this;
if (!swiper.params._emitClasses || !swiper.el) return;
const cls = swiper.native.contentClass.split(' ').filter(className => {
return className.indexOf('swiper') === 0 || className.indexOf(swiper.params
.containerModifierClass) === 0;
});
swiper.emit('_containerClasses', cls.join(' '));
}
getSlideClasses(slideEl) {
const swiper = this;
return slideEl.slideClass.split(' ').filter(className => {
return className.indexOf('swiper-slide') === 0 || className.indexOf(swiper.params
.slideClass) === 0;
}).join(' ');
}
emitSlidesClasses() {
const swiper = this;
if (!swiper.params._emitClasses || !swiper.el) return;
const updates = [];
swiper.slides.forEach(slideEl => {
const classNames = swiper.getSlideClasses(slideEl);
updates.push({
slideEl,
classNames
});
swiper.emit('_slideClass', slideEl, classNames);
});
swiper.emit('_slideClasses', updates);
}
slidesPerViewDynamic(view = 'current', exact = false) {
const swiper = this;
const {
params,
slides,
slidesGrid,
slidesSizesGrid,
size: swiperSize,
activeIndex
} = swiper;
let spv = 1;
if (params.centeredSlides) {
let slideSize = slides[activeIndex].swiperSlideSize;
let breakLoop;
for (let i = activeIndex + 1; i < slides.length; i += 1) {
if (slides[i] && !breakLoop) {
slideSize += slides[i].swiperSlideSize;
spv += 1;
if (slideSize > swiperSize) breakLoop = true;
}
}
for (let i = activeIndex - 1; i >= 0; i -= 1) {
if (slides[i] && !breakLoop) {
slideSize += slides[i].swiperSlideSize;
spv += 1;
if (slideSize > swiperSize) breakLoop = true;
}
}
} else {
// eslint-disable-next-line
if (view === 'current') {
for (let i = activeIndex + 1; i < slides.length; i += 1) {
const slideInView = exact ?
slidesGrid[i] + slidesSizesGrid[i] - slidesGrid[activeIndex] < swiperSize :
slidesGrid[i] - slidesGrid[activeIndex] < swiperSize;
if (slideInView) {
spv += 1;
}
}
} else {
// previous
for (let i = activeIndex - 1; i >= 0; i -= 1) {
const slideInView = slidesGrid[activeIndex] - slidesGrid[i] < swiperSize;
if (slideInView) {
spv += 1;
}
}
}
}
return spv;
}
changeDirection(newDirection, needUpdate) {
if (needUpdate === void 0) {
needUpdate = true;
}
const swiper = this;
const currentDirection = swiper.params.direction;
if (!newDirection) {
// eslint-disable-next-line
newDirection = currentDirection === 'horizontal' ? 'vertical' : 'horizontal';
}
if (newDirection === currentDirection || newDirection !== 'horizontal' && newDirection !== 'vertical') {
return swiper;
}
swiper.$wrapperEl.removeClass(`${swiper.params.containerModifierClass}${currentDirection}`)
swiper.$wrapperEl.addClass(
`${swiper.params.containerModifierClass}${newDirection}`);
swiper.emitContainerClasses();
swiper.params.direction = newDirection;
swiper.slides.forEach(slideEl => {
if (newDirection === 'vertical') {
slideEl.css({
width: ''
})
} else {
slideEl.css({
height: ''
})
}
});
swiper.emit('changeDirection');
if (needUpdate) swiper.update();
return swiper;
}
async update(el) {
const swiper = this;
if (!swiper || swiper.destroyed) return;
const {
snapGrid,
params
} = swiper; // Breakpoints
el = await swiper.native.getRect();
if (!el) {
return false;
}
Object.assign(swiper, {
el,
$el: swiper.native,
});
swiper.emit('beforeUpdate');
if (params.breakpoints) {
swiper.setBreakpoint();
}
swiper.updateSize();
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
function setTranslate() {
const translateValue = swiper.rtlTranslate ? swiper.translate * -1 : swiper.translate;
const newTranslate = Math.min(Math.max(translateValue, swiper.maxTranslate()), swiper.minTranslate());
swiper.setTranslate(newTranslate);
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
let translated;
if (swiper.params.freeMode && swiper.params.freeMode.enabled) {
setTranslate();
if (swiper.params.autoHeight) {
swiper.updateAutoHeight();
}
} else {
if ((swiper.params.slidesPerView === 'auto' || swiper.params.slidesPerView > 1) && swiper.isEnd && !
swiper.params.centeredSlides) {
translated = swiper.slideTo(swiper.slides.length - 1, 0, false, true);
} else {
translated = swiper.slideTo(swiper.activeIndex, 0, false, true);
}
if (!translated) {
setTranslate();
}
}
if (params.watchOverflow && snapGrid !== swiper.snapGrid) {
swiper.checkOverflow();
}
swiper.emit('update');
}
async mount(el) {
const swiper = this;
if (swiper.mounted) return true; // Find el
el = await swiper.native.getRect();
if (!el) {
return false;
}
swiper.emit('beforeMount'); // Set breakpoint
// let $wrapperEl = new DomSimulation(swiper.native);
// let $el = new DomSimulation(swiper.native);
// if (swiper.native && swiper.native.children && swiper.native.children.length) {
// swiper.native.children.forEach((item) => {
// item.$itemEl = new ChildDomSimulation(item);
// })
// }
Object.assign(swiper, {
$el: swiper.native,
el,
$wrapperEl: swiper.native,
wrapperEl: swiper.native,
mounted: true,
});
return true;
}
async init(el) {
const swiper = this;
if (swiper.initialized) return swiper;
const mounted = await swiper.mount(el);
if (mounted === false) return swiper;
swiper.emit('beforeInit'); // Set breakpoint
swiper.addClasses(); // Create loop
if (swiper.params.loop) {
swiper.loopCreate();
} // Update size
swiper.updateSize(); // Update slides
swiper.updateSlides();
if (swiper.params.watchOverflow) {
swiper.checkOverflow();
} // Set Grab Cursor
if (swiper.params.grabCursor && swiper.enabled) {
swiper.setGrabCursor();
}
// if (swiper.params.loop) {
// swiper.on("update", () => {
// swiper.slideTo(swiper.params.initialSlide + swiper.loopedSlides, 0, swiper.params
// .runCallbacksOnInit,
// false, true);
// })
// } else {
// swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
// } // Attach events
// Slide To Initial Slide
if (swiper.params.loop) {
swiper.slideTo(
swiper.params.initialSlide + swiper.loopedSlides,
0,
swiper.params.runCallbacksOnInit,
false,
true,
);
} else {
swiper.slideTo(swiper.params.initialSlide, 0, swiper.params.runCallbacksOnInit, false, true);
}
swiper.attachEvents(); // Init Flag
swiper.initialized = true; // Emit
swiper.emit('init');
swiper.emit('afterInit');
return swiper;
}
destroy(deleteInstance = true, cleanStyles = true) {
const swiper = this;
const {
params,
$el,
$wrapperEl,
slides
} = swiper;
if (typeof swiper.params === 'undefined' || swiper.destroyed) {
return null;
}
swiper.emit('beforeDestroy'); // Init Flag
swiper.initialized = false; // Detach events
swiper.detachEvents(); // Destroy loop
if (params.loop) {
swiper.loopDestroy();
} // Cleanup styles
swiper.emit('destroy'); // Detach emitter events
Object.keys(swiper.eventsListeners).forEach(eventName => {
swiper.off(eventName);
});
if (deleteInstance !== false) {
deleteProps(swiper);
}
swiper.destroyed = true;
return null;
}
static extendDefaults(newDefaults) {
extend(extendedDefaults, newDefaults);
}
static get extendedDefaults() {
return extendedDefaults;
}
static get defaults() {
return defaults;
}
static installModule(mod) {
if (!Swiper.prototype.__modules__) Swiper.prototype.__modules__ = [];
const modules = Swiper.prototype.__modules__;
if (typeof mod === 'function' && modules.indexOf(mod) < 0) {
modules.push(mod);
}
}
static use(module) {
if (Array.isArray(module)) {
module.forEach(m => Swiper.installModule(m));
return Swiper;
}
Swiper.installModule(module);
return Swiper;
}
}
Object.keys(prototypes).forEach(prototypeGroup => {
Object.keys(prototypes[prototypeGroup]).forEach(protoMethod => {
Swiper.prototype[protoMethod] = prototypes[prototypeGroup][protoMethod];
});
});
export default Swiper;
$themeColor: #007aff !default;
:root {
--swiper-theme-color: #{$themeColor};
}
.swiper {
margin-left: auto;
margin-right: auto;
position: relative;
overflow: hidden;
list-style: none;
padding: 0;
/* Fix of Webkit flickering */
z-index: 1;
}
.swiper-vertical > .swiper-wrapper {
flex-direction: column;
}
.swiper-wrapper {
position: relative;
width: 100%;
height: 100%;
z-index: 1;
display: flex;
transition-property: transform;
box-sizing: content-box;
}
.swiper-android .swiper-slide,
.swiper-wrapper {
transform: translate3d(0px, 0, 0);
}
.swiper-pointer-events {
touch-action: pan-y;
&.swiper-vertical {
touch-action: pan-x;
}
}
.swiper-slide {
flex-shrink: 0;
width: 100%;
height: 100%;
position: relative;
transition-property: transform;
}
.swiper-slide-invisible-blank {
visibility: hidden;
}
/* Auto Height */
.swiper-autoheight {
&,
.swiper-slide {
height: auto;
}
.swiper-wrapper {
align-items: flex-start;
transition-property: transform, height;
}
}
.swiper-slide-3d{
transform-style: preserve-3d;
}
/* 3D Effects */
.swiper-3d {
&,
&.swiper-css-mode .swiper-wrapper {
perspective: 1200px;
}
.swiper-wrapper,
.swiper-slide,
.swiper-slide-shadow,
.swiper-slide-shadow-left,
.swiper-slide-shadow-right,
.swiper-slide-shadow-top,
.swiper-slide-shadow-bottom,
.swiper-cube-shadow {
transform-style: preserve-3d;
}
.swiper-slide-shadow,
.swiper-slide-shadow-left,
.swiper-slide-shadow-right,
.swiper-slide-shadow-top,
.swiper-slide-shadow-bottom {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
pointer-events: none;
z-index: 10;
}
.swiper-slide-shadow {
background: rgba(0, 0, 0, 0.15);
}
.swiper-slide-shadow-left {
background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-slide-shadow-right {
background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-slide-shadow-top {
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
.swiper-slide-shadow-bottom {
background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0));
}
}
/* CSS Mode */
.swiper-css-mode {
> .swiper-wrapper {
overflow: auto;
scrollbar-width: none; /* For Firefox */
-ms-overflow-style: none; /* For Internet Explorer and Edge */
&::-webkit-scrollbar {
display: none;
}
}
> .swiper-wrapper > .swiper-slide {
scroll-snap-align: start start;
}
}
.swiper-horizontal.swiper-css-mode {
> .swiper-wrapper {
scroll-snap-type: x mandatory;
}
}
.swiper-vertical.swiper-css-mode {
> .swiper-wrapper {
scroll-snap-type: y mandatory;
}
}
.swiper-centered {
> .swiper-wrapper::before {
content: '';
flex-shrink: 0;
order: 9999;
}
&.swiper-horizontal {
> .swiper-wrapper > .swiper-slide:first-child {
margin-inline-start: var(--swiper-centered-offset-before);
}
> .swiper-wrapper::before {
height: 100%;
width: var(--swiper-centered-offset-after);
}
}
&.swiper-vertical {
> .swiper-wrapper > .swiper-slide:first-child {
margin-block-start: var(--swiper-centered-offset-before);
}
> .swiper-wrapper::before {
width: 100%;
height: var(--swiper-centered-offset-after);
}
}
> .swiper-wrapper > .swiper-slide {
scroll-snap-align: center center;
}
}
@import "../modules/effect-fade/effect-fade.scss";
@import "../modules/effect-cube/effect-cube.scss";
@import "../modules/effect-coverflow/effect-coverflow.scss";
@import "../modules/effect-flip/effect-flip.scss";
@import "../modules/effect-cards/effect-cards.scss";
@import "../modules/effect-creative/effect-creative.scss";
@import "../modules/effect-panorama/effect-panorama.scss";
@import "../modules/effect-carousel/effect-carousel.scss";
@import "../modules/navigation/navigation.scss";
@import "../modules/pagination/pagination.scss";
@import "../modules/thumbs/thumbs.scss";
@import "../modules/scrollbar/scrollbar.scss";
\ No newline at end of file
export default {
init: true,
direction: 'horizontal',
touchEventsTarget: 'wrapper',
initialSlide: 0,
speed: 300,
cssMode: false,
updateOnWindowResize: true,
resizeObserver: true,
nested: false,
createElements: false,
enabled: true,
focusableElements: 'input, select, option, textarea, button, video, label',
// Overrides
width: null,
height: null,
//
preventInteractionOnTransition: false,
// ssr
userAgent: null,
url: null,
// To support iOS's swipe-to-go-back gesture (when being used in-app).
edgeSwipeDetection: false,
edgeSwipeThreshold: 20,
// Autoheight
autoHeight: false,
// Set wrapper width
setWrapperSize: false,
// Virtual Translate
virtualTranslate: false,
virtualList: [],
virtualIndexList: [],
// Effects
effect: 'slide',
// 'slide' or 'fade' or 'cube' or 'coverflow' or 'flip'
// Breakpoints
breakpoints: undefined,
breakpointsBase: 'window',
// Slides grid
spaceBetween: 0,
slidesPerView: 1,
slidesPerGroup: 1,
slidesPerGroupSkip: 0,
slidesPerGroupAuto: false,
centeredSlides: false,
centeredSlidesBounds: false,
slidesOffsetBefore: 0,
// in px
slidesOffsetAfter: 0,
// in px
normalizeSlideIndex: true,
centerInsufficientSlides: false,
// Disable swiper and hide navigation when container not overflow
watchOverflow: true,
// Round length
roundLengths: false,
// Touches
touchRatio: 1,
touchAngle: 45,
simulateTouch: true,
shortSwipes: true,
longSwipes: true,
longSwipesRatio: 0.5,
longSwipesMs: 300,
followFinger: true,
allowTouchMove: true,
threshold: 0,
touchMoveStopPropagation: false,
touchStartPreventDefault: true,
touchStartForcePreventDefault: false,
touchReleaseOnEdges: false,
// Unique Navigation Elements
uniqueNavElements: true,
// Resistance
resistance: true,
resistanceRatio: 0.85,
// Progress
watchSlidesProgress: false,
// Cursor
grabCursor: false,
// Clicks
preventClicks: true,
preventClicksPropagation: true,
slideToClickedSlide: false,
// Images
preloadImages: true,
updateOnImagesReady: true,
// loop
loop: false,
loopAdditionalSlides: 0,
loopedSlides: null,
loopFillGroupWithBlank: false,
loopPreventsSlide: true,
// rewind
rewind: false,
// Swiping/no swiping
allowSlidePrev: true,
allowSlideNext: true,
swipeHandler: null,
// '.swipe-handler',
noSwiping: false,
noSwipingClass: 'swiper-no-swiping',
noSwipingSelector: null,
// Passive Listeners
passiveListeners: true,
// NS
containerModifierClass: 'swiper-',
// NEW
slideClass: 'swiper-slide',
slideBlankClass: 'swiper-slide-invisible-blank',
slideActiveClass: 'swiper-slide-active',
slideDuplicateActiveClass: 'swiper-slide-duplicate-active',
slideVisibleClass: 'swiper-slide-visible',
slideDuplicateClass: 'swiper-slide-duplicate',
slideNextClass: 'swiper-slide-next',
slideDuplicateNextClass: 'swiper-slide-duplicate-next',
slidePrevClass: 'swiper-slide-prev',
slideDuplicatePrevClass: 'swiper-slide-duplicate-prev',
wrapperClass: 'swiper-wrapper',
slideThumbsClass: 'swiper-slide-thumb',
// Callbacks
runCallbacksOnInit: true,
// Internals
_emitClasses: false,
willChange: false
};
/* eslint-disable no-underscore-dangle */
export default {
on(events, handler, priority) {
const self = this;
if (typeof handler !== 'function') return self;
const method = priority ? 'unshift' : 'push';
events.split(' ').forEach(event => {
if (!self.eventsListeners[event]) self.eventsListeners[event] = [];
self.eventsListeners[event][method](handler);
});
return self;
},
once(events, handler, priority) {
const self = this;
if (typeof handler !== 'function') return self;
function onceHandler(...args) {
self.off(events, onceHandler);
if (onceHandler.__emitterProxy) {
delete onceHandler.__emitterProxy;
}
handler.apply(self, args);
}
onceHandler.__emitterProxy = handler;
return self.on(events, onceHandler, priority);
},
onAny(handler, priority) {
const self = this;
if (typeof handler !== 'function') return self;
const method = priority ? 'unshift' : 'push';
if (self.eventsAnyListeners.indexOf(handler) < 0) {
self.eventsAnyListeners[method](handler);
}
return self;
},
offAny(handler) {
const self = this;
if (!self.eventsAnyListeners) return self;
const index = self.eventsAnyListeners.indexOf(handler);
if (index >= 0) {
self.eventsAnyListeners.splice(index, 1);
}
return self;
},
off(events, handler) {
const self = this;
if (!self.eventsListeners) return self;
events.split(' ').forEach(event => {
// self.native.off(event, handler);
if (typeof handler === 'undefined') {
self.eventsListeners[event] = [];
} else if (self.eventsListeners[event]) {
self.eventsListeners[event].forEach((eventHandler, index) => {
if (eventHandler === handler || eventHandler.__emitterProxy && eventHandler
.__emitterProxy === handler) {
self.eventsListeners[event].splice(index, 1);
}
});
}
});
return self;
},
emit(...args) {
const self = this;
if (!self.eventsListeners) return self;
let events;
let data;
let context;
if (typeof args[0] === 'string' || Array.isArray(args[0])) {
events = args[0];
data = args.slice(1, args.length);
context = self;
} else {
events = args[0].events;
data = args[0].data;
context = args[0].context || self;
}
data.unshift(context);
const eventsArray = Array.isArray(events) ? events : events.split(' ');
eventsArray.forEach(event => {
// console.log(event)
if (self.eventsAnyListeners && self.eventsAnyListeners.length) {
self.eventsAnyListeners.forEach(eventHandler => {
eventHandler.apply(context, [event, ...data]);
});
}
if (self.eventsListeners && self.eventsListeners[event]) {
self.eventsListeners[event].forEach(eventHandler => {
eventHandler.apply(context, data);
});
}
});
return self;
}
};
import onTouchStart from './onTouchStart.js';
import onTouchMove from './onTouchMove.js';
import onTouchEnd from './onTouchEnd.js';
import onResize from './onResize.js';
import onClick from './onClick.js';
import onScroll from './onScroll.js';
let dummyEventAttached = false;
function dummyEventListener() {}
const events = (swiper, method) => {
const {
params,
touchEvents,
wrapperEl,
device,
support
} = swiper;
let el = swiper.native;
const capture = !!params.nested;
const domMethod = method === 'on' ? 'on' : 'off';
const swiperMethod = method;
if (!support.touch) {
let desktopMethod = method === 'on' ? 'addEventListener' : 'removeEventListener';
if (document.querySelector(`#${swiper.$el.swiperElId}`)) {
document.querySelector(`#${swiper.$el.swiperElId}`)[desktopMethod](touchEvents.start, swiper
.onTouchStart,
false);
}
document[desktopMethod](touchEvents.move, swiper.onTouchMove, capture);
document[desktopMethod](touchEvents.end, swiper.onTouchEnd, false);
} else {
const passiveListener = touchEvents.start === 'touchstart' && support.passiveListener && params
.passiveListeners ? {
passive: true,
capture: false
} : false;
}
};
function attachEvents() {
const swiper = this;
const {
params,
support
} = swiper;
swiper.onTouchStart = onTouchStart.bind(swiper);
swiper.onTouchMove = onTouchMove.bind(swiper);
swiper.onTouchEnd = onTouchEnd.bind(swiper);
if (params.cssMode) {
swiper.onScroll = onScroll.bind(swiper);
}
swiper.onClick = onClick.bind(swiper);
events(swiper, 'on');
}
function detachEvents() {
const swiper = this;
events(swiper, 'off');
}
export default {
attachEvents,
detachEvents
};
export default function onClick(e) {
const swiper = this;
if (!swiper.enabled) return;
if (!swiper.allowClick) {
if (swiper.params.preventClicks) e.preventDefault();
if (swiper.params.preventClicksPropagation && swiper.animating) {
e.stopPropagation();
e.stopImmediatePropagation();
}
}
}
\ No newline at end of file
export default function onResize() {
const swiper = this;
const {
params,
el
} = swiper;
if (el && el.offsetWidth === 0) return;
if (params.breakpoints) {
swiper.setBreakpoint();
}
const {
allowSlideNext,
allowSlidePrev,
snapGrid
} = swiper;
swiper.allowSlideNext = true;
swiper.allowSlidePrev = true;
swiper.updateSize();
swiper.updateSlides();
swiper.updateSlidesClasses();
if ((params.slidesPerView === 'auto' || params.slidesPerView > 1) && swiper.isEnd && !swiper.isBeginning && !swiper.params.centeredSlides) {
swiper.slideTo(swiper.slides.length - 1, 0, false, true);
} else {
swiper.slideTo(swiper.activeIndex, 0, false, true);
}
if (swiper.autoplay && swiper.autoplay.running && swiper.autoplay.paused) {
swiper.autoplay.run();
}
swiper.allowSlidePrev = allowSlidePrev;
swiper.allowSlideNext = allowSlideNext;
if (swiper.params.watchOverflow && snapGrid !== swiper.snapGrid) {
swiper.checkOverflow();
}
}
\ No newline at end of file
export default function onScroll() {
const swiper = this;
const {
wrapperEl,
rtlTranslate,
enabled
} = swiper;
if (!enabled) return;
swiper.previousTranslate = swiper.translate;
if (swiper.isHorizontal()) {
swiper.translate = -wrapperEl.scrollLeft;
} else {
swiper.translate = -wrapperEl.scrollTop;
} // eslint-disable-next-line
if (swiper.translate === -0) swiper.translate = 0;
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
let newProgress;
const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
if (translatesDiff === 0) {
newProgress = 0;
} else {
newProgress = (swiper.translate - swiper.minTranslate()) / translatesDiff;
}
if (newProgress !== swiper.progress) {
swiper.updateProgress(rtlTranslate ? -swiper.translate : swiper.translate);
}
swiper.emit('setTranslate', swiper.translate, false);
}
\ No newline at end of file
import {
now,
nextTick
} from '../../shared/utils.js';
export default function onTouchEnd(event) {
const swiper = this;
const data = swiper.touchEventsData;
const {
params,
touches,
rtlTranslate: rtl,
slidesGrid,
enabled
} = swiper;
if (!enabled) return;
let e = event;
if (e.originalEvent) e = e.originalEvent;
if (data.allowTouchCallbacks) {
swiper.emit('touch-end', e);
}
data.allowTouchCallbacks = false;
if (!data.isTouched) {
if (data.isMoved && params.grabCursor) {
swiper.setGrabCursor(false);
}
data.isMoved = false;
data.startMoving = false;
return;
}
if (params.grabCursor && data.isMoved && data.isTouched && (swiper.allowSlideNext === true || swiper
.allowSlidePrev === true)) {
swiper.setGrabCursor(false);
}
const touchEndTime = now();
const timeDiff = touchEndTime - data.touchStartTime; // Tap, doubleTap, Click
if (swiper.allowClick) {
const pathTree = e.path || e.composedPath && e.composedPath();
// swiper.updateClickedSlide(pathTree && pathTree[0] || e.target);
swiper.emit('tap click', e);
if (timeDiff < 300 && touchEndTime - data.lastClickTime < 300) {
swiper.emit('doubleTap doubleClick', e);
}
}
data.lastClickTime = now();
nextTick(() => {
if (!swiper.destroyed) swiper.allowClick = true;
});
if (!data.isTouched || !data.isMoved || !swiper.swipeDirection || touches.diff === 0 || data.currentTranslate ===
data.startTranslate) {
data.isTouched = false;
data.isMoved = false;
data.startMoving = false;
return;
}
data.isTouched = false;
data.isMoved = false;
data.startMoving = false;
let currentPos;
if (params.followFinger) {
currentPos = rtl ? swiper.translate : -swiper.translate;
} else {
currentPos = -data.currentTranslate;
}
if (params.cssMode) {
return;
}
if (swiper.params.freeMode && params.freeMode.enabled) {
swiper.freeMode.onTouchEnd({
currentPos
});
return;
}
let stopIndex = 0;
let groupSize = swiper.slidesSizesGrid[0];
for (let i = 0; i < slidesGrid.length; i += i < params.slidesPerGroupSkip ? 1 : params.slidesPerGroup) {
const increment = i < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
if (typeof slidesGrid[i + increment] !== 'undefined') {
if (currentPos >= slidesGrid[i] && currentPos < slidesGrid[i + increment]) {
stopIndex = i;
groupSize = slidesGrid[i + increment] - slidesGrid[i];
}
} else if (currentPos >= slidesGrid[i]) {
stopIndex = i;
groupSize = slidesGrid[slidesGrid.length - 1] - slidesGrid[slidesGrid.length - 2];
}
}
const ratio = (currentPos - slidesGrid[stopIndex]) / groupSize;
const increment = stopIndex < params.slidesPerGroupSkip - 1 ? 1 : params.slidesPerGroup;
if (timeDiff > params.longSwipesMs) {
if (!params.longSwipes) {
swiper.slideTo(swiper.activeIndex);
return;
}
if (swiper.swipeDirection === 'next') {
if (ratio >= params.longSwipesRatio) swiper.slideTo(stopIndex + increment);
else swiper.slideTo(stopIndex);
}
if (swiper.swipeDirection === 'prev') {
if (ratio > 1 - params.longSwipesRatio) swiper.slideTo(stopIndex + increment);
else swiper.slideTo(stopIndex);
}
} else {
if (!params.shortSwipes) {
swiper.slideTo(swiper.activeIndex);
return;
}
const isNavButtonTarget = swiper.navigation && (e.target === swiper.navigation.nextEl || e.target === swiper
.navigation.prevEl);
if (!isNavButtonTarget) {
if (swiper.swipeDirection === 'next') {
swiper.slideTo(stopIndex + increment);
}
if (swiper.swipeDirection === 'prev') {
swiper.slideTo(stopIndex);
}
} else if (e.target === swiper.navigation.nextEl) {
swiper.slideTo(stopIndex + increment);
} else {
swiper.slideTo(stopIndex);
}
}
}
import {
now
} from '../../shared/utils.js';
export default function onTouchMove(event) {
const swiper = this;
const data = swiper.touchEventsData;
const {
params,
touches,
rtlTranslate: rtl,
enabled
} = swiper;
if (!enabled) return;
let e = event;
if (e.originalEvent) e = e.originalEvent;
if (!data.isTouched) {
if (data.startMoving && data.isScrolling) {
swiper.emit('touchMoveOpposite', e);
}
return;
}
if (data.isTouchEvent && e.type !== 'touchmove' && e.type !== 'touchMove' && e.type !== 'onTouchmove') return;
const targetTouch = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') && e.touches && (
e.touches[0] || e
.changedTouches[0]);
const pageX = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') ? targetTouch.pageX : e
.pageX;
const pageY = (e.type === 'touchmove' || e.type === 'touchMove' || e.type === 'onTouchmove') ? targetTouch.pageY : e
.pageY;
if (e.preventedByNestedSwiper) {
touches.startX = pageX;
touches.startY = pageY;
return;
}
if (!swiper.allowTouchMove) {
swiper.allowClick = false;
if (data.isTouched) {
Object.assign(touches, {
startX: pageX,
startY: pageY,
currentX: pageX,
currentY: pageY
});
data.touchStartTime = now();
}
return;
}
if (data.isTouchEvent && params.touchReleaseOnEdges && !params.loop) {
if (swiper.isVertical()) {
if (pageY < touches.startY && swiper.translate <= swiper.maxTranslate() || pageY > touches.startY && swiper
.translate >= swiper.minTranslate()) {
data.isTouched = false;
data.isMoved = false;
return;
}
} else if (pageX < touches.startX && swiper.translate <= swiper.maxTranslate() || pageX > touches.startX &&
swiper.translate >= swiper.minTranslate()) {
return;
}
}
// if (data.isTouchEvent && document.activeElement) {
// if (e.target === document.activeElement && $(e.target).is(data.focusableElements)) {
// data.isMoved = true;
// swiper.allowClick = false;
// return;
// }
// }
if (data.allowTouchCallbacks) {
swiper.emit('touch-move', e);
}
if (e.touches && e.touches.length > 1) return;
touches.currentX = pageX;
touches.currentY = pageY;
const diffX = touches.currentX - touches.startX;
const diffY = touches.currentY - touches.startY;
if (swiper.params.threshold && Math.sqrt(diffX ** 2 + diffY ** 2) < swiper.params.threshold) return;
if (typeof data.isScrolling === 'undefined') {
let touchAngle;
if (swiper.isHorizontal() && touches.currentY === touches.startY || swiper.isVertical() && touches.currentX ===
touches.startX) {
data.isScrolling = false;
} else {
if (diffX * diffX + diffY * diffY >= 25) {
touchAngle = Math.atan2(Math.abs(diffY), Math.abs(diffX)) * 180 / Math.PI;
data.isScrolling = swiper.isHorizontal() ? touchAngle > params.touchAngle : 90 - touchAngle > params
.touchAngle;
}
}
}
if (data.isScrolling) {
swiper.emit('touchMoveOpposite', e);
}
if (typeof data.startMoving === 'undefined') {
if (touches.currentX !== touches.startX || touches.currentY !== touches.startY) {
data.startMoving = true;
}
}
if (data.isScrolling) {
data.isTouched = false;
return;
}
if (!data.startMoving) {
return;
}
swiper.allowClick = false;
if (!params.cssMode && e.cancelable) {
e.preventDefault();
}
if (params.touchMoveStopPropagation && !params.nested) {
e.stopPropagation();
}
if (!data.isMoved) {
if (params.loop && !params.cssMode) {
swiper.loopFix();
}
data.startTranslate = swiper.getTranslate();
swiper.setTransition(0);
if (swiper.animating) {
swiper.$wrapperEl.emit('transitionend', [swiper]);
}
data.allowMomentumBounce = false;
if (params.grabCursor && (swiper.allowSlideNext === true || swiper.allowSlidePrev === true)) {
swiper.setGrabCursor(true);
}
swiper.emit('sliderFirstMove', e);
}
swiper.emit('sliderMove', e);
data.isMoved = true;
let diff = swiper.isHorizontal() ? diffX : diffY;
touches.diff = diff;
diff *= params.touchRatio;
if (rtl) diff = -diff;
swiper.swipeDirection = diff > 0 ? 'prev' : 'next';
data.currentTranslate = diff + data.startTranslate;
let disableParentSwiper = true;
let resistanceRatio = params.resistanceRatio;
if (params.touchReleaseOnEdges) {
resistanceRatio = 0;
}
if (diff > 0 && data.currentTranslate > swiper.minTranslate()) {
disableParentSwiper = false;
if (params.resistance) data.currentTranslate = swiper.minTranslate() - 1 + (-swiper.minTranslate() + data
.startTranslate + diff) ** resistanceRatio;
} else if (diff < 0 && data.currentTranslate < swiper.maxTranslate()) {
disableParentSwiper = false;
if (params.resistance) data.currentTranslate = swiper.maxTranslate() + 1 - (swiper.maxTranslate() - data
.startTranslate - diff) ** resistanceRatio;
}
if (disableParentSwiper) {
e.preventedByNestedSwiper = true;
}
if (!swiper.allowSlideNext && swiper.swipeDirection === 'next' && data.currentTranslate < data.startTranslate) {
data.currentTranslate = data.startTranslate;
}
if (!swiper.allowSlidePrev && swiper.swipeDirection === 'prev' && data.currentTranslate > data.startTranslate) {
data.currentTranslate = data.startTranslate;
}
if (!swiper.allowSlidePrev && !swiper.allowSlideNext) {
data.currentTranslate = data.startTranslate;
}
if (params.threshold > 0) {
if (Math.abs(diff) > params.threshold || data.allowThresholdMove) {
if (!data.allowThresholdMove) {
data.allowThresholdMove = true;
touches.startX = touches.currentX;
touches.startY = touches.currentY;
data.currentTranslate = data.startTranslate;
touches.diff = swiper.isHorizontal() ? touches.currentX - touches.startX : touches.currentY - touches
.startY;
return;
}
} else {
data.currentTranslate = data.startTranslate;
return;
}
}
if (!params.followFinger || params.cssMode) return;
if (params.freeMode && params.freeMode.enabled && swiper.freeMode || params.watchSlidesProgress) {
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
if (swiper.params.freeMode && params.freeMode.enabled && swiper.freeMode) {
swiper.freeMode.onTouchMove();
}
swiper.updateProgress(data.currentTranslate);
swiper.setTranslate(data.currentTranslate);
}
import {
now
} from '../../shared/utils.js';
export default function onTouchStart(event) {
const swiper = this;
const data = swiper.touchEventsData;
const {
params,
touches,
enabled
} = swiper;
if (!enabled) return;
if (swiper.animating && params.preventInteractionOnTransition) {
return;
}
if (!swiper.animating && params.cssMode && params.loop) {
swiper.loopFix();
}
let e = event;
if (e.originalEvent) e = e.originalEvent;
data.isTouchEvent = e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart';
if (!data.isTouchEvent && 'which' in e && e.which === 3) return;
if (!data.isTouchEvent && 'button' in e && e.button > 0) return;
if (data.isTouched && data.isMoved) return; // change target el for shadow root component
const swipingClassHasValue = !!params.noSwipingClass && params.noSwipingClass !== '';
const noSwipingSelector = params.noSwipingSelector ? params.noSwipingSelector : `.${params.noSwipingClass}`;
const isTargetShadow = !!(e.target && e.target
.shadowRoot
);
if (params.noSwiping) {
swiper.allowClick = true;
return;
}
if (params.swipeHandler) {
if (!$targetEl.closest(params.swipeHandler)[0]) return;
}
touches.currentX = (e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart') ? e.touches[0]
.pageX : e.pageX;
touches.currentY = (e.type === 'touchstart' || e.type === 'touchStart' || e.type === 'onTouchstart') ? e.touches[0]
.pageY : e.pageY;
const startX = touches.currentX;
const startY = touches
.currentY;
const edgeSwipeDetection = params.edgeSwipeDetection || params.iOSEdgeSwipeDetection;
const edgeSwipeThreshold = params.edgeSwipeThreshold || params.iOSEdgeSwipeThreshold;
Object.assign(data, {
isTouched: true,
isMoved: false,
allowTouchCallbacks: true,
isScrolling: undefined,
startMoving: undefined
});
touches.startX = startX;
touches.startY = startY;
data.touchStartTime = now();
swiper.allowClick = true;
swiper.updateSize();
swiper.swipeDirection = undefined;
if (params.threshold > 0) data.allowThresholdMove = false;
// if (e.type !== 'touchstart' && e.type !== 'touchStart') {
// let preventDefault = true;
// if ($targetEl.is(data.focusableElements)) preventDefault = false;
// const shouldPreventDefault = preventDefault && swiper.allowTouchMove && params.touchStartPreventDefault;
// if ((params.touchStartForcePreventDefault || shouldPreventDefault) && !$targetEl[0].isContentEditable) {
// e.preventDefault();
// }
// }
swiper.emit('touch-start', e);
}
import setGrabCursor from './setGrabCursor.js';
import unsetGrabCursor from './unsetGrabCursor.js';
export default {
setGrabCursor,
unsetGrabCursor
};
\ No newline at end of file
export default function setGrabCursor(moving) {
const swiper = this;
if (swiper.support.touch || !swiper.params.simulateTouch || swiper.params.watchOverflow && swiper.isLocked || swiper
.params.cssMode) return;
const el = swiper.params.touchEventsTarget === 'container' ? swiper.$el : swiper.$wrapperEl;
el.setCss({
cursor: 'move',
cursor: moving ? '-webkit-grabbing' : '-webkit-grab',
cursor: moving ? '-moz-grabbin' : '-moz-grab',
cursor: moving ? 'grabbing' : 'grab',
})
}
export default function unsetGrabCursor() {
const swiper = this;
if (swiper.support.touch || swiper.params.watchOverflow && swiper.isLocked || swiper.params.cssMode) {
return;
}
swiper[swiper.params.touchEventsTarget === 'container' ? '$el' : '$wrapperEl'].setCss({
cursor: ''
});
}
import loopCreate from './loopCreate.js';
import loopFix from './loopFix.js';
import loopDestroy from './loopDestroy.js';
export default {
loopCreate,
loopFix,
loopDestroy
};
\ No newline at end of file
export default function loopCreate() {
const swiper = this;
const {
params,
$wrapperEl,
native
} = swiper; // Remove duplicated slides
const $selector = $wrapperEl;
let slides = native.children;
if (params.loopFillGroupWithBlank) {
const blankSlidesNum = params.slidesPerGroup - slides.length % params.slidesPerGroup;
if (blankSlidesNum !== params.slidesPerGroup) {
native.loopBlankShow = true;
native.loopBlankNumber = blankSlidesNum;
}
}
if (params.slidesPerView === 'auto' && !params.loopedSlides) params.loopedSlides = slides.length;
swiper.loopedSlides = Math.ceil(parseFloat(params.loopedSlides || params.slidesPerView, 10));
swiper.loopedSlides += params.loopAdditionalSlides;
if (swiper.loopedSlides > slides.length) {
swiper.loopedSlides = slides.length;
}
const prependSlides = [];
const appendSlides = [];
slides.forEach((el, index) => {
const slide = el;
if (index < slides.length && index >= slides.length - swiper.loopedSlides) {
prependSlides.push(el);
}
if (index < swiper.loopedSlides) {
appendSlides.push(el);
}
});
let list = [...swiper.native.value];
let newList = [...list];
swiper.originalDataList = [...swiper.native.value];
for (let i = 0; i < appendSlides.length; i += 1) {
newList.push(list[appendSlides[i].index]);
}
for (let i = prependSlides.length - 1; i >= 0; i -= 1) {
newList.unshift(list[prependSlides[i].index]);
}
swiper.native.$emit("input", newList)
return true;
}
export default function loopDestroy() {
const swiper = this;
const {
$wrapperEl,
params,
slides
} = swiper;
}
export default function loopFix() {
const swiper = this;
swiper.emit('beforeLoopFix');
const {
activeIndex,
slides,
loopedSlides,
allowSlidePrev,
allowSlideNext,
snapGrid,
rtlTranslate: rtl
} = swiper;
let newIndex;
swiper.allowSlidePrev = true;
swiper.allowSlideNext = true;
const snapTranslate = -snapGrid[activeIndex];
const diff = snapTranslate - swiper.getTranslate();
if (activeIndex < loopedSlides) {
newIndex = slides.length - loopedSlides * 3 + activeIndex;
newIndex += loopedSlides;
const slideChanged = swiper.slideTo(newIndex, 0, false, true);
if (slideChanged && diff !== 0) {
swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
}
} else if (activeIndex >= slides.length - loopedSlides) {
newIndex = -slides.length + activeIndex + loopedSlides;
newIndex += loopedSlides;
const slideChanged = swiper.slideTo(newIndex, 0, false, true);
if (slideChanged && diff !== 0) {
swiper.setTranslate((rtl ? -swiper.translate : swiper.translate) - diff);
}
}
swiper.allowSlidePrev = allowSlidePrev;
swiper.allowSlideNext = allowSlideNext;
swiper.emit('loopFix');
}
export function ChildrenMixin(parent, options = {}) {
const indexKey = options.indexKey || 'index';
return {
inject: {
[parent]: {
default: null,
},
},
mounted() {
this.parent = this[parent];
this.bindRelation();
},
// #ifdef VUE2
beforeDestroy() {
if (this.parent) {
this.parent.children = this.parent.children.filter(
(item) => item !== this
);
uni.$emit("childrenReady" + this.parent._uid, this);
}
},
// #endif
// #ifdef VUE3
beforeUnmount() {
if (this.parent) {
this.parent.children = this.parent.children.filter(
(item) => item !== this
);
uni.$emit("childrenReady" + this.parent._uid, this);
}
},
// #endif
methods: {
bindRelation() {
if (!this.parent || this.parent.children.indexOf(this) !== -1) {
return;
}
const children = [...this.parent.children, this];
this.parent.children = children;
this.index = this.parent.children.indexOf(this);
uni.$emit("childrenReady" + this.parent._uid, this);
},
},
};
}
export function ParentMixin(parent) {
return {
provide() {
return {
[parent]: this,
};
},
created() {
this.children = [];
},
// #ifdef VUE2
beforeDestroy() {
uni.$off("childrenReady" + this._uid)
},
// #endif
// #ifdef VUE3
beforeUnmount() {
uni.$off("childrenReady" + this._uid)
},
// #endif
};
}
import {
extend
} from '../shared/utils.js';
export default function moduleExtendParams(params, allModulesParams) {
return function extendParams(obj = {}) {
const moduleParamName = Object.keys(obj)[0];
const moduleParams = obj[moduleParamName];
if (typeof moduleParams !== 'object' || moduleParams === null) {
extend(allModulesParams, obj);
return;
}
if (['navigation', 'pagination', 'scrollbar'].indexOf(moduleParamName) >= 0 && params[moduleParamName] ===
true) {
params[moduleParamName] = {
auto: true
};
}
if (!(moduleParamName in params && 'enabled' in moduleParams)) {
extend(allModulesParams, obj);
return;
}
if (params[moduleParamName] === true) {
params[moduleParamName] = {
enabled: true
};
}
if (typeof params[moduleParamName] === 'object' && !('enabled' in params[moduleParamName])) {
params[moduleParamName].enabled = true;
}
if (!params[moduleParamName]) params[moduleParamName] = {
enabled: false
};
extend(allModulesParams, obj);
};
}
import slideTo from './slideTo.js';
import slideToLoop from './slideToLoop.js';
import slideNext from './slideNext.js';
import slidePrev from './slidePrev.js';
import slideReset from './slideReset.js';
import slideToClosest from './slideToClosest.js';
import slideToClickedSlide from './slideToClickedSlide.js';
export default {
slideTo,
slideToLoop,
slideNext,
slidePrev,
slideReset,
slideToClosest,
slideToClickedSlide
};
export default function slideNext(speed = this.params.speed, runCallbacks = true, internal) {
const swiper = this;
const {
animating,
enabled,
params
} = swiper;
if (!enabled) return swiper;
let perGroup = params.slidesPerGroup;
if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
perGroup = Math.max(swiper.slidesPerViewDynamic('current', true), 1);
}
const increment = swiper.activeIndex < params.slidesPerGroupSkip ? 1 : perGroup;
if (params.loop) {
if (animating && params.loopPreventsSlide) return false;
swiper.loopFix();
}
if (params.rewind && swiper.isEnd) {
return swiper.slideTo(0, speed, runCallbacks, internal);
}
setTimeout(() => {
swiper.slideTo(swiper.activeIndex + increment, speed, runCallbacks, internal)
}, 0)
return true;
}
export default function slidePrev(speed = this.params.speed, runCallbacks = true, internal) {
const swiper = this;
const {
params,
animating,
snapGrid,
slidesGrid,
rtlTranslate,
enabled
} = swiper;
if (!enabled) return swiper;
if (params.loop) {
if (animating && params.loopPreventsSlide) return false;
swiper.loopFix();
}
const translate = rtlTranslate ? swiper.translate : -swiper.translate;
function normalize(val) {
if (val < 0) return -Math.floor(Math.abs(val));
return Math.floor(val);
}
const normalizedTranslate = normalize(translate);
const normalizedSnapGrid = snapGrid.map(val => normalize(val));
let prevSnap = snapGrid[normalizedSnapGrid.indexOf(normalizedTranslate) - 1];
if (typeof prevSnap === 'undefined' && params.cssMode) {
let prevSnapIndex;
snapGrid.forEach((snap, snapIndex) => {
if (normalizedTranslate >= snap) {
prevSnapIndex = snapIndex;
}
});
if (typeof prevSnapIndex !== 'undefined') {
prevSnap = snapGrid[prevSnapIndex > 0 ? prevSnapIndex - 1 : prevSnapIndex];
}
}
let prevIndex = 0;
if (typeof prevSnap !== 'undefined') {
prevIndex = slidesGrid.indexOf(prevSnap);
if (prevIndex < 0) prevIndex = swiper.activeIndex - 1;
if (params.slidesPerView === 'auto' && params.slidesPerGroup === 1 && params.slidesPerGroupAuto) {
prevIndex = prevIndex - swiper.slidesPerViewDynamic('previous', true) + 1;
prevIndex = Math.max(prevIndex, 0);
}
}
if (params.rewind && swiper.isBeginning) {
return swiper.slideTo(swiper.slides.length - 1, speed, runCallbacks, internal);
}
setTimeout(() => {
swiper.slideTo(prevIndex, speed, runCallbacks, internal)
}, 30)
return true;
}
export default function slideReset(speed = this.params.speed, runCallbacks = true, internal) {
const swiper = this;
return swiper.slideTo(swiper.activeIndex, speed, runCallbacks, internal);
}
\ No newline at end of file
import {
animateCSSModeScroll
} from '../../shared/utils.js';
export default function slideTo(index = 0, speed = this.params.speed, runCallbacks = true, internal, initial) {
if (typeof index !== 'number' && typeof index !== 'string') {
throw new Error(
`The 'index' argument cannot have type other than 'number' or 'string'. [${typeof index}] given.`);
}
if (typeof index === 'string') {
/**
* The `index` argument converted from `string` to `number`.
* @type {number}
*/
const indexAsNumber = parseInt(index, 10);
/**
* Determines whether the `index` argument is a valid `number`
* after being converted from the `string` type.
* @type {boolean}
*/
const isValidNumber = isFinite(indexAsNumber);
if (!isValidNumber) {
throw new Error(`The passed-in 'index' (string) couldn't be converted to 'number'. [${index}] given.`);
} // Knowing that the converted `index` is a valid number,
// we can update the original argument's value.
index = indexAsNumber;
}
const swiper = this;
let slideIndex = index;
let timer;
if (slideIndex < 0) slideIndex = 0;
const {
params,
snapGrid,
slidesGrid,
previousIndex,
activeIndex,
rtlTranslate: rtl,
wrapperEl,
enabled
} = swiper;
if (swiper.animating && params.preventInteractionOnTransition || !enabled && !internal && !initial) {
return false;
}
const skip = Math.min(swiper.params.slidesPerGroupSkip, slideIndex);
let snapIndex = skip + Math.floor((slideIndex - skip) / swiper.params.slidesPerGroup);
if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
if ((activeIndex || params.initialSlide || 0) === (previousIndex || 0) && runCallbacks) {
swiper.emit('beforeSlideChangeStart');
}
const translate = -snapGrid[snapIndex]; // Update progress
swiper.updateProgress(translate); // Normalize slideIndex
if (params.normalizeSlideIndex) {
for (let i = 0; i < slidesGrid.length; i += 1) {
const normalizedTranslate = -Math.floor(translate * 100);
const normalizedGrid = Math.floor(slidesGrid[i] * 100);
const normalizedGridNext = Math.floor(slidesGrid[i + 1] * 100);
if (typeof slidesGrid[i + 1] !== 'undefined') {
if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext - (
normalizedGridNext - normalizedGrid) / 2) {
slideIndex = i;
} else if (normalizedTranslate >= normalizedGrid && normalizedTranslate < normalizedGridNext) {
slideIndex = i + 1;
}
} else if (normalizedTranslate >= normalizedGrid) {
slideIndex = i;
}
}
} // Directions locks
if (swiper.initialized && slideIndex !== activeIndex) {
if (!swiper.allowSlideNext && translate < swiper.translate && translate < swiper.minTranslate()) {
return false;
}
if (!swiper.allowSlidePrev && translate > swiper.translate && translate > swiper.maxTranslate()) {
if ((activeIndex || 0) !== slideIndex) return false;
}
}
let direction;
if (slideIndex > activeIndex) direction = 'next';
else if (slideIndex < activeIndex) direction = 'prev';
else direction = 'reset'; // Update Index
if (rtl && -translate === swiper.translate || !rtl && translate === swiper.translate) {
swiper.updateActiveIndex(slideIndex); // Update Height
if (params.autoHeight) {
setTimeout(() => {
swiper.updateAutoHeight();
}, 0)
}
swiper.updateSlidesClasses();
if (params.effect !== 'slide') {
swiper.setTranslate(translate);
}
if (direction !== 'reset') {
swiper.transitionStart(runCallbacks, direction);
swiper.transitionEnd(runCallbacks, direction);
}
return false;
}
if (params.cssMode) {
const isH = swiper.isHorizontal();
const t = rtl ? translate : -translate;
if (speed === 0) {
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
if (isVirtual) {
swiper.wrapperEl.style.scrollSnapType = 'none';
swiper._immediateVirtual = true;
}
wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = t;
if (isVirtual) {
requestAnimationFrame(() => {
swiper.wrapperEl.style.scrollSnapType = '';
swiper._swiperImmediateVirtual = false;
});
}
} else {
if (!swiper.support.smoothScroll) {
animateCSSModeScroll({
swiper,
targetPosition: t,
side: isH ? 'left' : 'top'
});
return true;
}
wrapperEl.scrollTo({
[isH ? 'left' : 'top']: t,
behavior: 'smooth'
});
}
return true;
}
swiper.setTransition(speed);
swiper.setTranslate(translate);
swiper.updateActiveIndex(slideIndex);
swiper.updateSlidesClasses();
swiper.emit('beforeTransitionStart', speed, internal);
swiper.transitionStart(runCallbacks, direction);
if (speed === 0) {
swiper.transitionEnd(runCallbacks, direction);
} else if (!swiper.animating) {
swiper.animating = true;
if (!swiper.onSlideToWrapperTransitionEnd) {
swiper.onSlideToWrapperTransitionEnd = function transitionEnd(e) {
if (!swiper || swiper.destroyed) return;
clearTimeout(timer)
swiper.onSlideToWrapperTransitionEnd = null;
delete swiper.onSlideToWrapperTransitionEnd;
swiper.transitionEnd(runCallbacks, direction);
};
}
timer = setTimeout(() => {
if (swiper.onSlideToWrapperTransitionEnd) {
swiper.onSlideToWrapperTransitionEnd();
}
}, speed)
}
return true;
}
import {
nextTick
} from '../../shared/utils.js';
export default function slideToClickedSlide() {
const swiper = this;
const {
params,
$wrapperEl
} = swiper;
const slidesPerView = params.slidesPerView === 'auto' ? swiper.slidesPerViewDynamic() : params.slidesPerView;
let slideToIndex = swiper.clickedIndex;
let realIndex;
if (params.loop) {
if (swiper.animating) return;
// realIndex = parseInt($(swiper.clickedSlide).attr('data-swiper-slide-index'), 10);
realIndex = parseInt(swiper.activeIndex, 10);
if (params.centeredSlides) {
if (slideToIndex < swiper.loopedSlides - slidesPerView / 2 || slideToIndex > swiper.slides.length - swiper
.loopedSlides + slidesPerView / 2) {
swiper.loopFix();
slideToIndex = $wrapperEl.children(
`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`
).eq(0).index();
nextTick(() => {
swiper.slideTo(slideToIndex);
});
} else {
swiper.slideTo(slideToIndex);
}
} else if (slideToIndex > swiper.slides.length - slidesPerView) {
swiper.loopFix();
slideToIndex = $wrapperEl.children(
`.${params.slideClass}[data-swiper-slide-index="${realIndex}"]:not(.${params.slideDuplicateClass})`)
.eq(0).index();
nextTick(() => {
swiper.slideTo(slideToIndex);
});
} else {
swiper.slideTo(slideToIndex);
}
} else {
swiper.slideTo(slideToIndex);
}
}
/* eslint no-unused-vars: "off" */
export default function slideToClosest(speed = this.params.speed, runCallbacks = true, internal, threshold = 0.5) {
const swiper = this;
let index = swiper.activeIndex;
const skip = Math.min(swiper.params.slidesPerGroupSkip, index);
const snapIndex = skip + Math.floor((index - skip) / swiper.params.slidesPerGroup);
const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
if (translate >= swiper.snapGrid[snapIndex]) {
const currentSnap = swiper.snapGrid[snapIndex];
const nextSnap = swiper.snapGrid[snapIndex + 1];
if (translate - currentSnap > (nextSnap - currentSnap) * threshold) {
index += swiper.params.slidesPerGroup;
}
} else {
const prevSnap = swiper.snapGrid[snapIndex - 1];
const currentSnap = swiper.snapGrid[snapIndex];
if (translate - prevSnap <= (currentSnap - prevSnap) * threshold) {
index -= swiper.params.slidesPerGroup;
}
}
index = Math.max(index, 0);
index = Math.min(index, swiper.slidesGrid.length - 1);
return swiper.slideTo(index, speed, runCallbacks, internal);
}
\ No newline at end of file
export default function slideToLoop(index = 0, speed = this.params.speed, runCallbacks = true, internal) {
const swiper = this;
let newIndex = index;
if (swiper.params.loop) {
newIndex += swiper.loopedSlides;
}
return swiper.slideTo(newIndex, speed, runCallbacks, internal);
}
\ No newline at end of file
import setTransition from './setTransition.js';
import transitionStart from './transitionStart.js';
import transitionEnd from './transitionEnd.js';
export default {
setTransition,
transitionStart,
transitionEnd
};
export default function setTransition(duration, byController) {
const swiper = this;
if (!swiper.$wrapperEl) return
if (!swiper.params.cssMode) {
swiper.$wrapperEl.transition(duration);
}
swiper.emit('setTransition', duration, byController);
}
export default function transitionEmit({
swiper,
runCallbacks,
direction,
step
}) {
const {
activeIndex,
previousIndex
} = swiper;
let dir = direction;
if (!dir) {
if (activeIndex > previousIndex) dir = 'next';
else if (activeIndex < previousIndex) dir = 'prev';
else dir = 'reset';
}
swiper.emit(`transition${step}`);
if (runCallbacks && activeIndex !== previousIndex) {
if (dir === 'reset') {
swiper.emit(`slideResetTransition${step}`);
return;
}
swiper.emit(`slideChangeTransition${step}`);
if (dir === 'next') {
swiper.emit(`slideNextTransition${step}`);
} else {
swiper.emit(`slidePrevTransition${step}`);
}
}
}
import transitionEmit from './transitionEmit.js';
export default function transitionEnd(runCallbacks = true, direction) {
const swiper = this;
const {
params
} = swiper;
swiper.animating = false;
if (params.cssMode) return;
swiper.setTransition(0);
transitionEmit({
swiper,
runCallbacks,
direction,
step: 'End'
});
}
import transitionEmit from './transitionEmit.js';
export default function transitionStart(runCallbacks = true, direction) {
const swiper = this;
const {
params
} = swiper;
if (params.cssMode) return;
if (params.autoHeight) {
swiper.updateAutoHeight();
}
transitionEmit({
swiper,
runCallbacks,
direction,
step: 'Start'
});
}
import {
getTranslate
} from '../../shared/utils.js';
export default function getSwiperTranslate(axis = this.isHorizontal() ? 'x' : 'y') {
const swiper = this;
const {
params,
rtlTranslate: rtl,
translate,
$wrapperEl
} = swiper;
if (params.virtualTranslate) {
return rtl ? -translate : translate;
}
if (params.cssMode) {
return translate;
}
let currentTranslate = getTranslate(swiper, axis);
if (rtl) currentTranslate = -currentTranslate;
return currentTranslate || 0;
}
import getTranslate from './getTranslate.js';
import setTranslate from './setTranslate.js';
import minTranslate from './minTranslate.js';
import maxTranslate from './maxTranslate.js';
import translateTo from './translateTo.js';
export default {
getTranslate,
setTranslate,
minTranslate,
maxTranslate,
translateTo
};
\ No newline at end of file
export default function maxTranslate() {
return -this.snapGrid[this.snapGrid.length - 1];
}
\ No newline at end of file
export default function minTranslate() {
return -this.snapGrid[0];
}
\ No newline at end of file
export default function setTranslate(translate, byController) {
const swiper = this;
const {
rtlTranslate: rtl,
params,
$wrapperEl,
wrapperEl,
progress
} = swiper;
let x = 0;
let y = 0;
const z = 0;
if (isNaN(translate)) {
return
}
if (!$wrapperEl) return
if (swiper.isHorizontal()) {
x = rtl ? -translate : translate;
} else {
y = translate;
}
if (params.roundLengths) {
x = Math.floor(x);
y = Math.floor(y);
}
if (params.cssMode) {
wrapperEl[swiper.isHorizontal() ? 'scrollLeft' : 'scrollTop'] = swiper.isHorizontal() ? -x : -y;
} else if (!params.virtualTranslate) {
$wrapperEl.transform(`translate3d(${x}px, ${y}px, ${z}px)`);
}
swiper.previousTranslate = swiper.translate;
swiper.translate = swiper.isHorizontal() ? x : y; // Check if we need to update progress
let newProgress;
const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
if (translatesDiff === 0) {
newProgress = 0;
} else {
newProgress = (translate - swiper.minTranslate()) / translatesDiff;
}
if (newProgress !== progress) {
swiper.updateProgress(translate);
}
swiper.emit('setTranslate', swiper.translate, byController);
}
import {
animateCSSModeScroll
} from '../../shared/utils.js';
export default function translateTo(translate = 0, speed = this.params.speed, runCallbacks = true, translateBounds =
true, internal) {
const swiper = this;
let timer;
const {
params,
wrapperEl
} = swiper;
if (swiper.animating && params.preventInteractionOnTransition) {
return false;
}
const minTranslate = swiper.minTranslate();
const maxTranslate = swiper.maxTranslate();
let newTranslate;
if (translateBounds && translate > minTranslate) newTranslate = minTranslate;
else if (translateBounds && translate < maxTranslate) newTranslate = maxTranslate;
else newTranslate = translate; // Update progress
swiper.updateProgress(newTranslate);
if (params.cssMode) {
const isH = swiper.isHorizontal();
if (speed === 0) {
wrapperEl[isH ? 'scrollLeft' : 'scrollTop'] = -newTranslate;
} else {
if (!swiper.support.smoothScroll) {
animateCSSModeScroll({
swiper,
targetPosition: -newTranslate,
side: isH ? 'left' : 'top'
});
return true;
}
wrapperEl.scrollTo({
[isH ? 'left' : 'top']: -newTranslate,
behavior: 'smooth'
});
}
return true;
}
if (speed === 0) {
swiper.setTransition(0);
swiper.setTranslate(newTranslate);
if (runCallbacks) {
swiper.emit('beforeTransitionStart', speed, internal);
swiper.emit('transitionEnd');
}
} else {
swiper.setTransition(speed);
swiper.setTranslate(newTranslate);
if (runCallbacks) {
swiper.emit('beforeTransitionStart', speed, internal);
swiper.emit('transitionStart');
}
if (!swiper.animating) {
swiper.animating = true;
if (!swiper.onTranslateToWrapperTransitionEnd) {
swiper.onTranslateToWrapperTransitionEnd = function transitionEnd(e) {
if (!swiper || swiper.destroyed) return;
if (e.target !== this) return;
clearTimeout(timer)
swiper.onTranslateToWrapperTransitionEnd = null;
delete swiper.onTranslateToWrapperTransitionEnd;
if (runCallbacks) {
swiper.emit('transitionEnd');
}
};
}
timer = setTimeout(() => {
swiper.onTranslateToWrapperTransitionEnd();
}, speed)
}
}
return true;
}
import updateSize from './updateSize.js';
import updateSlides from './updateSlides.js';
import updateAutoHeight from './updateAutoHeight.js';
import updateSlidesOffset from './updateSlidesOffset.js';
import updateSlidesProgress from './updateSlidesProgress.js';
import updateProgress from './updateProgress.js';
import updateSlidesClasses from './updateSlidesClasses.js';
import updateActiveIndex from './updateActiveIndex.js';
import updateClickedSlide from './updateClickedSlide.js';
export default {
updateSize,
updateSlides,
updateAutoHeight,
updateSlidesOffset,
updateSlidesProgress,
updateProgress,
updateSlidesClasses,
updateActiveIndex,
updateClickedSlide
};
export default function updateActiveIndex(newActiveIndex) {
const swiper = this;
const translate = swiper.rtlTranslate ? swiper.translate : -swiper.translate;
const {
slidesGrid,
snapGrid,
params,
activeIndex: previousIndex,
realIndex: previousRealIndex,
snapIndex: previousSnapIndex
} = swiper;
let activeIndex = newActiveIndex;
let snapIndex;
if (typeof activeIndex === 'undefined') {
for (let i = 0; i < slidesGrid.length; i += 1) {
if (typeof slidesGrid[i + 1] !== 'undefined') {
if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1] - (slidesGrid[i + 1] - slidesGrid[i]) /
2) {
activeIndex = i;
} else if (translate >= slidesGrid[i] && translate < slidesGrid[i + 1]) {
activeIndex = i + 1;
}
} else if (translate >= slidesGrid[i]) {
activeIndex = i;
}
} // Normalize slideIndex
if (params.normalizeSlideIndex) {
if (activeIndex < 0 || typeof activeIndex === 'undefined') activeIndex = 0;
}
}
if (snapGrid.indexOf(translate) >= 0) {
snapIndex = snapGrid.indexOf(translate);
} else {
const skip = Math.min(params.slidesPerGroupSkip, activeIndex);
snapIndex = skip + Math.floor((activeIndex - skip) / params.slidesPerGroup);
}
if (snapIndex >= snapGrid.length) snapIndex = snapGrid.length - 1;
if (swiper.loopedSlides) {
swiper.slides.filter((item) => item.index >= swiper.loopedSlides && item.index < swiper.slides.length - swiper
.loopedSlides).forEach((item, index) => {
item.dataSwiperSlideIndex = item.index - swiper.loopedSlides;
})
swiper.slides.filter((item) => item.index < swiper.loopedSlides).forEach((item, index) => {
if (swiper.slides[swiper.slides.length - swiper.loopedSlides * 3 + index]) {
item.dataSwiperSlideIndex = swiper.slides[swiper.slides.length - swiper.loopedSlides * 3 +
index]
.index;
}
})
swiper.slides.filter((item) => item.index >= swiper.slides.length - swiper
.loopedSlides).forEach((item, index) => {
item.dataSwiperSlideIndex = swiper.slides[index].index;
})
}
if (activeIndex === previousIndex) {
if (snapIndex !== previousSnapIndex) {
swiper.snapIndex = snapIndex;
swiper.emit('snapIndexChange');
}
return;
} // Get real index
let realIndex;
if (swiper.virtual && params.virtual.enabled) {
realIndex = activeIndex;
} else {
if (swiper.slides[activeIndex].dataSwiperSlideIndex == undefined || swiper.slides[activeIndex]
.dataSwiperSlideIndex == null) {
realIndex = activeIndex;
} else {
realIndex = swiper.slides[activeIndex].dataSwiperSlideIndex;
}
}
Object.assign(swiper, {
snapIndex,
realIndex,
previousIndex,
activeIndex
});
swiper.emit('activeIndexChange');
swiper.emit('snapIndexChange');
if (previousRealIndex !== realIndex) {
swiper.emit('realIndexChange');
}
if (swiper.initialized || swiper.params.runCallbacksOnInit) {
swiper.emit('slideChange', activeIndex);
}
}
export default async function updateAutoHeight(speed) {
const swiper = this;
const activeSlides = [];
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
let newHeight = 0;
let i;
if (typeof speed === 'number') {
swiper.setTransition(speed);
} else if (speed === true) {
swiper.setTransition(swiper.params.speed);
}
const getSlideByIndex = index => {
if (isVirtual) {
return swiper.slides.filter(el => parseInt(el.getAttribute('data-swiper-slide-index'), 10) ===
index)[
0];
}
return swiper.slides[index];
}; // Find slides currently in view
if (swiper.params.slidesPerView !== 'auto' && swiper.params.slidesPerView > 1) {
if (swiper.params.centeredSlides) {
swiper.visibleSlides.each(slide => {
activeSlides.push(slide);
});
} else {
for (i = 0; i < Math.ceil(swiper.params.slidesPerView); i += 1) {
const index = swiper.activeIndex + i;
if (index > swiper.slides.length && !isVirtual) break;
activeSlides.push(getSlideByIndex(index));
}
}
} else {
activeSlides.push(getSlideByIndex(swiper.activeIndex));
} // Find new height from highest slide in view
for (i = 0; i < activeSlides.length; i += 1) {
if (typeof activeSlides[i] !== 'undefined') {
const size = await activeSlides[i].getSize();
const height = size.height;
newHeight = height > newHeight ? height : newHeight;
}
} // Update Height
if (newHeight || newHeight === 0) swiper.$wrapperEl.css({
height: `${newHeight?newHeight:''}px`
});
}
export default function updateClickedSlide(e) {
const swiper = this;
const params = swiper.params;
const slide = swiper.slides[e];
let slideFound = false;
let slideIndex;
if (slide) {
for (let i = 0; i < swiper.slides.length; i += 1) {
if (swiper.slides[i] === slide) {
slideFound = true;
slideIndex = i;
break;
}
}
}
if (slide && slideFound) {
swiper.clickedSlide = slide;
if (swiper.virtual && swiper.params.virtual.enabled) {
swiper.clickedIndex = parseInt($(slide).attr('data-swiper-slide-index'), 10);
} else {
swiper.clickedIndex = slideIndex;
}
} else {
swiper.clickedSlide = undefined;
swiper.clickedIndex = undefined;
return;
}
if (params.slideToClickedSlide && swiper.clickedIndex !== undefined && swiper.clickedIndex !== swiper.activeIndex) {
swiper.slideToClickedSlide();
}
}
export default function updateProgress(translate) {
const swiper = this;
if (typeof translate === 'undefined') {
const multiplier = swiper.rtlTranslate ? -1 : 1; // eslint-disable-next-line
translate = swiper && swiper.translate && swiper.translate * multiplier || 0;
}
const params = swiper.params;
const translatesDiff = swiper.maxTranslate() - swiper.minTranslate();
let {
progress,
isBeginning,
isEnd
} = swiper;
const wasBeginning = isBeginning;
const wasEnd = isEnd;
if (translatesDiff === 0) {
progress = 0;
isBeginning = true;
isEnd = true;
} else {
progress = (translate - swiper.minTranslate()) / translatesDiff;
isBeginning = progress <= 0;
isEnd = progress >= 1;
}
Object.assign(swiper, {
progress,
isBeginning,
isEnd
});
if (params.watchSlidesProgress || params.centeredSlides && params.autoHeight) swiper.updateSlidesProgress(translate);
if (isBeginning && !wasBeginning) {
swiper.emit('reachBeginning toEdge');
}
if (isEnd && !wasEnd) {
swiper.emit('reachEnd toEdge');
}
if (wasBeginning && !isBeginning || wasEnd && !isEnd) {
swiper.emit('fromEdge');
}
swiper.emit('progress', progress);
}
\ No newline at end of file
export default function updateSize() {
const swiper = this;
let width;
let height;
const el = swiper.el;
if (typeof swiper.params.width !== 'undefined' && swiper.params.width !== null) {
width = swiper.params.width;
} else {
width = el.width;
}
if (typeof swiper.params.height !== 'undefined' && swiper.params.height !== null) {
height = swiper.params.height;
} else {
height = el.height;
}
if (width === 0 && swiper.isHorizontal() || height === 0 && swiper.isVertical()) {
return;
} // Subtract paddings
if (Number.isNaN(width)) width = 0;
if (Number.isNaN(height)) height = 0;
Object.assign(swiper, {
width,
height,
size: swiper.isHorizontal() ? width : height
});
}
import {
setCSSProperty
} from '../../shared/utils.js';
export default function updateSlides() {
const swiper = this;
function getDirectionLabel(property) {
if (swiper.isHorizontal()) {
return property;
} // prettier-ignore
return {
'width': 'height',
'margin-top': 'margin-left',
'margin-bottom ': 'margin-right',
'margin-left': 'margin-top',
'margin-right': 'margin-bottom',
'padding-left': 'padding-top',
'padding-right': 'padding-bottom',
'marginRight': 'marginBottom'
} [property];
}
function getDirectionPropertyValue(node, label) {
return parseFloat(node[getDirectionLabel(label)] || 0);
}
function getComputedStyle(native) {
return native.itemStyle;
}
const params = swiper.params;
const {
$wrapperEl,
size: swiperSize,
rtlTranslate: rtl,
wrongRTL
} = swiper;
const isVirtual = swiper.virtual && params.virtual.enabled;
const previousSlidesLength = isVirtual ? swiper.virtual.slides.length : swiper.slides.length;
// const slides = $wrapperEl.children(`.${swiper.params.slideClass}`);
const slides = swiper.slides;
const slidesLength = isVirtual ? swiper.virtual.slides.length : slides.length;
let snapGrid = [];
const slidesGrid = [];
const slidesSizesGrid = [];
let offsetBefore = params.slidesOffsetBefore;
if (typeof offsetBefore === 'function') {
offsetBefore = params.slidesOffsetBefore.call(swiper);
}
let offsetAfter = params.slidesOffsetAfter;
if (typeof offsetAfter === 'function') {
offsetAfter = params.slidesOffsetAfter.call(swiper);
}
const previousSnapGridLength = swiper.snapGrid.length;
const previousSlidesGridLength = swiper.slidesGrid.length;
let spaceBetween = params.spaceBetween;
let slidePosition = -offsetBefore;
let prevSlideSize = 0;
let index = 0;
if (typeof swiperSize === 'undefined') {
return;
}
if (typeof spaceBetween === 'string' && spaceBetween.indexOf('%') >= 0) {
spaceBetween = parseFloat(spaceBetween.replace('%', '')) / 100 * swiperSize;
}
swiper.virtualSize = -spaceBetween; // reset margins
if (params.centeredSlides && params.cssMode) {
setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', '');
setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after', '');
}
const gridEnabled = params.grid && params.grid.rows > 1 && swiper.grid;
if (gridEnabled) {
swiper.grid.initSlides(slidesLength);
}
let slideSize;
const shouldResetSlideSize = params.slidesPerView === 'auto' && params.breakpoints && Object.keys(params
.breakpoints).filter(key => {
return typeof params.breakpoints[key].slidesPerView !== 'undefined';
}).length > 0;
Array(...Array(slidesLength)).forEach(async (item, i) => {
slideSize = 0;
const slide = slides[i];
if (gridEnabled) {
swiper.grid.updateSlide(i, slide, slidesLength, getDirectionLabel);
}
if (params.slidesPerView === 'auto') {
if (shouldResetSlideSize) {
slides[i].style[getDirectionLabel('width')] = ``;
}
const slideStyles = getComputedStyle(slide);
const currentTransform = slide.itemStyle.transform;
const currentWebKitTransform = slide.itemStyle.webkitTransform;
if (currentTransform) {
slide.itemStyle.transform = 'none';
}
if (currentWebKitTransform) {
slide.itemStyle.webkitTransform = 'none';
}
if (params.roundLengths) {
slideSize = swiper.isHorizontal() ? slide.outerWidth(true) : slide.outerHeight(true);
} else {
const width = swiper.isHorizontal() ? slide.width : slide.height;
const paddingLeft = getDirectionPropertyValue(slideStyles, 'padding-left');
const paddingRight = getDirectionPropertyValue(slideStyles, 'padding-right');
const marginLeft = getDirectionPropertyValue(slideStyles, 'margin-left');
const marginRight = getDirectionPropertyValue(slideStyles, 'margin-right');
const boxSizing = slideStyles['box-sizing'];
if (boxSizing && boxSizing === 'border-box') {
slideSize = width + marginLeft + marginRight;
} else {
// slideSize = width + paddingLeft + paddingRight + marginLeft + marginRight;
slideSize = width;
}
}
if (currentTransform) {
slide.itemStyle.transform = currentTransform;
}
if (currentWebKitTransform) {
slide.itemStyle.webkitTransform = currentWebKitTransform;
}
if (params.roundLengths) slideSize = Math.floor(slideSize);
} else {
slideSize = (swiperSize - (params.slidesPerView - 1) * spaceBetween) / params.slidesPerView;
if (params.roundLengths) slideSize = Math.floor(slideSize);
slides[i] && slides[i].css({
[getDirectionLabel('width')]: `${slideSize}px`
})
}
if (slides[i]) {
slides[i].swiperSlideSize = slideSize;
}
if (params.autoHeight) {
slides[i] && slides[i].css({
height: 'auto'
})
}
slidesSizesGrid.push(slideSize);
if (params.centeredSlides) {
slidePosition = slidePosition + slideSize / 2 + prevSlideSize / 2 + spaceBetween;
if (prevSlideSize === 0 && i !== 0) slidePosition = slidePosition - swiperSize / 2 -
spaceBetween;
if (i === 0) slidePosition = slidePosition - swiperSize / 2 - spaceBetween;
if (Math.abs(slidePosition) < 1 / 1000) slidePosition = 0;
if (params.roundLengths) slidePosition = Math.floor(slidePosition);
if (index % params.slidesPerGroup === 0) snapGrid.push(slidePosition);
slidesGrid.push(slidePosition);
} else {
if (params.roundLengths) slidePosition = Math.floor(slidePosition);
if ((index - Math.min(swiper.params.slidesPerGroupSkip, index)) % swiper.params
.slidesPerGroup === 0)
snapGrid.push(slidePosition);
slidesGrid.push(slidePosition);
slidePosition = slidePosition + slideSize + spaceBetween;
}
swiper.virtualSize += slideSize + spaceBetween;
prevSlideSize = slideSize;
index += 1;
})
swiper.virtualSize = Math.max(swiper.virtualSize, swiperSize) + offsetAfter;
if (rtl && wrongRTL && (params.effect === 'slide' || params.effect === 'coverflow')) {
$wrapperEl.css({
width: `${swiper.virtualSize + params.spaceBetween}px`
});
}
if (params.setWrapperSize) {
$wrapperEl.css({
[getDirectionLabel('width')]: `${swiper.virtualSize + params.spaceBetween}px`
});
}
if (gridEnabled) {
swiper.grid.updateWrapperSize(slideSize, snapGrid, getDirectionLabel);
} // Remove last grid elements depending on width
if (!params.centeredSlides) {
const newSlidesGrid = [];
for (let i = 0; i < snapGrid.length; i += 1) {
let slidesGridItem = snapGrid[i];
if (params.roundLengths) slidesGridItem = Math.floor(slidesGridItem);
if (snapGrid[i] <= swiper.virtualSize - swiperSize) {
newSlidesGrid.push(slidesGridItem);
}
}
snapGrid = newSlidesGrid;
if (Math.floor(swiper.virtualSize - swiperSize) - Math.floor(snapGrid[snapGrid.length - 1]) > 1) {
snapGrid.push(swiper.virtualSize - swiperSize);
}
}
if (snapGrid.length === 0) snapGrid = [0];
if (params.spaceBetween !== 0) {
// #ifdef MP-BAIDU
const key = swiper.isHorizontal() && rtl ? 'marginLeft' : getDirectionLabel('marginRight');
// #endif
// #ifndef MP-BAIDU
const key = swiper.isHorizontal() && rtl ? 'margin-left' : getDirectionLabel('margin-right');
// #endif
slides.filter((_, slideIndex) => {
if (!params.cssMode) return true;
if (slideIndex === slides.length - 1) {
return false;
}
return true;
}).forEach((item) => {
item.css({
[key]: `${spaceBetween}px`
})
});
}
if (params.centeredSlides && params.centeredSlidesBounds) {
let allSlidesSize = 0;
slidesSizesGrid.forEach(slideSizeValue => {
allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
});
allSlidesSize -= params.spaceBetween;
const maxSnap = allSlidesSize - swiperSize;
snapGrid = snapGrid.map(snap => {
if (snap < 0) return -offsetBefore;
if (snap > maxSnap) return maxSnap + offsetAfter;
return snap;
});
}
if (params.centerInsufficientSlides) {
let allSlidesSize = 0;
slidesSizesGrid.forEach(slideSizeValue => {
allSlidesSize += slideSizeValue + (params.spaceBetween ? params.spaceBetween : 0);
});
allSlidesSize -= params.spaceBetween;
if (allSlidesSize < swiperSize) {
const allSlidesOffset = (swiperSize - allSlidesSize) / 2;
snapGrid.forEach((snap, snapIndex) => {
snapGrid[snapIndex] = snap - allSlidesOffset;
});
slidesGrid.forEach((snap, snapIndex) => {
slidesGrid[snapIndex] = snap + allSlidesOffset;
});
}
}
Object.assign(swiper, {
slides,
snapGrid,
slidesGrid,
slidesSizesGrid
});
if (params.centeredSlides && params.cssMode && !params.centeredSlidesBounds) {
setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-before', `${-snapGrid[0]}px`);
setCSSProperty(swiper.wrapperEl, '--swiper-centered-offset-after',
`${swiper.size / 2 - slidesSizesGrid[slidesSizesGrid.length - 1] / 2}px`);
const addToSnapGrid = -swiper.snapGrid[0];
const addToSlidesGrid = -swiper.slidesGrid[0];
swiper.snapGrid = swiper.snapGrid.map(v => v + addToSnapGrid);
swiper.slidesGrid = swiper.slidesGrid.map(v => v + addToSlidesGrid);
}
if (slidesLength !== previousSlidesLength) {
swiper.emit('slidesLengthChange');
}
if (snapGrid.length !== previousSnapGridLength) {
if (swiper.params.watchOverflow) swiper.checkOverflow();
swiper.emit('snapGridLengthChange');
}
if (slidesGrid.length !== previousSlidesGridLength) {
swiper.emit('slidesGridLengthChange');
}
if (params.watchSlidesProgress) {
swiper.updateSlidesOffset();
}
return slides;
}
export default function updateSlidesClasses() {
const swiper = this;
const {
slides,
params,
$wrapperEl,
activeIndex,
realIndex
} = swiper;
if (!slides.length || !$wrapperEl) return;
const isVirtual = swiper.virtual && params.virtual.enabled;
for (var i = 0; i < slides.length; i++) {
slides[i].removeClass(
`${params.slideActiveClass} ${params.slideNextClass} ${params.slidePrevClass} ${params.slideDuplicateActiveClass} ${params.slideDuplicateNextClass} ${params.slideDuplicatePrevClass}`
);
}
let activeSlide;
if (isVirtual) {
// activeSlide = swiper.$wrapperEl.find(`.${params.slideClass}[data-swiper-slide-index="${activeIndex}"]`);
activeSlide = slides[slides.findIndex((item) => {
return item.dataSwiperSlideIndex == activeIndex
})];
} else {
activeSlide = slides[activeIndex];
} // Active classes
if (!activeSlide) return
activeSlide.addClass(params.slideActiveClass);
if (params.loop) {
if (activeSlide.hasClass(params.slideDuplicateClass)) {
// $wrapperEl.children[realIndex].addClass(params.slideDuplicateActiveClass);
let index = slides.findIndex((item) => {
return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == realIndex
})
slides[index] && slides[index].addClass(params.slideDuplicateActiveClass);
} else {
// $wrapperEl.children[realIndex].addClass(params.slideDuplicateActiveClass);
let index = slides.findIndex((item) => {
return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == realIndex
})
slides[index] && slides[index].addClass(params.slideDuplicateActiveClass);
}
} // Next Slide
let nextSlide = activeSlide.nextAll(`.${params.slideClass}`)[0];
if (nextSlide) {
nextSlide.addClass(params.slideNextClass);
} else {
if (params.loop && !nextSlide) {
nextSlide = slides[0];
nextSlide.addClass(params.slideNextClass);
} // Prev Slide
}
let prevSlide = activeSlide.prevAll(`.${params.slideClass}`)[0];
if (prevSlide) {
prevSlide.addClass(params.slidePrevClass);
} else {
if (params.loop && !prevSlide) {
prevSlide = slides[slides.length - 1];
prevSlide.addClass(params.slidePrevClass);
}
}
if (params.loop) {
// Duplicate to all looped slides
if (nextSlide.hasClass(params.slideDuplicateClass)) {
// $wrapperEl.children(
// nextSlide.dataSwiperSlideIndex
// ).addClass(params.slideDuplicateNextClass);
let index = slides.findIndex((item) => {
return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == nextSlide
.dataSwiperSlideIndex
})
slides[index] && slides[index].addClass(params.slideDuplicateNextClass);
} else {
// $wrapperEl.children(
// nextSlide.dataSwiperSlideIndex
// ).addClass(params.slideDuplicateNextClass);
let index = slides.findIndex((item) => {
return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == nextSlide
.dataSwiperSlideIndex
})
slides[index] && slides[index].addClass(params.slideDuplicateNextClass);
}
if (prevSlide.hasClass(params.slideDuplicateClass)) {
// $wrapperEl.children(
// prevSlide.dataSwiperSlideIndex
// ).addClass(params.slideDuplicatePrevClass);
let index = slides.findIndex((item) => {
return !item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == prevSlide
.dataSwiperSlideIndex
})
slides[index] && slides[index].addClass(params.slideDuplicatePrevClass);
} else {
// $wrapperEl.children(
// prevSlide.dataSwiperSlideIndex
// ).addClass(params.slideDuplicatePrevClass);
let index = slides.findIndex((item) => {
return item.hasClass(params.slideDuplicateClass) && item.dataSwiperSlideIndex == prevSlide
.dataSwiperSlideIndex
})
slides[index] && slides[index].addClass(params.slideDuplicatePrevClass);
}
}
swiper.emitSlidesClasses();
}
export default async function updateSlidesOffset() {
const swiper = this;
const slides = swiper.slides;
for (let i = 0; i < slides.length; i += 1) {
let offset = (slides[i].swiperSlideSize + swiper.params.spaceBetween) * slides[i].index;
slides[i].swiperSlideOffset = swiper.isHorizontal() ? offset :
offset;
}
}
export default function updateSlidesProgress(translate = this && this.translate || 0) {
const swiper = this;
const params = swiper.params;
const {
slides,
rtlTranslate: rtl,
snapGrid
} = swiper;
if (slides.length === 0) return;
if (typeof slides[0].swiperSlideOffset === 'undefined' || typeof slides[slides.length - 1].swiperSlideOffset ===
'undefined') swiper
.updateSlidesOffset();
let offsetCenter = -translate;
if (rtl) offsetCenter = translate; // Visible Slides
swiper.visibleSlidesIndexes = [];
swiper.visibleSlides = [];
// slides.forEach((item)=>)
for (let i = 0; i < slides.length; i += 1) {
const slide = slides[i];
let slideOffset = slide.swiperSlideOffset;
if (params.cssMode && params.centeredSlides) {
slideOffset -= slides[0].swiperSlideOffset;
}
const slideProgress = (offsetCenter + (params.centeredSlides ? swiper.minTranslate() : 0) - slideOffset) / (
slide.swiperSlideSize + params.spaceBetween);
const originalSlideProgress = (offsetCenter - snapGrid[0] + (params.centeredSlides ? swiper.minTranslate() :
0) - slideOffset) / (slide.swiperSlideSize + params.spaceBetween);
const slideBefore = -(offsetCenter - slideOffset);
const slideAfter = slideBefore + swiper.slidesSizesGrid[i];
const isVisible = slideBefore >= 0 && slideBefore < swiper.size - 1 || slideAfter > 1 && slideAfter <= swiper
.size || slideBefore <= 0 && slideAfter >= swiper.size;
if (isVisible) {
swiper.visibleSlides.push(slide);
swiper.visibleSlidesIndexes.push(i);
slides[i].addClass(params.slideVisibleClass);
}
slide.progress = rtl ? -slideProgress : slideProgress;
slide.originalProgress = rtl ? -originalSlideProgress : originalSlideProgress;
}
}
export function getAllRect(context, selector) {
return new Promise((resolve) => {
uni.createSelectorQuery()
.in(context)
.selectAll(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}
export function getRect(context, selector) {
return new Promise((resolve) => {
uni.createSelectorQuery()
.in(context)
.select(selector)
.boundingClientRect()
.exec((rect = []) => resolve(rect[0]));
});
}
export function requestAnimationFrame(cb) {
const systemInfo = uni.getSystemInfoSync();
if (systemInfo.platform === 'devtools') {
return setTimeout(() => {
cb();
}, 1000 / 30);
}
return uni
.createSelectorQuery()
.selectViewport()
.boundingClientRect()
.exec(() => {
cb();
});
}
import {
paramsList
} from './params-list.js';
import {
isObject
} from './utils.js';
function getChangedParams(swiperParams, oldParams, children, oldChildren) {
const keys = [];
if (!oldParams) return keys;
const addKey = (key) => {
if (keys.indexOf(key) < 0) keys.push(key);
};
const oldChildrenKeys = oldChildren.map((child) => child.props && child.props.key);
const childrenKeys = children.map((child) => child.props && child.props.key);
if (oldChildrenKeys.join('') !== childrenKeys.join('')) keys.push('children');
if (oldChildren.length !== children.length) keys.push('children');
const watchParams = paramsList.filter((key) => key[0] === '_').map((key) => key.replace(/_/, ''));
watchParams.forEach((key) => {
if (key in swiperParams && key in oldParams) {
if (isObject(swiperParams[key]) && isObject(oldParams[key])) {
const newKeys = Object.keys(swiperParams[key]);
const oldKeys = Object.keys(oldParams[key]);
if (newKeys.length !== oldKeys.length) {
addKey(key);
} else {
newKeys.forEach((newKey) => {
if (swiperParams[key][newKey] !== oldParams[key][newKey]) {
addKey(key);
}
});
oldKeys.forEach((oldKey) => {
if (swiperParams[key][oldKey] !== oldParams[key][oldKey]) addKey(key);
});
}
} else if (swiperParams[key] !== oldParams[key]) {
addKey(key);
}
} else if (key in swiperParams && !(key in oldParams)) {
addKey(key);
} else if (!(key in swiperParams) && key in oldParams) {
addKey(key);
}
});
return keys;
}
export {
getChangedParams
};
import Swiper from '../../index.js';
import {
isObject,
extend
} from './utils.js';
import {
paramsList
} from './params-list.js';
function getParams(obj = {}) {
const params = {
on: {},
};
const passedParams = {};
extend(params, Swiper.defaults);
extend(params, Swiper.extendedDefaults);
params._emitClasses = true;
params.init = false;
const rest = {};
const allowedParams = paramsList.map((key) => key.replace(/_/, ''));
// Prevent empty Object.keys(obj) array on ios.
const plainObj = Object.assign({}, obj);
Object.keys(plainObj).forEach((key) => {
if (typeof obj[key] === 'undefined') return;
if (allowedParams.indexOf(key) >= 0) {
if (isObject(obj[key])) {
params[key] = {};
passedParams[key] = {};
extend(params[key], obj[key]);
extend(passedParams[key], obj[key]);
} else {
params[key] = obj[key];
passedParams[key] = obj[key];
}
} else if (key.search(/on[A-Z]/) === 0 && typeof obj[key] === 'function') {
params.on[`${key[2].toLowerCase()}${key.substr(3)}`] = obj[key];
} else {
rest[key] = obj[key];
}
});
['navigation', 'pagination', 'scrollbar'].forEach((key) => {
if (params[key] === true) params[key] = {};
if (params[key] === false) delete params[key];
});
return {
params,
passedParams,
rest
};
}
export {
getParams
};
import Swiper from '../../index.js';
import {
needsNavigation,
needsPagination,
needsScrollbar
} from './utils.js';
function initSwiper(swiperParams, native) {
return new Swiper(swiperParams, native);
}
function mountSwiper({
el,
nextEl,
prevEl,
paginationEl,
scrollbarEl,
swiper
}, swiperParams) {
if (needsNavigation(swiperParams) && nextEl && prevEl) {
swiper.params.navigation.nextEl = nextEl;
swiper.originalParams.navigation.nextEl = nextEl;
swiper.params.navigation.prevEl = prevEl;
swiper.originalParams.navigation.prevEl = prevEl;
}
if (needsPagination(swiperParams) && paginationEl) {
swiper.params.pagination.el = paginationEl;
swiper.originalParams.pagination.el = paginationEl;
}
if (needsScrollbar(swiperParams) && scrollbarEl) {
swiper.params.scrollbar.el = scrollbarEl;
swiper.originalParams.scrollbar.el = scrollbarEl;
}
swiper.init(el);
}
export {
initSwiper,
mountSwiper
};
import Swiper from '../../index.js';
function calcLoopedSlides(slides, swiperParams) {
let slidesPerViewParams = swiperParams.slidesPerView;
if (swiperParams.breakpoints) {
const breakpoint = Swiper.prototype.getBreakpoint(swiperParams.breakpoints);
const breakpointOnlyParams =
breakpoint in swiperParams.breakpoints ? swiperParams.breakpoints[breakpoint] : undefined;
if (breakpointOnlyParams && breakpointOnlyParams.slidesPerView) {
slidesPerViewParams = breakpointOnlyParams.slidesPerView;
}
}
let loopedSlides = Math.ceil(parseFloat(swiperParams.loopedSlides || slidesPerViewParams, 10));
loopedSlides += swiperParams.loopAdditionalSlides;
if (loopedSlides > slides.length) {
loopedSlides = slides.length;
}
return loopedSlides;
}
function renderLoop(native, swiperParams, data) {
const modifiedValue = data;
if (swiperParams.loopFillGroupWithBlank) {
const blankSlidesNum =
swiperParams.slidesPerGroup - (modifiedValue.length % swiperParams.slidesPerGroup);
if (blankSlidesNum !== swiperParams.slidesPerGroup) {
for (let i = 0; i < blankSlidesNum; i += 1) {
const blankSlide = h('div', {
class: `${swiperParams.slideClass} ${swiperParams.slideBlankClass}`,
});
modifiedValue.push(blankSlide);
}
}
}
if (swiperParams.slidesPerView === 'auto' && !swiperParams.loopedSlides) {
swiperParams.loopedSlides = modifiedValue.length;
}
const loopedSlides = calcLoopedSlides(modifiedValue, swiperParams);
const prependSlides = [];
const appendSlides = [];
const prependValue = [];
const appendValue = [];
modifiedValue.forEach((child, index) => {
if (index < loopedSlides) {
if (!native.loopUpdateData) {
appendValue.push(child);
}
}
if (index < modifiedValue.length && index >= modifiedValue.length - loopedSlides) {
if (!native.loopUpdateData) {
prependValue.push(child);
}
}
})
if (native) {
if (!native.originalDataList) native.originalDataList = [];
native.originalDataList = [...prependValue, ...modifiedValue, ...appendValue];
}
return {
data: [...prependValue, ...modifiedValue, ...appendValue]
};
}
export {
calcLoopedSlides,
renderLoop
};
/* underscore in name -> watch for changes */
const paramsList = [
'modules',
'init',
'_direction',
'touchEventsTarget',
'initialSlide',
'_speed',
'cssMode',
'updateOnWindowResize',
'resizeObserver',
'nested',
'focusableElements',
'_enabled',
'_width',
'_height',
'preventInteractionOnTransition',
'userAgent',
'url',
'_edgeSwipeDetection',
'_edgeSwipeThreshold',
'_freeMode',
'_autoHeight',
'setWrapperSize',
'virtualTranslate',
'_effect',
'breakpoints',
'_spaceBetween',
'_slidesPerView',
'maxBackfaceHiddenSlides',
'_grid',
'_slidesPerGroup',
'_slidesPerGroupSkip',
'_slidesPerGroupAuto',
'_centeredSlides',
'_centeredSlidesBounds',
'_slidesOffsetBefore',
'_slidesOffsetAfter',
'normalizeSlideIndex',
'_centerInsufficientSlides',
'_watchOverflow',
'roundLengths',
'touchRatio',
'touchAngle',
'simulateTouch',
'_shortSwipes',
'_longSwipes',
'longSwipesRatio',
'longSwipesMs',
'_followFinger',
'allowTouchMove',
'_threshold',
'touchMoveStopPropagation',
'touchStartPreventDefault',
'touchStartForcePreventDefault',
'touchReleaseOnEdges',
'uniqueNavElements',
'_resistance',
'_resistanceRatio',
'_watchSlidesProgress',
'_grabCursor',
'preventClicks',
'preventClicksPropagation',
'_slideToClickedSlide',
'_preloadImages',
'updateOnImagesReady',
'_loop',
'_loopAdditionalSlides',
'_loopedSlides',
'_loopFillGroupWithBlank',
'loopPreventsSlide',
'_rewind',
'_allowSlidePrev',
'_allowSlideNext',
'_swipeHandler',
'_noSwiping',
'noSwipingClass',
'noSwipingSelector',
'passiveListeners',
'containerModifierClass',
'slideClass',
'slideBlankClass',
'slideActiveClass',
'slideDuplicateActiveClass',
'slideVisibleClass',
'slideDuplicateClass',
'slideNextClass',
'slideDuplicateNextClass',
'slidePrevClass',
'slideDuplicatePrevClass',
'wrapperClass',
'runCallbacksOnInit',
'observer',
'observeParents',
'observeSlideChildren',
// modules
'a11y',
'_autoplay',
'_controller',
'coverflowEffect',
'cubeEffect',
'fadeEffect',
'flipEffect',
'creativeEffect',
'cardsEffect',
'panorama',
'hashNavigation',
'history',
'keyboard',
'lazy',
'mousewheel',
'_navigation',
'_pagination',
'parallax',
'_scrollbar',
'_thumbs',
'_virtual',
'zoom',
];
export {
paramsList
};
import {
isObject,
extend
} from './utils.js';
async function updateSwiper({
swiper,
slides,
passedParams,
changedParams,
nextEl,
prevEl,
paginationEl,
scrollbarEl,
}) {
const updateParams = changedParams.filter((key) => key !== 'children' && key !== 'direction');
const {
params: currentParams,
pagination,
navigation,
scrollbar,
virtual,
thumbs
} = swiper;
let needThumbsInit;
let needControllerInit;
let needPaginationInit;
let needScrollbarInit;
let needNavigationInit;
if (
changedParams.includes('thumbs') &&
passedParams.thumbs &&
passedParams.thumbs.swiper &&
currentParams.thumbs &&
!currentParams.thumbs.swiper
) {
needThumbsInit = true;
}
if (
changedParams.includes('controller') &&
passedParams.controller &&
passedParams.controller.control &&
currentParams.controller &&
!currentParams.controller.control
) {
needControllerInit = true;
}
if (
changedParams.includes('pagination') &&
passedParams.pagination &&
(passedParams.pagination.el || paginationEl) &&
(currentParams.pagination || currentParams.pagination === false) &&
pagination &&
!pagination.el
) {
needPaginationInit = true;
}
if (
changedParams.includes('scrollbar') &&
passedParams.scrollbar &&
(passedParams.scrollbar.el || scrollbarEl) &&
(currentParams.scrollbar || currentParams.scrollbar === false) &&
scrollbar &&
!scrollbar.el
) {
needScrollbarInit = true;
}
if (
changedParams.includes('navigation') &&
passedParams.navigation &&
(passedParams.navigation.prevEl || prevEl) &&
(passedParams.navigation.nextEl || nextEl) &&
(currentParams.navigation || currentParams.navigation === false) &&
navigation &&
!navigation.prevEl &&
!navigation.nextEl
) {
needNavigationInit = true;
}
const destroyModule = (mod) => {
if (!swiper[mod]) return;
swiper[mod].destroy();
if (mod === 'navigation') {
currentParams[mod].prevEl = undefined;
currentParams[mod].nextEl = undefined;
swiper[mod].prevEl = undefined;
swiper[mod].nextEl = undefined;
} else {
currentParams[mod].el = undefined;
swiper[mod].el = undefined;
}
};
updateParams.forEach((key) => {
if (isObject(currentParams[key]) && isObject(passedParams[key])) {
extend(currentParams[key], passedParams[key]);
} else {
const newValue = passedParams[key];
if (
(newValue === true || newValue === false) &&
(key === 'navigation' || key === 'pagination' || key === 'scrollbar')
) {
if (newValue === false) {
destroyModule(key);
}
} else {
currentParams[key] = passedParams[key];
}
}
});
// if (changedParams.includes('virtual') && virtual && currentParams.virtual.enabled) {
// virtual.update();
// }
if (changedParams.includes('children') && virtual && currentParams.virtual.enabled) {
// virtual.slides = slides;
virtual.update(true);
} else if (changedParams.includes('children') && swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
if (needThumbsInit) {
const initialized = thumbs.init();
if (initialized) thumbs.update(true);
}
if (needControllerInit) {
swiper.controller.control = currentParams.controller.control;
}
if (needPaginationInit) {
if (paginationEl) currentParams.pagination.el = paginationEl;
pagination.init();
pagination.render();
pagination.update();
}
if (needScrollbarInit) {
if (scrollbarEl) currentParams.scrollbar.el = scrollbarEl;
scrollbar.init();
scrollbar.updateSize();
scrollbar.setTranslate();
}
if (needNavigationInit) {
if (nextEl) currentParams.navigation.nextEl = nextEl;
if (prevEl) currentParams.navigation.prevEl = prevEl;
navigation.init();
navigation.update();
}
if (changedParams.includes('allowSlideNext')) {
swiper.allowSlideNext = passedParams.allowSlideNext;
}
if (changedParams.includes('allowSlidePrev')) {
swiper.allowSlidePrev = passedParams.allowSlidePrev;
}
if (changedParams.includes('direction')) {
swiper.changeDirection(passedParams.direction, false);
}
swiper.update();
}
export {
updateSwiper
};
function isObject(o) {
return (
typeof o === 'object' &&
o !== null &&
o.constructor &&
Object.prototype.toString.call(o).slice(8, -1) === 'Object'
);
}
function extend(target, src) {
const noExtend = ['__proto__', 'constructor', 'prototype'];
Object.keys(src)
.filter((key) => noExtend.indexOf(key) < 0)
.forEach((key) => {
if (typeof target[key] === 'undefined') target[key] = src[key];
else if (isObject(src[key]) && isObject(target[key]) && Object.keys(src[key]).length > 0) {
if (src[key].__swiper__) target[key] = src[key];
else extend(target[key], src[key]);
} else {
target[key] = src[key];
}
});
}
function needsNavigation(props = {}) {
return (
props.navigation &&
typeof props.navigation.nextEl === 'undefined' &&
typeof props.navigation.prevEl === 'undefined'
);
}
function needsPagination(props = {}) {
return props.pagination && typeof props.pagination.el === 'undefined';
}
function needsScrollbar(props = {}) {
return props.scrollbar;
}
function uniqueClasses(classNames = '') {
const classes = classNames
.split(' ')
.map((c) => c.trim())
.filter((c) => !!c);
const unique = [];
classes.forEach((c) => {
if (unique.indexOf(c) < 0) unique.push(c);
});
return unique.join(' ');
}
export {
isObject,
extend,
needsNavigation,
needsPagination,
needsScrollbar,
uniqueClasses
};
// import { h } from 'vue';
function updateOnVirtualData(swiper) {
if (
!swiper ||
swiper.destroyed ||
!swiper.params.virtual ||
(swiper.params.virtual && !swiper.params.virtual.enabled)
) return;
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
if (swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
if (swiper.parallax && swiper.params.parallax && swiper.params.parallax.enabled) {
swiper.parallax.setTranslate();
}
}
function renderVirtual(swiperRef, slides, virtualData) {
if (!virtualData) return null;
const style = swiperRef.isHorizontal() ? {
[swiperRef.rtlTranslate ? 'right' : 'left']: `${virtualData.offset}px`,
} : {
top: `${virtualData.offset}px`,
};
return slides
.filter((slide, index) => index >= virtualData.from && index <= virtualData.to)
.map((slide) => {
if (!slide.props) slide.props = {};
if (!slide.props.style) slide.props.style = {};
slide.props.swiperRef = swiperRef;
slide.props.style = style;
return h(slide.type, {
...slide.props
}, slide.children);
});
}
export {
renderVirtual,
updateOnVirtualData
};
import {
nextTick
} from '../../shared/utils.js';
export default function Autoplay({
swiper,
extendParams,
on,
emit
}) {
let timeout;
swiper.autoplay = {
running: false,
paused: false
};
extendParams({
autoplay: {
enabled: false,
delay: 3000,
waitForTransition: true,
disableOnInteraction: true,
stopOnLastSlide: false,
reverseDirection: false,
pauseOnMouseEnter: false
}
});
function run() {
const $activeSlideEl = swiper.slides[swiper.activeIndex];
let delay = swiper.params.autoplay.delay;
clearTimeout(timeout);
timeout = nextTick(() => {
let autoplayResult;
if (swiper.params.autoplay.reverseDirection) {
if (swiper.params.loop) {
swiper.loopFix();
autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.isBeginning) {
autoplayResult = swiper.slidePrev(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.params.autoplay.stopOnLastSlide) {
autoplayResult = swiper.slideTo(swiper.slides.length - 1, swiper.params.speed, true, true);
emit('autoplay');
} else {
stop();
}
} else if (swiper.params.loop) {
swiper.loopFix();
setTimeout(() => {
autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
}, 30)
emit('autoplay');
} else if (!swiper.isEnd) {
autoplayResult = swiper.slideNext(swiper.params.speed, true, true);
emit('autoplay');
} else if (!swiper.params.autoplay.stopOnLastSlide) {
autoplayResult = swiper.slideTo(0, swiper.params.speed, true, true);
emit('autoplay');
} else {
stop();
}
if (swiper.params.cssMode && swiper.autoplay.running) run();
else if (autoplayResult === false) {
run();
}
}, delay);
}
function start() {
if (typeof timeout !== 'undefined') return false;
if (swiper.autoplay.running) return false;
swiper.autoplay.running = true;
emit('autoplayStart');
run();
return true;
}
function stop() {
if (!swiper.autoplay.running) return false;
if (typeof timeout === 'undefined') return false;
if (timeout) {
clearTimeout(timeout);
timeout = undefined;
}
swiper.autoplay.running = false;
emit('autoplayStop');
return true;
}
function pause(speed) {
if (!swiper.autoplay.running) return;
if (swiper.autoplay.paused) return;
if (timeout) clearTimeout(timeout);
swiper.autoplay.paused = true;
if (speed === 0 || !swiper.params.autoplay.waitForTransition) {
swiper.autoplay.paused = false;
run();
} else {
['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
swiper.on(event, onTransitionEnd);
});
}
}
function onVisibilityChange() {
// const document = getDocument();
// if (document.visibilityState === 'hidden' && swiper.autoplay.running) {
// pause();
// }
// if (document.visibilityState === 'visible' && swiper.autoplay.paused) {
// run();
// swiper.autoplay.paused = false;
// }
}
function onTransitionEnd(e) {
if (!swiper || swiper.destroyed || !swiper.$wrapperEl) return;
// if (e.target !== swiper.$wrapperEl[0]) return;
['transitionEnd', 'webkitTransitionEnd'].forEach(event => {
swiper.off(event, onTransitionEnd);
});
swiper.autoplay.paused = false;
if (!swiper.autoplay.running) {
stop();
} else {
run();
}
}
function onMouseEnter() {
if (swiper.params.autoplay.disableOnInteraction) {
stop();
} else {
pause();
}
// ['transitionend', 'webkitTransitionEnd'].forEach(event => {
// swiper.$wrapperEl[0].removeEventListener(event, onTransitionEnd);
// });
}
function onMouseLeave() {
if (swiper.params.autoplay.disableOnInteraction) {
return;
}
swiper.autoplay.paused = false;
run();
}
function attachMouseEvents() {
if (swiper.params.autoplay.pauseOnMouseEnter) {}
}
function detachMouseEvents() {}
on('init update', () => {
if (swiper.params.autoplay.enabled) {
start();
attachMouseEvents();
}
});
on('beforeTransitionStart', (_s, speed, internal) => {
if (swiper.autoplay.running) {
if (internal || !swiper.params.autoplay.disableOnInteraction) {
swiper.autoplay.pause(speed);
} else {
if (!swiper.params.loop) {
stop();
}
}
}
});
on('sliderFirstMove', () => {
if (swiper.autoplay.running) {
if (swiper.params.autoplay.disableOnInteraction) {
stop();
} else {
pause();
}
}
});
on('touch-end', () => {
if (swiper.params.cssMode && swiper.autoplay.paused && !swiper.params.autoplay.disableOnInteraction) {
run();
}
});
on('destroy', () => {
detachMouseEvents();
if (swiper.autoplay.running) {
stop();
}
});
Object.assign(swiper.autoplay, {
pause,
run,
start,
stop
});
}
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectCards({
swiper,
extendParams,
on
}) {
extendParams({
cardsEffect: {
slideShadows: true,
transformEl: null,
rotate: true,
perSlideRotate: 2,
perSlideOffset: 8,
},
});
const setTranslate = () => {
const {
slides,
activeIndex
} = swiper;
const params = swiper.params.cardsEffect;
const {
startTranslate,
isTouched
} = swiper.touchEventsData;
const currentTranslate = swiper.translate;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
const slideProgress = $slideEl.progress;
const progress = Math.min(Math.max(slideProgress, -4), 4);
let offset = $slideEl.swiperSlideOffset;
if (swiper.params.centeredSlides && !swiper.params.cssMode) {
swiper.$wrapperEl.transform(`translateX(${swiper.minTranslate()}px)`);
}
if (swiper.params.centeredSlides && swiper.params.cssMode) {
offset -= slides.swiperSlideOffset;
}
let tX = swiper.params.cssMode ? -offset - swiper.translate : -offset;
let tY = 0;
const tZ = -100 * Math.abs(progress);
let scale = 1;
let rotate = -params.perSlideRotate * progress;
let tXAdd = params.perSlideOffset - Math.abs(progress) * 0.75;
const isSwipeToNext =
(i === activeIndex || i === activeIndex - 1) &&
progress > 0 &&
progress < 1 &&
(isTouched || swiper.params.cssMode) &&
currentTranslate < startTranslate;
const isSwipeToPrev =
(i === activeIndex || i === activeIndex + 1) &&
progress < 0 &&
progress > -1 &&
(isTouched || swiper.params.cssMode) &&
currentTranslate > startTranslate;
if (isSwipeToNext || isSwipeToPrev) {
const subProgress = (1 - Math.abs((Math.abs(progress) - 0.5) / 0.5)) ** 0.5;
rotate += -28 * progress * subProgress;
scale += -0.5 * subProgress;
tXAdd += 96 * subProgress;
tY = `${-25 * subProgress * Math.abs(progress)}%`;
}
if (progress < 0) {
// next
tX = `calc(${tX}px + (${tXAdd * Math.abs(progress)}%))`;
} else if (progress > 0) {
// prev
tX = `calc(${tX}px + (-${tXAdd * Math.abs(progress)}%))`;
} else {
tX = `${tX}px`;
}
if (!swiper.isHorizontal()) {
const prevY = tY;
tY = tX;
tX = prevY;
}
const scaleString =
progress < 0 ? `${1 + (1 - scale) * progress}` : `${1 - (1 - scale) * progress}`;
const transform =
`translate3d(${tX}, ${tY}, ${tZ}px) rotateZ(${params.rotate ? rotate : 0}deg) scale(${scaleString})`;
$slideEl.css({
zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
})
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
slides[i].addClass('swiper-slide-cards')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.cardsEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl
});
};
effectInit({
effect: 'cards',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true,
virtualTranslate: !swiper.params.cssMode,
}),
});
}
.swiper-cards {
overflow: visible;
}
.swiper-slide-cards {
transform-origin: center bottom;
backface-visibility: hidden;
}
\ No newline at end of file
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
export default function EffectCarousel({
swiper,
extendParams,
on
}) {
extendParams({
carouselEffect: {}
});
const setTranslate = () => {
const scaleStep = 0.2;
const zIndexMax = swiper.slides.length;
for (let i = 0; i < swiper.slides.length; i += 1) {
const slideEl = swiper.slides[i];
const slideProgress = swiper.slides[i].progress;
const absProgress = Math.abs(slideProgress);
let modify = 1;
if (absProgress > 1) {
modify = (absProgress - 1) * 0.3 + 1;
}
const translate = `${slideProgress * modify * 50}%`;
const scale = 1 - absProgress * scaleStep;
const zIndex = zIndexMax - Math.abs(Math.round(slideProgress));
const slideTransform = `translateX(${translate}) scale(${scale})`;
slideEl.transform(slideTransform);
slideEl.css({
zIndex: zIndex
})
if (absProgress > 3) {
slideEl.css({
opacity: 0
})
} else {
slideEl.css({
opacity: 1
})
}
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.coverflowEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (var i = 0; i < $transitionElements.length; i++) {
$transitionElements[i].transition(duration);
}
};
effectInit({
effect: 'carousel',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true,
slidesPerView: 'auto',
centeredSlides: true,
})
});
}
.swiper-slide-carousel {
backface-visibility: hidden;
overflow: hidden;
transition-property: transform, opacity, height;
transform-style: preserve-3d;
}
\ No newline at end of file
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
export default function EffectCoverflow({
swiper,
extendParams,
on
}) {
extendParams({
coverflowEffect: {
rotate: 50,
stretch: 0,
depth: 100,
scale: 1,
modifier: 1,
slideShadows: true,
transformEl: null
}
});
const setTranslate = () => {
const {
width: swiperWidth,
height: swiperHeight,
slides,
slidesSizesGrid
} = swiper;
const params = swiper.params.coverflowEffect;
const isHorizontal = swiper.isHorizontal();
const transform = swiper.translate;
const center = isHorizontal ? -transform + swiperWidth / 2 : -transform + swiperHeight / 2;
const rotate = isHorizontal ? params.rotate : -params.rotate;
const translate = params.depth; // Each slide offset from center
for (let i = 0, length = slides.length; i < length; i += 1) {
const $slideEl = slides[i];
const slideSize = slidesSizesGrid[i];
const slideOffset = $slideEl.swiperSlideOffset;
const offsetMultiplier = (center - slideOffset - slideSize / 2) / slideSize * params.modifier;
let rotateY = isHorizontal ? rotate * offsetMultiplier : 0;
let rotateX = isHorizontal ? 0 : rotate * offsetMultiplier; // var rotateZ = 0
let translateZ = -translate * Math.abs(offsetMultiplier);
let stretch = params.stretch; // Allow percentage to make a relative stretch for responsive sliders
if (typeof stretch === 'string' && stretch.indexOf('%') !== -1) {
stretch = parseFloat(params.stretch) / 100 * slideSize;
}
let translateY = isHorizontal ? 0 : stretch * offsetMultiplier;
let translateX = isHorizontal ? stretch * offsetMultiplier : 0;
let scale = 1 - (1 - params.scale) * Math.abs(offsetMultiplier); // Fix for ultra small values
if (Math.abs(translateX) < 0.001) translateX = 0;
if (Math.abs(translateY) < 0.001) translateY = 0;
if (Math.abs(translateZ) < 0.001) translateZ = 0;
if (Math.abs(rotateY) < 0.001) rotateY = 0;
if (Math.abs(rotateX) < 0.001) rotateX = 0;
if (Math.abs(scale) < 0.001) scale = 0;
const slideTransform =
`translate3d(${translateX}px,${translateY}px,${translateZ}px) rotateX(${rotateX}deg) rotateY(${rotateY}deg) scale(${scale})`;
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(slideTransform);
$slideEl.css({
zIndex: -Math.abs(Math.round(offsetMultiplier)) + 1
})
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
$slideEl.addClass('swiper-slide-coverflow')
// if (params.slideShadows) {
// // Set shadows
// let $shadowBeforeEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-left') : $slideEl.find('.swiper-slide-shadow-top');
// let $shadowAfterEl = isHorizontal ? $slideEl.find('.swiper-slide-shadow-right') : $slideEl.find('.swiper-slide-shadow-bottom');
// if ($shadowBeforeEl.length === 0) {
// $shadowBeforeEl = createShadow(params, $slideEl, isHorizontal ? 'left' : 'top');
// }
// if ($shadowAfterEl.length === 0) {
// $shadowAfterEl = createShadow(params, $slideEl, isHorizontal ? 'right' : 'bottom');
// }
// if ($shadowBeforeEl.length) $shadowBeforeEl[0].style.opacity = offsetMultiplier > 0 ? offsetMultiplier : 0;
// if ($shadowAfterEl.length) $shadowAfterEl[0].style.opacity = -offsetMultiplier > 0 ? -offsetMultiplier : 0;
// }
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.coverflowEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (var i = 0; i < $transitionElements.length; i++) {
$transitionElements[i].transition(duration);
}
};
effectInit({
effect: 'coverflow',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
watchSlidesProgress: true
})
});
}
.swiper-slide-coverflow{
transform-style: preserve-3d;
}
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectCreative({
swiper,
extendParams,
on
}) {
extendParams({
creativeEffect: {
transformEl: null,
limitProgress: 1,
shadowPerProgress: false,
progressMultiplier: 1,
perspective: true,
prev: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
next: {
translate: [0, 0, 0],
rotate: [0, 0, 0],
opacity: 1,
scale: 1,
},
},
});
const getTranslateValue = (value) => {
if (typeof value === 'string') return value;
return `${value}px`;
};
const setTranslate = () => {
const {
slides,
$wrapperEl,
slidesSizesGrid
} = swiper;
const params = swiper.params.creativeEffect;
const {
progressMultiplier: multiplier
} = params;
const isCenteredSlides = swiper.params.centeredSlides;
if (isCenteredSlides) {
const margin = slidesSizesGrid[0] / 2 - swiper.params.slidesOffsetBefore || 0;
$wrapperEl.transform(`translateX(calc(50% - ${margin}px))`);
}
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
const slideProgress = $slideEl.progress;
const progress = Math.min(
Math.max($slideEl.progress, -params.limitProgress),
params.limitProgress,
);
let originalProgress = progress;
if (!isCenteredSlides) {
originalProgress = Math.min(
Math.max($slideEl.originalProgress, -params.limitProgress),
params.limitProgress,
);
}
const offset = $slideEl.swiperSlideOffset;
const t = [swiper.params.cssMode ? -offset - swiper.translate : -offset, 0, 0];
const r = [0, 0, 0];
let custom = false;
if (!swiper.isHorizontal()) {
t[1] = t[0];
t[0] = 0;
}
let data = {
translate: [0, 0, 0],
rotate: [0, 0, 0],
scale: 1,
opacity: 1,
};
if (progress < 0) {
data = params.next;
custom = true;
} else if (progress > 0) {
data = params.prev;
custom = true;
}
// set translate
t.forEach((value, index) => {
t[index] = `calc(${value}px + (${getTranslateValue(data.translate[index])} * ${Math.abs(
progress * multiplier,
)}))`;
});
// set rotates
r.forEach((value, index) => {
r[index] = data.rotate[index] * Math.abs(progress * multiplier);
});
// $slideEl[0].style.zIndex = -Math.abs(Math.round(slideProgress)) + slides.length;
$slideEl.css({
zIndex: -Math.abs(Math.round(slideProgress)) + slides.length
})
const translateString = t.join(', ');
const rotateString = `rotateX(${r[0]}deg) rotateY(${r[1]}deg) rotateZ(${r[2]}deg)`;
const scaleString =
originalProgress < 0 ?
`scale(${1 + (1 - data.scale) * originalProgress * multiplier})` :
`scale(${1 - (1 - data.scale) * originalProgress * multiplier})`;
const opacityString =
originalProgress < 0 ?
1 + (1 - data.opacity) * originalProgress * multiplier :
1 - (1 - data.opacity) * originalProgress * multiplier;
const transform = `translate3d(${translateString}) ${rotateString} ${scaleString}`;
// Set shadows
// if ((custom && data.shadow) || !custom) {
// let $shadowEl = $slideEl.children('.swiper-slide-shadow');
// if ($shadowEl.length === 0 && data.shadow) {
// $shadowEl = createShadow(params, $slideEl);
// }
// if ($shadowEl.length) {
// const shadowOpacity = params.shadowPerProgress
// ? progress * (1 / params.limitProgress)
// : progress;
// $shadowEl[0].style.opacity = Math.min(Math.max(Math.abs(shadowOpacity), 0), 1);
// }
// }
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
$targetEl.css({
opacity: opacityString
});
if (data.origin) {
$targetEl.css({
'transform-origin': data.origin
});
}
if (swiper.params.willChange) {
slides[i].willChange("transform,opacity");
}
slides[i].addClass('swiper-slide-creative')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.creativeEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl,
allSlides: true
});
};
effectInit({
effect: 'creative',
swiper,
on,
setTranslate,
setTransition,
perspective: () => swiper.params.creativeEffect.perspective,
overwriteParams: () => ({
watchSlidesProgress: true,
virtualTranslate: !swiper.params.cssMode,
}),
});
}
.swiper-creative {
}
.swiper-slide-creative {
backface-visibility: hidden;
overflow: hidden;
transition-property: transform, opacity, height;
transform-style: preserve-3d;
}
\ No newline at end of file
import effectInit from '../../shared/effect-init.js';
export default function EffectCube({
swiper,
extendParams,
on
}) {
extendParams({
cubeEffect: {
slideShadows: true,
shadow: true,
shadowOffset: 20,
shadowScale: 0.94,
},
});
const setTranslate = () => {
const {
$el,
$wrapperEl,
slides,
width: swiperWidth,
height: swiperHeight,
rtlTranslate: rtl,
size: swiperSize,
browser,
} = swiper;
const params = swiper.params.cubeEffect;
const isHorizontal = swiper.isHorizontal();
const isVirtual = swiper.virtual && swiper.params.virtual.enabled;
let wrapperRotate = 0;
let $cubeShadowEl;
if (params.shadow) {
if (isHorizontal) {
// $cubeShadowEl = $wrapperEl.find('.swiper-cube-shadow');
if (!swiper.native.cubeShadowShowWrapper) {
swiper.$wrapperEl.updateData({
cubeShadowShowWrapper: true
})
}
swiper.$wrapperEl.cubeShadowCss({
height: `${swiperWidth}px`
});
} else {
if (!swiper.native.cubeShadowShowRoot) {
swiper.$wrapperEl.updateData({
cubeShadowShowRoot: true
})
}
}
}
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
let slideIndex = i;
if (isVirtual) {
slideIndex = parseInt(swiper.activeIndex, 10);
}
let slideAngle = slideIndex * 90;
let round = Math.floor(slideAngle / 360);
if (rtl) {
slideAngle = -slideAngle;
round = Math.floor(-slideAngle / 360);
}
const progress = Math.max(Math.min($slideEl.progress, 1), -1);
let tx = 0;
let ty = 0;
let tz = 0;
if (slideIndex % 4 === 0) {
tx = -round * 4 * swiperSize;
tz = 0;
} else if ((slideIndex - 1) % 4 === 0) {
tx = 0;
tz = -round * 4 * swiperSize;
} else if ((slideIndex - 2) % 4 === 0) {
tx = swiperSize + round * 4 * swiperSize;
tz = swiperSize;
} else if ((slideIndex - 3) % 4 === 0) {
tx = -swiperSize;
tz = 3 * swiperSize + swiperSize * 4 * round;
}
if (rtl) {
tx = -tx;
}
if (!isHorizontal) {
ty = tx;
tx = 0;
}
const transform = `rotateX(${isHorizontal ? 0 : -slideAngle}deg) rotateY(${
isHorizontal ? slideAngle : 0
}deg) translate3d(${tx}px, ${ty}px, ${tz}px)`;
if (progress <= 1 && progress > -1) {
wrapperRotate = slideIndex * 90 + progress * 90;
if (rtl) wrapperRotate = -slideIndex * 90 - progress * 90;
}
$slideEl.transform(transform);
// if (params.slideShadows) {
// // Set shadows
// let shadowBefore = isHorizontal ?
// $slideEl.find('.swiper-slide-shadow-left') :
// $slideEl.find('.swiper-slide-shadow-top');
// let shadowAfter = isHorizontal ?
// $slideEl.find('.swiper-slide-shadow-right') :
// $slideEl.find('.swiper-slide-shadow-bottom');
// if (shadowBefore.length === 0) {
// shadowBefore = $(
// `<div class="swiper-slide-shadow-${isHorizontal ? 'left' : 'top'}"></div>`,
// );
// $slideEl.append(shadowBefore);
// }
// if (shadowAfter.length === 0) {
// shadowAfter = $(
// `<div class="swiper-slide-shadow-${isHorizontal ? 'right' : 'bottom'}"></div>`,
// );
// $slideEl.append(shadowAfter);
// }
// if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
// if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
// }
$slideEl.addClass('swiper-slide-cube')
}
$wrapperEl.css({
'-webkit-transform-origin': `50% 50% -${swiperSize / 2}px`,
'transform-origin': `50% 50% -${swiperSize / 2}px`,
});
if (params.shadow) {
if (isHorizontal) {
swiper.$wrapperEl.cubeShadowTransform(
`translate3d(0px, ${swiperWidth / 2 + params.shadowOffset}px, ${
-swiperWidth / 2
}px) rotateX(90deg) rotateZ(0deg) scale(${params.shadowScale})`,
);
} else {
const shadowAngle = Math.abs(wrapperRotate) - Math.floor(Math.abs(wrapperRotate) / 90) * 90;
const multiplier =
1.5 -
(Math.sin((shadowAngle * 2 * Math.PI) / 360) / 2 +
Math.cos((shadowAngle * 2 * Math.PI) / 360) / 2);
const scale1 = params.shadowScale;
const scale2 = params.shadowScale / multiplier;
const offset = params.shadowOffset;
swiper.$wrapperEl.cubeShadowTransform(
`scale3d(${scale1}, 1, ${scale2}) translate3d(0px, ${swiperHeight / 2 + offset}px, ${
-swiperHeight / 2 / scale2
}px) rotateX(-90deg)`,
);
}
}
const zFactor = browser.isSafari || browser.isWebView ? -swiperSize / 2 : 0;
$wrapperEl.transform(
`translate3d(0px,0,${zFactor}px) rotateX(${
swiper.isHorizontal() ? 0 : wrapperRotate
}deg) rotateY(${swiper.isHorizontal() ? -wrapperRotate : 0}deg)`,
);
};
const setTransition = (duration) => {
const {
$el,
slides
} = swiper;
for (var i = 0; i < slides.length; i++) {
slides[i].transition(duration)
}
if (swiper.params.cubeEffect.shadow && !swiper.isHorizontal()) {
swiper.$wrapperEl.cubeShadowTransition(duration);
}
};
effectInit({
effect: 'cube',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
resistanceRatio: 0,
spaceBetween: 0,
centeredSlides: false,
virtualTranslate: true,
}),
});
}
.swiper-cube {
overflow: visible;
&.swiper-rtl .swiper-slide {
transform-origin: 100% 0;
}
.swiper-cube-shadow {
position: absolute;
left: 0;
bottom: 0px;
width: 100%;
height: 100%;
opacity: 0.6;
z-index: 0;
&:before {
content: '';
background: #000;
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
-webkit-filter: blur(50px);
filter: blur(50px);
}
}
}
.swiper-slide-cube {
pointer-events: none;
backface-visibility: hidden;
z-index: 1;
visibility: hidden;
transform-origin: 0 0;
width: 100%;
height: 100%;
transform-style: preserve-3d;
.swiper-slide {
pointer-events: none;
}
}
.swiper-slide-cube.swiper-slide-active,
.swiper-slide-cube.swiper-slide-next,
.swiper-slide-cube.swiper-slide-prev,
.swiper-slide-cube.swiper-slide-next + .swiper-slide {
pointer-events: auto;
visibility: visible;
}
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectFade({
swiper,
extendParams,
on
}) {
extendParams({
fadeEffect: {
crossFade: false,
transformEl: null
}
});
const setTranslate = () => {
const {
slides
} = swiper;
const params = swiper.params.fadeEffect;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = swiper.slides[i];
const offset = $slideEl.swiperSlideOffset;
let tx = -offset;
if (!swiper.params.virtualTranslate) tx -= swiper.translate;
let ty = 0;
if (!swiper.isHorizontal()) {
ty = tx;
tx = 0;
}
const slideOpacity = swiper.params.fadeEffect.crossFade ? Math.max(1 - Math.abs($slideEl.progress), 0) :
1 + Math.min(Math.max($slideEl.progress, -1), 0);
const $targetEl = effectTarget(params, $slideEl);
$targetEl.css({
opacity: slideOpacity
})
$targetEl.transform(`translate3d(${tx}px, ${ty}px, 0px)`);
if (swiper.params.willChange) {
$targetEl.willChange("opacity");
}
slides[i].addClass('swiper-slide-fade')
}
};
const setTransition = duration => {
const {
transformEl
} = swiper.params.fadeEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl,
allSlides: true
});
};
effectInit({
effect: 'fade',
swiper,
on,
setTranslate,
setTransition,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
spaceBetween: 0,
virtualTranslate: !swiper.params.cssMode
})
});
}
.swiper-slide-fade {
pointer-events: none;
transition-property: opacity;
.swiper-slide {
pointer-events: none;
}
}
.swiper-slide-fade.swiper-slide-active {
pointer-events: auto;
}
import effectInit from '../../shared/effect-init.js';
import effectTarget from '../../shared/effect-target.js';
import effectVirtualTransitionEnd from '../../shared/effect-virtual-transition-end.js';
export default function EffectFlip({
swiper,
extendParams,
on
}) {
extendParams({
flipEffect: {
slideShadows: true,
limitRotation: true,
transformEl: null,
},
});
const setTranslate = () => {
const {
slides,
rtlTranslate: rtl
} = swiper;
const params = swiper.params.flipEffect;
for (let i = 0; i < slides.length; i += 1) {
const $slideEl = slides[i];
let progress = $slideEl.progress;
if (swiper.params.flipEffect.limitRotation) {
progress = Math.max(Math.min($slideEl.progress, 1), -1);
}
const offset = $slideEl.swiperSlideOffset;
const rotate = -180 * progress;
let rotateY = rotate;
let rotateX = 0;
let tx = swiper.params.cssMode ? -offset - swiper.translate : -offset;
let ty = 0;
if (!swiper.isHorizontal()) {
ty = tx;
tx = 0;
rotateX = -rotateY;
rotateY = 0;
} else if (rtl) {
rotateY = -rotateY;
}
$slideEl.css({
zIndex: -Math.abs(Math.round(progress)) + slides.length
})
// if (params.slideShadows) {
// // Set shadows
// let shadowBefore = swiper.isHorizontal()
// ? $slideEl.find('.swiper-slide-shadow-left')
// : $slideEl.find('.swiper-slide-shadow-top');
// let shadowAfter = swiper.isHorizontal()
// ? $slideEl.find('.swiper-slide-shadow-right')
// : $slideEl.find('.swiper-slide-shadow-bottom');
// if (shadowBefore.length === 0) {
// shadowBefore = createShadow(params, $slideEl, swiper.isHorizontal() ? 'left' : 'top');
// }
// if (shadowAfter.length === 0) {
// shadowAfter = createShadow(params, $slideEl, swiper.isHorizontal() ? 'right' : 'bottom');
// }
// if (shadowBefore.length) shadowBefore[0].style.opacity = Math.max(-progress, 0);
// if (shadowAfter.length) shadowAfter[0].style.opacity = Math.max(progress, 0);
// }
const transform = `translate3d(${tx}px, ${ty}px, 0px) rotateX(${rotateX}deg) rotateY(${rotateY}deg)`;
const $targetEl = effectTarget(params, $slideEl);
$targetEl.transform(transform);
if (swiper.params.willChange) {
$targetEl.willChange("transform");
}
slides[i].addClass('swiper-slide-flip')
}
};
const setTransition = (duration) => {
const {
transformEl
} = swiper.params.flipEffect;
const $transitionElements = transformEl ? swiper.slides.find(transformEl) : swiper.slides;
for (let i = 0; i < $transitionElements.length; i += 1) {
$transitionElements[i].transition(duration);
}
effectVirtualTransitionEnd({
swiper,
duration,
transformEl
});
};
effectInit({
effect: 'flip',
swiper,
on,
setTranslate,
setTransition,
perspective: () => true,
overwriteParams: () => ({
slidesPerView: 1,
slidesPerGroup: 1,
watchSlidesProgress: true,
spaceBetween: 0,
virtualTranslate: !swiper.params.cssMode,
}),
});
}
.swiper-flip {
overflow: visible;
.swiper-slide-shadow-top,
.swiper-slide-shadow-bottom,
.swiper-slide-shadow-left,
.swiper-slide-shadow-right {
z-index: 0;
backface-visibility: hidden;
}
}
.swiper-slide-flip {
pointer-events: none;
backface-visibility: hidden;
z-index: 1;
transform-style: preserve-3d;
.swiper-slide {
pointer-events: none;
}
}
export default function Panorama({
swiper,
extendParams,
on
}) {
extendParams({
panorama: {
depth: 200,
rotate: 30,
stretch: 1
},
});
on('beforeInit', () => {
if (swiper.params.effect !== 'panorama') return;
swiper.classNames.push(`${swiper.params.containerModifierClass}panorama`);
swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
const overwriteParams = {
watchSlidesProgress: true,
};
Object.assign(swiper.params, overwriteParams);
Object.assign(swiper.originalParams, overwriteParams);
});
on('progress', () => {
if (swiper.params.effect !== 'panorama') return;
const sizesGrid = swiper.slidesSizesGrid;
const {
depth = 200, rotate = 30, stretch = 1
} = swiper.params.panorama;
const angleRad = (rotate * Math.PI) / 180;
const halfAngleRad = angleRad / 2;
const angleModifier = 1 / (180 / rotate);
for (let i = 0; i < swiper.slides.length; i += 1) {
const slideEl = swiper.slides[i];
const slideProgress = slideEl.progress;
const slideSize = sizesGrid[i];
const progressModifier = swiper.params.centeredSlides ?
0 :
(swiper.params.slidesPerView - 1) * 0.5;
const modifiedProgress = slideProgress + progressModifier;
const angleCos = 1 - Math.cos(modifiedProgress * angleModifier * Math.PI);
const translateX = `${modifiedProgress * (stretch * slideSize / 3) * angleCos}px`;
const rotateY = modifiedProgress * rotate;
const radius = (slideSize * 0.5) / Math.sin(halfAngleRad);
const translateZ = `${radius * angleCos - depth}px`;
slideEl.transform(
`translateX(${translateX}) translateZ(${translateZ}) rotateY(${rotateY}deg)`);
if (swiper.params.willChange) {
slideEl.willChange("transform");
}
slideEl.addClass('swiper-slide-panorama')
}
});
on('setTransition', (s, duration) => {
if (swiper.params.effect !== 'panorama') return;
swiper.slides.forEach((slideEl) => {
slideEl.transition(duration);
});
});
}
import {
now
} from '../../shared/utils.js';
export default function freeMode({
swiper,
extendParams,
emit,
once
}) {
extendParams({
freeMode: {
enabled: false,
momentum: true,
momentumRatio: 1,
momentumBounce: true,
momentumBounceRatio: 1,
momentumVelocityRatio: 1,
sticky: false,
minimumVelocity: 0.02
}
});
function onTouchMove() {
const {
touchEventsData: data,
touches
} = swiper; // Velocity
if (data.velocities.length === 0) {
data.velocities.push({
position: touches[swiper.isHorizontal() ? 'startX' : 'startY'],
time: data.touchStartTime
});
}
data.velocities.push({
position: touches[swiper.isHorizontal() ? 'currentX' : 'currentY'],
time: now()
});
}
function onTouchEnd({
currentPos
}) {
const {
params,
$wrapperEl,
rtlTranslate: rtl,
snapGrid,
touchEventsData: data
} = swiper; // Time diff
const touchEndTime = now();
const timeDiff = touchEndTime - data.touchStartTime;
if (currentPos < -swiper.minTranslate()) {
swiper.slideTo(swiper.activeIndex);
return;
}
if (currentPos > -swiper.maxTranslate()) {
if (swiper.slides.length < snapGrid.length) {
swiper.slideTo(snapGrid.length - 1);
} else {
swiper.slideTo(swiper.slides.length - 1);
}
return;
}
if (params.freeMode.momentum) {
if (data.velocities.length > 1) {
const lastMoveEvent = data.velocities.pop();
const velocityEvent = data.velocities.pop();
const distance = lastMoveEvent.position - velocityEvent.position;
const time = lastMoveEvent.time - velocityEvent.time;
swiper.velocity = distance / time;
swiper.velocity /= 2;
if (Math.abs(swiper.velocity) < params.freeMode.minimumVelocity) {
swiper.velocity = 0;
} // this implies that the user stopped moving a finger then released.
// There would be no events with distance zero, so the last event is stale.
if (time > 150 || now() - lastMoveEvent.time > 300) {
swiper.velocity = 0;
}
} else {
swiper.velocity = 0;
}
swiper.velocity *= params.freeMode.momentumVelocityRatio;
data.velocities.length = 0;
let momentumDuration = 1000 * params.freeMode.momentumRatio;
const momentumDistance = swiper.velocity * momentumDuration;
let newPosition = swiper.translate + momentumDistance;
if (rtl) newPosition = -newPosition;
let doBounce = false;
let afterBouncePosition;
const bounceAmount = Math.abs(swiper.velocity) * 20 * params.freeMode.momentumBounceRatio;
let needsLoopFix;
if (newPosition < swiper.maxTranslate()) {
if (params.freeMode.momentumBounce) {
if (newPosition + swiper.maxTranslate() < -bounceAmount) {
newPosition = swiper.maxTranslate() - bounceAmount;
}
afterBouncePosition = swiper.maxTranslate();
doBounce = true;
data.allowMomentumBounce = true;
} else {
newPosition = swiper.maxTranslate();
}
if (params.loop && params.centeredSlides) needsLoopFix = true;
} else if (newPosition > swiper.minTranslate()) {
if (params.freeMode.momentumBounce) {
if (newPosition - swiper.minTranslate() > bounceAmount) {
newPosition = swiper.minTranslate() + bounceAmount;
}
afterBouncePosition = swiper.minTranslate();
doBounce = true;
data.allowMomentumBounce = true;
} else {
newPosition = swiper.minTranslate();
}
if (params.loop && params.centeredSlides) needsLoopFix = true;
} else if (params.freeMode.sticky) {
let nextSlide;
for (let j = 0; j < snapGrid.length; j += 1) {
if (snapGrid[j] > -newPosition) {
nextSlide = j;
break;
}
}
if (Math.abs(snapGrid[nextSlide] - newPosition) < Math.abs(snapGrid[nextSlide - 1] - newPosition) ||
swiper.swipeDirection === 'next') {
newPosition = snapGrid[nextSlide];
} else {
newPosition = snapGrid[nextSlide - 1];
}
newPosition = -newPosition;
}
if (needsLoopFix) {
once('transitionEnd', () => {
swiper.loopFix();
});
} // Fix duration
if (swiper.velocity !== 0) {
if (rtl) {
momentumDuration = Math.abs((-newPosition - swiper.translate) / swiper.velocity);
} else {
momentumDuration = Math.abs((newPosition - swiper.translate) / swiper.velocity);
}
if (params.freeMode.sticky) {
const moveDistance = Math.abs((rtl ? -newPosition : newPosition) - swiper.translate);
const currentSlideSize = swiper.slidesSizesGrid[swiper.activeIndex];
if (moveDistance < currentSlideSize) {
momentumDuration = params.speed;
} else if (moveDistance < 2 * currentSlideSize) {
momentumDuration = params.speed * 1.5;
} else {
momentumDuration = params.speed * 2.5;
}
}
} else if (params.freeMode.sticky) {
swiper.slideToClosest();
return;
}
if (params.freeMode.momentumBounce && doBounce) {
swiper.updateProgress(afterBouncePosition);
swiper.setTransition(momentumDuration);
swiper.setTranslate(newPosition);
swiper.transitionStart(true, swiper.swipeDirection);
swiper.animating = true;
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed || !data.allowMomentumBounce) return;
emit('momentumBounce');
swiper.setTransition(params.speed);
setTimeout(() => {
swiper.setTranslate(afterBouncePosition);
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed) return;
swiper.transitionEnd();
}, momentumDuration);
}, 0);
}, momentumDuration);
} else if (swiper.velocity) {
emit('_freeModeNoMomentumRelease');
swiper.updateProgress(newPosition);
swiper.setTransition(momentumDuration);
swiper.setTranslate(newPosition);
swiper.transitionStart(true, swiper.swipeDirection);
if (!swiper.animating) {
swiper.animating = true;
$wrapperEl.transitionEnd(() => {
if (!swiper || swiper.destroyed) return;
swiper.transitionEnd();
}, momentumDuration);
}
} else {
swiper.updateProgress(newPosition);
}
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
} else if (params.freeMode.sticky) {
swiper.slideToClosest();
return;
} else if (params.freeMode) {
emit('_freeModeNoMomentumRelease');
}
if (!params.freeMode.momentum || timeDiff >= params.longSwipesMs) {
swiper.updateProgress();
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
}
Object.assign(swiper, {
freeMode: {
onTouchMove,
onTouchEnd
}
});
}
export default function Navigation({
swiper,
extendParams,
on,
emit
}) {
extendParams({
navigation: {
nextEl: null,
prevEl: null,
hideOnClick: false,
disabledClass: 'swiper-button-disabled',
hiddenClass: 'swiper-button-hidden',
lockClass: 'swiper-button-lock',
},
});
swiper.navigation = {
nextEl: null,
$nextEl: null,
prevEl: null,
$prevEl: null,
};
function toggleEl($el, disabled) {
if (!swiper.$wrapperEl) return
// debugger
const params = swiper.params.navigation;
if ($el) {
swiper.$wrapperEl[disabled ? `add${$el}` : `remove${$el}`](params.disabledClass);
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? `add${$el}` : `remove${$el}`](params.lockClass);
}
}
}
function update() {
// Update Navigation Buttons
if (swiper.params.loop) return;
const {
$nextEl,
$prevEl
} = swiper.navigation;
toggleEl('PrevElClass', swiper.isBeginning && !swiper.params.rewind);
toggleEl('NextElClass', swiper.isEnd && !swiper.params.rewind);
}
function onPrevClick(e) {
// e.preventDefault();
if (swiper.isBeginning && !swiper.params.loop && !swiper.params.rewind) return;
swiper.slidePrev();
}
function onNextClick() {
// e.preventDefault();
if (swiper.isEnd && !swiper.params.loop && !swiper.params.rewind) return;
swiper.slideNext();
}
function init() {
const params = swiper.params.navigation;
if (params.slot || params.custom) {
params.nextEl = true;
params.prevEl = true;
}
if (!(params.nextEl || params.prevEl) && !params.slot && !params.custom) return;
if (params.slot) {
swiper.native.updateData({
showPrevButtonSlot: true,
showNextButtonSlot: true
})
} else if (params.custom) {} else {
swiper.native.updateData({
showPrevButton: true,
showNextButton: true
})
}
const $nextEl = params.nextEl;
const $prevEl = params.prevEl;
if ($nextEl) {
swiper.on('nextClick', onNextClick);
}
if ($prevEl) {
swiper.on('prevClick', onPrevClick);
}
Object.assign(swiper.navigation, {
$nextEl,
nextEl: $nextEl,
$prevEl,
prevEl: $prevEl,
});
if (!swiper.enabled) {
if ($nextEl) swiper.$wrapperEl.addNextElClass(params.lockClass);
if ($prevEl) swiper.$wrapperEl.addPrevElClass(params.lockClass);
}
}
function destroy() {
const {
$nextEl,
$prevEl
} = swiper.navigation;
if ($nextEl) {
swiper.off('nextClick', onNextClick);
swiper.$wrapperEl.removeNextElClass(swiper.params.navigation.disabledClass);
}
if ($prevEl) {
swiper.off('prevClick', onPrevClick);
swiper.$wrapperEl.removePrevElClass(swiper.params.navigation.disabledClass);
}
}
on('init', () => {
init();
update();
});
on('toEdge fromEdge lock unlock', () => {
update();
});
on('destroy', () => {
destroy();
});
on('enable disable', () => {
const {
$nextEl,
$prevEl
} = swiper.navigation;
if ($nextEl) {
swiper.$wrapperEl[swiper.enabled ? 'removeNextElClass' : 'addNextElClass'](swiper.params.navigation
.lockClass);
// $nextEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
}
if ($prevEl) {
swiper.$wrapperEl[swiper.enabled ? 'removePrevElClass' : 'addPrevElClass'](swiper.params.navigation
.lockClass);
// $prevEl[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.navigation.lockClass);
}
});
// on('click', (_s, e) => {
// const {
// $nextEl,
// $prevEl
// } = swiper.navigation;
// const targetEl = e.target;
// if (
// swiper.params.navigation.hideOnClick &&
// !$(targetEl).is($prevEl) &&
// !$(targetEl).is($nextEl)
// ) {
// if (
// swiper.pagination &&
// swiper.params.pagination &&
// swiper.params.pagination.clickable &&
// (swiper.pagination.el === targetEl || swiper.pagination.el.contains(targetEl))
// )
// return;
// let isHidden;
// if ($nextEl) {
// isHidden = $nextEl.hasClass(swiper.params.navigation.hiddenClass);
// } else if ($prevEl) {
// isHidden = $prevEl.hasClass(swiper.params.navigation.hiddenClass);
// }
// if (isHidden === true) {
// emit('navigationShow');
// } else {
// emit('navigationHide');
// }
// if ($nextEl) {
// $nextEl.toggleClass(swiper.params.navigation.hiddenClass);
// }
// if ($prevEl) {
// $prevEl.toggleClass(swiper.params.navigation.hiddenClass);
// }
// }
// });
Object.assign(swiper.navigation, {
update,
init,
destroy,
});
}
.swiper-button-prev,
.swiper-button-next {
position: absolute;
top: 50%;
// width: calc(80rpx / 44 * 27);
height: 80rpx;
margin-top: calc(0rpx - (80rpx / 2));
z-index: 10;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
color: #007aff;
font-size: 50rpx;
&.swiper-button-disabled {
opacity: 0.35;
cursor: auto;
pointer-events: none;
}
&:after {
font-family: swiper-icons;
font-size: 80rpx;
text-transform: none !important;
letter-spacing: 0;
text-transform: none;
font-variant: initial;
line-height: 1;
}
}
.swiper-button-prev,
.swiper-rtl .swiper-button-next {
// &:after {
// content: 'prev';
// }
left: 10px;
right: auto;
}
.swiper-button-next,
.swiper-rtl .swiper-button-prev {
// &:after {
// content: 'next';
// }
right: 10px;
left: auto;
}
.swiper-button-lock {
display: none;
}
import classesToSelector from '../../shared/classes-to-selector.js';
export default function Pagination({
swiper,
extendParams,
on,
emit
}) {
const pfx = 'swiper-pagination';
extendParams({
pagination: {
el: null,
bulletElement: 'span',
clickable: false,
hideOnClick: false,
renderBullet: null,
renderProgressbar: null,
renderFraction: null,
renderCustom: null,
progressbarOpposite: false,
type: 'bullets', // 'bullets' or 'progressbar' or 'fraction' or 'custom'
dynamicBullets: false,
dynamicMainBullets: 1,
formatFractionCurrent: (number) => number,
formatFractionTotal: (number) => number,
bulletClass: `${pfx}-bullet`,
bulletActiveClass: `${pfx}-bullet-active`,
modifierClass: `${pfx}-`,
currentClass: `${pfx}-current`,
totalClass: `${pfx}-total`,
hiddenClass: `${pfx}-hidden`,
progressbarFillClass: `${pfx}-progressbar-fill`,
progressbarOppositeClass: `${pfx}-progressbar-opposite`,
clickableClass: `${pfx}-clickable`,
lockClass: `${pfx}-lock`,
horizontalClass: `${pfx}-horizontal`,
verticalClass: `${pfx}-vertical`,
},
});
swiper.pagination = {
el: null,
$el: null,
bullets: [],
};
let bulletSize;
let dynamicBulletIndex = 0;
function isPaginationDisabled() {
return (
!swiper.params.pagination.el ||
!swiper.pagination.el ||
!swiper.pagination.$el
);
}
function setSideBullets($bulletEl, position) {
const {
bulletActiveClass
} = swiper.params.pagination;
const bullets = swiper.pagination.bullets;
if (bullets[$bulletEl.index + position]) {
bullets[$bulletEl.index + position].addPaginationItemClass(
`${bulletActiveClass}-${position>0?'next':'prev'}`);
}
if (bullets[$bulletEl.index + (position > 0 ? position + 1 : position -
1)]) {
bullets[$bulletEl.index + (position > 0 ? position + 1 : position - 1)].addPaginationItemClass(
`${bulletActiveClass}-${position>0?'next':'prev'}-${position>0?'next':'prev'}`);
}
}
function update() {
// Render || Update Pagination bullets/items
const rtl = swiper.rtl;
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const slidesLength =
swiper.virtual && swiper.params.virtual.enabled ?
swiper.virtual.slides.length :
swiper.slides.length;
const $el = swiper.pagination.$el;
// Current/Total
let current;
const total = swiper.params.loop ?
Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
swiper.snapGrid.length;
if (swiper.params.loop) {
current = Math.ceil(
(swiper.activeIndex - swiper.loopedSlides) / swiper.params.slidesPerGroup,
);
if (current > slidesLength - 1 - swiper.loopedSlides * 2) {
current -= slidesLength - swiper.loopedSlides * 2;
}
if (current > total - 1) current -= total;
if (current < 0 && swiper.params.paginationType !== 'bullets') current = total + current;
} else if (typeof swiper.snapIndex !== 'undefined') {
current = swiper.snapIndex;
} else {
current = swiper.activeIndex || 0;
}
// Types
if (
params.type === 'bullets' &&
swiper.pagination.bullets &&
swiper.pagination.bullets.length > 0
) {
const bullets = swiper.pagination.bullets;
let firstIndex;
let lastIndex;
let midIndex;
if (params.dynamicBullets) {
bulletSize = bullets[0][swiper.isHorizontal() ? 'outerWidth' : 'outerHeight'];
swiper.$wrapperEl.paginationCss({
[swiper.isHorizontal() ? 'width' :
'height'
]: `${bulletSize * (params.dynamicMainBullets + 4)}px`
});
if (params.dynamicMainBullets > 1 && swiper.previousIndex !== undefined) {
dynamicBulletIndex += current - (swiper.previousIndex - swiper.loopedSlides || 0);
if (dynamicBulletIndex > params.dynamicMainBullets - 1) {
dynamicBulletIndex = params.dynamicMainBullets - 1;
} else if (dynamicBulletIndex < 0) {
dynamicBulletIndex = 0;
}
}
firstIndex = Math.max(current - dynamicBulletIndex, 0);
lastIndex = firstIndex + (Math.min(bullets.length, params.dynamicMainBullets) - 1);
midIndex = (lastIndex + firstIndex) / 2;
}
bullets.forEach((item) => {
item.removePaginationItemClass(
['', '-next', '-next-next', '-prev', '-prev-prev', '-main']
.map((suffix) => `${params.bulletActiveClass}${suffix}`)
.join(' '),
);
})
if ($el.length > 1) {
bullets.each((bullet) => {
const $bullet = $(bullet);
const bulletIndex = $bullet.index();
if (bulletIndex === current) {
$bullet.addClass(params.bulletActiveClass);
}
if (params.dynamicBullets) {
if (bulletIndex >= firstIndex && bulletIndex <= lastIndex) {
$bullet.addClass(`${params.bulletActiveClass}-main`);
}
if (bulletIndex === firstIndex) {
setSideBullets($bullet, 'prev');
}
if (bulletIndex === lastIndex) {
setSideBullets($bullet, 'next');
}
}
});
} else {
const $bullet = bullets[current];
const bulletIndex = $bullet.index;
$bullet.addPaginationItemClass(params.bulletActiveClass);
if (params.dynamicBullets) {
const $firstDisplayedBullet = bullets[firstIndex];
const $lastDisplayedBullet = bullets[lastIndex];
for (let i = firstIndex; i <= lastIndex; i += 1) {
bullets[i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
}
if (swiper.params.loop) {
if (bulletIndex >= bullets.length) {
for (let i = params.dynamicMainBullets; i >= 0; i -= 1) {
bullets[bullets.length - i].addPaginationItemClass(`${params.bulletActiveClass}-main`);
}
bullets
[bullets.length - params.dynamicMainBullets - 1]
.addPaginationItemClass(`${params.bulletActiveClass}-prev`);
} else {
setSideBullets($firstDisplayedBullet, -1);
setSideBullets($lastDisplayedBullet, 1);
}
} else {
setSideBullets($firstDisplayedBullet, -1);
setSideBullets($lastDisplayedBullet, 1);
}
}
}
if (params.dynamicBullets) {
const dynamicBulletsLength = Math.min(bullets.length, params.dynamicMainBullets + 4);
const bulletsOffset =
(bulletSize * dynamicBulletsLength - bulletSize) / 2 - midIndex * bulletSize;
const offsetProp = rtl ? 'right' : 'left';
bullets.forEach((item) => {
item.setCss({
[swiper.isHorizontal() ? offsetProp : 'top']: `${bulletsOffset}px`
})
})
// bullets.css(swiper.isHorizontal() ? offsetProp : 'top', `${bulletsOffset}px`);
}
}
if (params.type === 'fraction') {
// $el
// .find(classesToSelector(params.currentClass))
// .text(params.formatFractionCurrent(current + 1));
swiper.native.paginationContent.text = params.formatFractionCurrent(current + 1);
swiper.native.paginationContent.total = params.formatFractionTotal(total);
swiper.native.updateData({
paginationContent: swiper.native.paginationContent,
})
// $el.find(classesToSelector(params.totalClass)).text(params.formatFractionTotal(total));
}
if (params.type === 'progressbar') {
let progressbarDirection;
if (params.progressbarOpposite) {
progressbarDirection = swiper.isHorizontal() ? 'vertical' : 'horizontal';
} else {
progressbarDirection = swiper.isHorizontal() ? 'horizontal' : 'vertical';
}
const scale = (current + 1) / total;
let scaleX = 1;
let scaleY = 1;
if (progressbarDirection === 'horizontal') {
scaleX = scale;
} else {
scaleY = scale;
}
// $el
// .find(classesToSelector(params.progressbarFillClass))
swiper.native.paginationContent.transform(`translate3d(0,0,0) scaleX(${scaleX}) scaleY(${scaleY})`);
swiper.native.paginationContent.transition(swiper.params.speed);
swiper.native.updateData({
paginationContent: swiper.native.paginationContent,
})
}
if (params.type === 'custom' && params.renderCustom) {
$el.html(params.renderCustom(swiper, current + 1, total));
emit('paginationRender', $el[0]);
} else {
emit('paginationUpdate', $el[0]);
}
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? 'addPaginationClass' : 'removePaginationClass'](params.lockClass);
}
}
function render() {
// Render Container
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const slidesLength =
swiper.virtual && swiper.params.virtual.enabled ?
swiper.virtual.slides.length :
swiper.slides.length;
const $el = swiper.pagination.$el;
let paginationHTML = 0;
if (params.type === 'bullets') {
let numberOfBullets = swiper.params.loop ?
Math.ceil((slidesLength - swiper.loopedSlides * 2) / swiper.params.slidesPerGroup) :
swiper.snapGrid.length;
if (
swiper.params.freeMode &&
swiper.params.freeMode.enabled &&
!swiper.params.loop &&
numberOfBullets > slidesLength
) {
numberOfBullets = slidesLength;
}
for (let i = 0; i < numberOfBullets; i += 1) {
if (params.renderBullet) {
paginationHTML += params.renderBullet.call(swiper, i, params.bulletClass);
}
// else {
// paginationHTML +=
// `<${params.bulletElement} class="${params.bulletClass}"></${params.bulletElement}>`;
// }
// paginationHTML += 1;
else {
swiper.native.paginationType = "bullets";
swiper.native.paginationContent.push({
index: i,
outerWidth: 16,
outerHeight: 16,
classContent: [params.bulletClass],
styleContent: {},
addPaginationItemClass: function(value) {
this.classContent = Array.from(new Set([...this.classContent,
...value.split(" ")
]));
},
removePaginationItemClass: function(value) {
this.classContent = this.classContent.filter(item => !value.split(
" ").includes(item));
},
setCss: function(value) {
// vueNative['itemStyle'] = {
// ...vueNative['itemStyle'],
// ...value
// };Object.keys(value).forEach((item) => {
Object.keys(value).forEach((item) => {
// this.$set(this.itemStyle, item, value[item])
this.styleContent[item] = value[item];
})
// this.$set(this.itemStyle, item, value[item])
}
});
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
}
// $el.html(paginationHTML);
// swiper.$wrapperEl.addPaginationItemClass(params.bulletClass)
// swiper.pagination.bullets = $el.find(classesToSelector(params.bulletClass));
swiper.pagination.bullets = swiper.native.paginationContent;
}
if (params.type === 'fraction') {
if (params.renderFraction) {
paginationHTML = params.renderFraction.call(swiper, params.currentClass, params.totalClass);
} else {
swiper.native.paginationType = "fraction";
// paginationHTML =
// `<span class="${params.currentClass}"></span>` +
// ' / ' +
// `<span class="${params.totalClass}"></span>`;
swiper.native.paginationContent = {
currentClass: params.currentClass,
totalClass: params.totalClass
}
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
}
if (params.type === 'progressbar') {
if (params.renderProgressbar) {
paginationHTML = params.renderProgressbar.call(swiper, params.progressbarFillClass);
} else {
swiper.native.paginationType = "progressbar";
// paginationHTML = `<span class="${params.progressbarFillClass}"></span>`;
swiper.native.paginationContent = {
progressbarFillClass: params.progressbarFillClass,
styleContent: {
transform: '',
transitionDuration: ''
},
transition: function(value) {
this.styleContent.transitionDuration = `${value}ms`;
},
transform: function(value) {
this.styleContent.transform = value;
},
}
swiper.native.updateData({
paginationType: swiper.native.paginationType,
paginationContent: swiper.native.paginationContent,
})
}
// $el.html(paginationHTML);
}
if (params.type !== 'custom') {
emit('paginationRender', swiper.pagination.$el[0]);
}
}
function init() {
const params = swiper.params.pagination;
if (!params.el) return;
// swiper.native.showIndicators = true;
swiper.native.updateData({
showIndicators: true
})
let $el = params.el;
if (params.type === 'bullets' && params.clickable) {
swiper.$wrapperEl.addPaginationClass(params.clickableClass);
}
swiper.$wrapperEl.addPaginationClass(params.modifierClass + params.type);
swiper.$wrapperEl.addPaginationClass(params.modifierClass + swiper.params.direction);
if (params.type === 'bullets' && params.dynamicBullets) {
swiper.$wrapperEl.addPaginationClass(`${params.modifierClass}${params.type}-dynamic`);
dynamicBulletIndex = 0;
if (params.dynamicMainBullets < 1) {
params.dynamicMainBullets = 1;
}
}
if (params.type === 'progressbar' && params.progressbarOpposite) {
swiper.$wrapperEl.addPaginationClass(params.progressbarOppositeClass);
}
if (params.clickable) {
swiper.on('paginationItemClick', function onClick(_s, itemIndex) {
let index = itemIndex * swiper.params.slidesPerGroup;
if (swiper.params.loop) index += swiper.loopedSlides;
swiper.slideTo(index);
});
}
Object.assign(swiper.pagination, {
$el,
el: $el,
});
if (!swiper.enabled) {
swiper.$wrapperEl.addPaginationClass(params.lockClass);
}
}
function destroy() {
const params = swiper.params.pagination;
if (isPaginationDisabled()) return;
const $el = swiper.pagination.$el;
if (params.clickable) {
swiper.off('paginationItemClick', classesToSelector(params.bulletClass));
}
}
on('init update', () => {
if (swiper.native.paginationContent) {
swiper.native.updateData({
paginationContent: []
})
}
// swiper.native.paginationContent = [];
init();
render();
update();
});
on('activeIndexChange', () => {
if (swiper.params.loop) {
update();
} else if (typeof swiper.snapIndex === 'undefined') {
update();
}
});
on('snapIndexChange', () => {
if (!swiper.params.loop) {
update();
}
});
on('slidesLengthChange', () => {
if (swiper.params.loop) {
render();
update();
}
});
on('snapGridLengthChange', () => {
if (!swiper.params.loop) {
render();
update();
}
});
on('destroy', () => {
destroy();
});
on('enable disable', () => {
const {
$el
} = swiper.pagination;
if ($el) {
swiper.$wrapperEl[swiper.enabled ? 'removePaginationClass' : 'addPaginationClass'](swiper.params
.pagination.lockClass);
}
});
on('lock unlock', () => {
update();
});
on('click', (_s, e) => {
const targetEl = e.target;
const {
$el
} = swiper.pagination;
if (
swiper.params.pagination.el &&
swiper.params.pagination.hideOnClick &&
$el.length > 0 &&
!$(targetEl).hasClass(swiper.params.pagination.bulletClass)
) {
if (
swiper.navigation &&
((swiper.navigation.nextEl && targetEl === swiper.navigation.nextEl) ||
(swiper.navigation.prevEl && targetEl === swiper.navigation.prevEl))
)
return;
const isHidden = $el.hasClass(swiper.params.pagination.hiddenClass);
if (isHidden === true) {
emit('paginationShow');
} else {
emit('paginationHide');
}
$el.toggleClass(swiper.params.pagination.hiddenClass);
}
});
Object.assign(swiper.pagination, {
render,
update,
init,
destroy,
});
}
.swiper-pagination {
position: absolute;
text-align: center;
transition: 300ms opacity;
transform: translate3d(0, 0, 0);
z-index: 10;
font-size: 24rpx;
&.swiper-pagination-hidden {
opacity: 0;
}
}
/* Common Styles */
.swiper-pagination-fraction,
.swiper-pagination-custom,
.swiper-horizontal > .swiper-pagination-bullets,
.swiper-pagination-bullets.swiper-pagination-horizontal {
bottom: 10px;
left: 0;
width: 100%;
}
/* Bullets */
.swiper-pagination-bullets-dynamic {
overflow: hidden;
font-size: 0;
.swiper-pagination-bullet {
transform: scale(0.33);
position: relative;
}
.swiper-pagination-bullet-active {
transform: scale(1);
}
.swiper-pagination-bullet-active-main {
transform: scale(1);
}
.swiper-pagination-bullet-active-prev {
transform: scale(0.66);
}
.swiper-pagination-bullet-active-prev-prev {
transform: scale(0.33);
}
.swiper-pagination-bullet-active-next {
transform: scale(0.66);
}
.swiper-pagination-bullet-active-next-next {
transform: scale(0.33);
}
}
.swiper-pagination-bullet {
width: var(--swiper-pagination-bullet-width, var(--swiper-pagination-bullet-size, 8px));
height: var(--swiper-pagination-bullet-height, var(--swiper-pagination-bullet-size, 8px));
display: inline-block;
border-radius: 50%;
background: var(--swiper-pagination-bullet-inactive-color, #000);
opacity: var(--swiper-pagination-bullet-inactive-opacity, 0.2);
@at-root button#{&} {
border: none;
margin: 0;
padding: 0;
box-shadow: none;
appearance: none;
}
.swiper-pagination-clickable & {
cursor: pointer;
}
&:only-child {
display: none !important;
}
}
.swiper-pagination-bullet-active {
opacity: var(--swiper-pagination-bullet-opacity, 1);
background: var(--swiper-pagination-color, #007aff);
}
.swiper-vertical > .swiper-pagination-bullets,
.swiper-pagination-vertical.swiper-pagination-bullets {
right: 10px;
top: 50%;
transform: translate3d(0px, -50%, 0);
.swiper-pagination-bullet {
margin: var(--swiper-pagination-bullet-vertical-gap, 6px) 0;
display: block;
}
&.swiper-pagination-bullets-dynamic {
top: 50%;
transform: translateY(-50%);
width: 8px;
.swiper-pagination-bullet {
display: inline-block;
transition: 200ms transform, 200ms top;
}
}
}
.swiper-horizontal > .swiper-pagination-bullets,
.swiper-pagination-horizontal.swiper-pagination-bullets {
.swiper-pagination-bullet {
margin: 0 var(--swiper-pagination-bullet-horizontal-gap, 4px);
}
&.swiper-pagination-bullets-dynamic {
left: 50%;
transform: translateX(-50%);
white-space: nowrap;
.swiper-pagination-bullet {
transition: 200ms transform, 200ms left;
}
}
}
.swiper-horizontal.swiper-rtl > .swiper-pagination-bullets-dynamic .swiper-pagination-bullet {
transition: 200ms transform, 200ms right;
}
/* Progress */
.swiper-pagination-progressbar {
background: rgba(0, 0, 0, 0.25);
position: absolute;
.swiper-pagination-progressbar-fill {
background: var(--swiper-pagination-color, #007aff);
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
transform: scale(0);
transform-origin: left top;
}
.swiper-rtl & .swiper-pagination-progressbar-fill {
transform-origin: right top;
}
.swiper-horizontal > &,
&.swiper-pagination-horizontal,
.swiper-vertical > &.swiper-pagination-progressbar-opposite,
&.swiper-pagination-vertical.swiper-pagination-progressbar-opposite {
width: 100%;
height: 4px;
left: 0;
top: 0;
}
.swiper-vertical > &,
&.swiper-pagination-vertical,
.swiper-horizontal > &.swiper-pagination-progressbar-opposite,
&.swiper-pagination-horizontal.swiper-pagination-progressbar-opposite {
width: 4px;
height: 100%;
left: 0;
top: 0;
}
}
.swiper-pagination-lock {
display: none;
}
import {
nextTick
} from '../../shared/utils.js';
export default function Scrollbar({
swiper,
extendParams,
on,
emit
}) {
let isTouched = false;
let timeout = null;
let dragTimeout = null;
let dragStartPos;
let dragSize;
let trackSize;
let divider;
extendParams({
scrollbar: {
el: null,
dragSize: 'auto',
hide: false,
draggable: false,
snapOnRelease: true,
lockClass: 'swiper-scrollbar-lock',
dragClass: 'swiper-scrollbar-drag',
},
});
swiper.scrollbar = {
el: null,
dragEl: null,
$el: null,
$dragEl: null,
};
function setTranslate() {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
const {
scrollbar,
rtlTranslate: rtl,
progress
} = swiper;
const params = swiper.params.scrollbar;
let newSize = dragSize;
let newPos = (trackSize - dragSize) * progress;
if (rtl) {
newPos = -newPos;
if (newPos > 0) {
newSize = dragSize - newPos;
newPos = 0;
} else if (-newPos + dragSize > trackSize) {
newSize = trackSize + newPos;
}
} else if (newPos < 0) {
newSize = dragSize + newPos;
newPos = 0;
} else if (newPos + dragSize > trackSize) {
newSize = trackSize - newPos;
}
if (swiper.isHorizontal()) {
swiper.$wrapperEl.scrollbarItemTransform(`translate3d(${newPos}px, 0, 0)`);
swiper.$wrapperEl.scrollbarItemCss({
width: `${newSize}px`
})
} else {
swiper.$wrapperEl.scrollbarItemTransform(`translate3d(0px, ${newPos}px, 0)`);
swiper.$wrapperEl.scrollbarItemCss({
height: `${newSize}px`
})
}
if (params.hide) {
clearTimeout(timeout);
swiper.$wrapperEl.scrollbarCss({
opacity: 1
})
timeout = setTimeout(() => {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
swiper.$wrapperEl.scrollbarTransition(400)
}, 1000);
}
}
function setTransition(duration) {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
swiper.$wrapperEl.scrollbarItemTransition(duration);
}
async function updateSize() {
if (!swiper.params.scrollbar.el || !swiper.scrollbar.el) return;
const {
scrollbar
} = swiper;
const {
$el,
methods
} = scrollbar;
swiper.$wrapperEl.scrollbarItemCss({
width: '',
height: ''
})
let rectInfo = await swiper.native.getRectScrollbar();
methods.offset = function() {
return rectInfo;
}
trackSize = swiper.isHorizontal() ? rectInfo.width : rectInfo.height;
divider =
swiper.size /
(swiper.virtualSize +
swiper.params.slidesOffsetBefore -
(swiper.params.centeredSlides ? swiper.snapGrid[0] : 0));
if (swiper.params.scrollbar.dragSize === 'auto') {
dragSize = trackSize * divider;
} else {
dragSize = parseInt(swiper.params.scrollbar.dragSize, 10);
}
if (swiper.isHorizontal()) {
swiper.$wrapperEl.scrollbarItemCss({
width: `${dragSize}px`
})
} else {
swiper.$wrapperEl.scrollbarItemCss({
height: `${dragSize}px`
})
}
if (divider >= 1) {
swiper.$wrapperEl.scrollbarCss({
display: 'none'
})
} else {
swiper.$wrapperEl.scrollbarCss({
display: ''
})
}
if (swiper.params.scrollbar.hide) {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
}
if (swiper.params.watchOverflow && swiper.enabled) {
swiper.$wrapperEl[swiper.isLocked ? 'addScrollbarClass' : 'removeScrollbarClass'](
swiper.params.scrollbar.lockClass,
);
}
}
function getPointerPosition(e) {
if (swiper.isHorizontal()) {
return e.type === 'touchstart' || e.type === 'touchmove' || 'touchStart' || e.type === 'touchMove' ?
e.touches[0].clientX :
e.clientX;
}
return e.type === 'touchstart' || e.type === 'touchmove' ?
e.touches[0].clientY :
e.clientY;
}
function setDragPosition(e) {
const {
scrollbar,
rtlTranslate: rtl
} = swiper;
const {
$el,
methods
} = scrollbar;
let positionRatio;
positionRatio =
(getPointerPosition(e) -
methods.offset()[swiper.isHorizontal() ? 'left' : 'top'] -
(dragStartPos !== null ? dragStartPos : dragSize / 2)) /
(trackSize - dragSize);
positionRatio = Math.max(Math.min(positionRatio, 1), 0);
if (rtl) {
positionRatio = 1 - positionRatio;
}
const position =
swiper.minTranslate() + (swiper.maxTranslate() - swiper.minTranslate()) * positionRatio;
swiper.updateProgress(position);
swiper.setTranslate(position);
swiper.updateActiveIndex();
swiper.updateSlidesClasses();
}
function onDragStart(_s, e) {
const params = swiper.params.scrollbar;
const {
scrollbar,
$wrapperEl
} = swiper;
isTouched = true;
dragStartPos =
// e.target ===
// $dragEl[0] || e.target === $dragEl ?
// getPointerPosition(e) -
// e.target.getBoundingClientRect()[swiper.isHorizontal() ? 'left' : 'top'] :
null;
// e.preventDefault();
// e.stopPropagation();
$wrapperEl.transition(100);
swiper.$wrapperEl.scrollbarItemTransition(100)
// $dragEl.transition(100);
setDragPosition(e);
clearTimeout(dragTimeout);
swiper.$wrapperEl.scrollbarTransition(0)
if (params.hide) {
swiper.$wrapperEl.scrollbarCss({
opacity: 1
})
}
if (swiper.params.cssMode) {
swiper.$wrapperEl.css({
'scroll-snap-type': 'none'
});
}
emit('scrollbarDragStart', e);
}
function onDragMove(_s, e) {
const {
scrollbar,
$wrapperEl
} = swiper;
if (!isTouched) return;
setDragPosition(e);
$wrapperEl.transition(0);
swiper.$wrapperEl.scrollbarTransition(0)
swiper.$wrapperEl.scrollbarItemTransition(0)
emit('scrollbarDragMove', e);
}
function onDragEnd(_s, e) {
const params = swiper.params.scrollbar;
const {
scrollbar,
$wrapperEl
} = swiper;
const {
$el
} = scrollbar;
if (!isTouched) return;
isTouched = false;
if (swiper.params.cssMode) {
swiper.$wrapperEl.css({
'scroll-snap-type': ''
});
$wrapperEl.transition('');
}
if (params.hide) {
clearTimeout(dragTimeout);
dragTimeout = nextTick(() => {
swiper.$wrapperEl.scrollbarCss({
opacity: 0
})
swiper.$wrapperEl.scrollbarTransition(400)
}, 1000);
}
emit('scrollbarDragEnd', e);
if (params.snapOnRelease) {
swiper.slideToClosest();
}
}
function events(method) {
const {
scrollbar,
touchEventsTouch,
touchEventsDesktop,
params,
support
} = swiper;
const $el = scrollbar.$el;
const target = $el;
const activeListener =
support.passiveListener && params.passiveListeners ? {
passive: false,
capture: false
} :
false;
const passiveListener =
support.passiveListener && params.passiveListeners ? {
passive: true,
capture: false
} :
false;
if (!target) return;
const eventMethod = method === 'on' ? 'on' : 'off';
if (!support.touch) {
swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
} else {
swiper[eventMethod]('touchStartScrollbar', onDragStart, activeListener);
swiper[eventMethod]('touchMoveScrollbar', onDragMove, activeListener);
swiper[eventMethod]('touchEndScrollbar', onDragEnd, passiveListener);
}
}
function enableDraggable() {
if (!swiper.params.scrollbar.el) return;
events('on');
}
function disableDraggable() {
if (!swiper.params.scrollbar.el) return;
events('off');
}
function init() {
const {
scrollbar,
} = swiper;
const params = swiper.params.scrollbar;
if (!params.el) return;
// swiper.native.updateData({
// scrollbarShow: true
// })
let $el = params.el;
Object.assign(scrollbar, {
$el,
el: $el,
methods: {}
});
if (params.draggable) {
enableDraggable();
}
swiper.$wrapperEl[swiper.enabled ? 'removeScrollbarClass' : 'addScrollbarClass'](swiper.params.scrollbar
.lockClass);
return true;
}
function destroy() {
disableDraggable();
}
on('init', async () => {
await init();
updateSize();
setTranslate();
});
on('update resize observerUpdate lock unlock', () => {
updateSize();
});
on('setTranslate', () => {
setTranslate();
});
on('setTransition', (_s, duration) => {
setTransition(duration);
});
on('enable disable', () => {
const {
$el
} = swiper.scrollbar;
if ($el) {
$el[swiper.enabled ? 'removeClass' : 'addClass'](swiper.params.scrollbar.lockClass);
}
});
on('destroy', () => {
destroy();
});
Object.assign(swiper.scrollbar, {
updateSize,
setTranslate,
init,
destroy,
});
}
/* Scrollbar */
.swiper-scrollbar {
border-radius: 10px;
position: relative;
-ms-touch-action: none;
background: rgba(0, 0, 0, 0.1);
.swiper-horizontal > & {
position: absolute;
left: 1%;
bottom: 3px;
z-index: 50;
height: 5px;
width: 98%;
}
.swiper-vertical > & {
position: absolute;
right: 3px;
top: 1%;
z-index: 50;
width: 5px;
height: 98%;
}
}
.swiper-scrollbar-drag {
height: 100%;
width: 100%;
position: relative;
background: rgba(0, 0, 0, 0.5);
border-radius: 10px;
left: 0;
top: 0;
}
.swiper-scrollbar-cursor-drag {
cursor: move;
}
.swiper-scrollbar-lock {
display: none;
}
import {
isObject
} from '../../shared/utils.js';
// import $ from '../../shared/dom.js';
export default function Thumb({
swiper,
extendParams,
on
}) {
extendParams({
thumbs: {
swiper: null,
multipleActiveThumbs: true,
autoScrollOffset: 0,
slideThumbActiveClass: 'swiper-slide-thumb-active',
thumbsContainerClass: 'swiper-thumbs',
},
});
let initialized = false;
let swiperCreated = false;
swiper.thumbs = {
swiper: null,
};
function onThumbClick() {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
const clickedIndex = thumbsSwiper.clickedIndex;
const clickedSlide = thumbsSwiper.clickedSlide;
if (clickedSlide && clickedSlide.hasClass(swiper.params.thumbs.slideThumbActiveClass))
return;
if (typeof clickedIndex === 'undefined' || clickedIndex === null) return;
let slideToIndex;
if (thumbsSwiper.params.loop) {
slideToIndex = parseInt($(thumbsSwiper.clickedSlide).attr('data-swiper-slide-index'), 10);
} else {
slideToIndex = clickedIndex;
}
if (swiper.params.loop) {
let currentIndex = swiper.activeIndex;
if (swiper.slides.eq(currentIndex).hasClass(swiper.params.slideDuplicateClass)) {
swiper.loopFix();
// eslint-disable-next-line
swiper._clientLeft = swiper.$wrapperEl[0].clientLeft;
currentIndex = swiper.activeIndex;
}
const prevIndex = swiper.slides
.eq(currentIndex)
.prevAll(`[data-swiper-slide-index="${slideToIndex}"]`)
.eq(0)
.index();
const nextIndex = swiper.slides
.eq(currentIndex)
.nextAll(`[data-swiper-slide-index="${slideToIndex}"]`)
.eq(0)
.index();
if (typeof prevIndex === 'undefined') slideToIndex = nextIndex;
else if (typeof nextIndex === 'undefined') slideToIndex = prevIndex;
else if (nextIndex - currentIndex < currentIndex - prevIndex) slideToIndex = nextIndex;
else slideToIndex = prevIndex;
}
swiper.slideTo(slideToIndex);
}
function init() {
const {
thumbs: thumbsParams
} = swiper.params;
if (initialized) return false;
initialized = true;
const SwiperClass = swiper.constructor;
if (thumbsParams.swiper instanceof SwiperClass) {
swiper.thumbs.swiper = thumbsParams.swiper;
Object.assign(swiper.thumbs.swiper.originalParams, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
Object.assign(swiper.thumbs.swiper.params, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
} else if (isObject(thumbsParams.swiper)) {
const thumbsSwiperParams = Object.assign({}, thumbsParams.swiper);
Object.assign(thumbsSwiperParams, {
watchSlidesProgress: true,
slideToClickedSlide: false,
});
swiper.thumbs.swiper = new SwiperClass(thumbsSwiperParams);
swiperCreated = true;
}
swiper.thumbs.swiper.$el && swiper.thumbs.swiper.$el.addClass(swiper.params.thumbs.thumbsContainerClass);
swiper.thumbs.swiper.on('slideClick', onThumbClick);
return true;
}
function update(initial) {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
const slidesPerView =
thumbsSwiper.params.slidesPerView === 'auto' ?
thumbsSwiper.slidesPerViewDynamic() :
thumbsSwiper.params.slidesPerView;
const autoScrollOffset = swiper.params.thumbs.autoScrollOffset;
const useOffset = autoScrollOffset && !thumbsSwiper.params.loop;
if (swiper.realIndex !== thumbsSwiper.realIndex || useOffset) {
let currentThumbsIndex = thumbsSwiper.activeIndex;
let newThumbsIndex;
let direction;
if (thumbsSwiper.params.loop) {
if (
thumbsSwiper.slides
.eq(currentThumbsIndex)
.hasClass(thumbsSwiper.params.slideDuplicateClass)
) {
thumbsSwiper.loopFix();
// eslint-disable-next-line
thumbsSwiper._clientLeft = thumbsSwiper.$wrapperEl[0].clientLeft;
currentThumbsIndex = thumbsSwiper.activeIndex;
}
// Find actual thumbs index to slide to
const prevThumbsIndex = thumbsSwiper.slides
.eq(currentThumbsIndex)
.prevAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
.eq(0)
.index();
const nextThumbsIndex = thumbsSwiper.slides
.eq(currentThumbsIndex)
.nextAll(`[data-swiper-slide-index="${swiper.realIndex}"]`)
.eq(0)
.index();
if (typeof prevThumbsIndex === 'undefined') {
newThumbsIndex = nextThumbsIndex;
} else if (typeof nextThumbsIndex === 'undefined') {
newThumbsIndex = prevThumbsIndex;
} else if (nextThumbsIndex - currentThumbsIndex === currentThumbsIndex - prevThumbsIndex) {
newThumbsIndex =
thumbsSwiper.params.slidesPerGroup > 1 ? nextThumbsIndex : currentThumbsIndex;
} else if (nextThumbsIndex - currentThumbsIndex < currentThumbsIndex - prevThumbsIndex) {
newThumbsIndex = nextThumbsIndex;
} else {
newThumbsIndex = prevThumbsIndex;
}
direction = swiper.activeIndex > swiper.previousIndex ? 'next' : 'prev';
} else {
newThumbsIndex = swiper.realIndex;
direction = newThumbsIndex > swiper.previousIndex ? 'next' : 'prev';
}
if (useOffset) {
newThumbsIndex += direction === 'next' ? autoScrollOffset : -1 * autoScrollOffset;
}
if (
thumbsSwiper.visibleSlidesIndexes &&
thumbsSwiper.visibleSlidesIndexes.indexOf(newThumbsIndex) < 0
) {
if (thumbsSwiper.params.centeredSlides) {
if (newThumbsIndex > currentThumbsIndex) {
newThumbsIndex = newThumbsIndex - Math.floor(slidesPerView / 2) + 1;
} else {
newThumbsIndex = newThumbsIndex + Math.floor(slidesPerView / 2) - 1;
}
} else if (
newThumbsIndex > currentThumbsIndex &&
thumbsSwiper.params.slidesPerGroup === 1
) {
// newThumbsIndex = newThumbsIndex - slidesPerView + 1;
}
thumbsSwiper.slideTo(newThumbsIndex, initial ? 0 : undefined);
}
}
// Activate thumbs
let thumbsToActivate = 1;
const thumbActiveClass = swiper.params.thumbs.slideThumbActiveClass;
if (swiper.params.slidesPerView > 1 && !swiper.params.centeredSlides) {
thumbsToActivate = swiper.params.slidesPerView;
}
if (!swiper.params.thumbs.multipleActiveThumbs) {
thumbsToActivate = 1;
}
thumbsToActivate = Math.floor(thumbsToActivate);
// thumbsSwiper.slides.removeClass(thumbActiveClass);
thumbsSwiper.slides.forEach((item) => {
item.addClass(swiper.params.slideThumbsClass);
item.removeClass(thumbActiveClass);
})
if (
thumbsSwiper.params.loop ||
(thumbsSwiper.params.virtual && thumbsSwiper.params.virtual.enabled)
) {
for (let i = 0; i < thumbsToActivate; i += 1) {
thumbsSwiper.$wrapperEl
.children(`[data-swiper-slide-index="${swiper.realIndex + i}"]`)
.addClass(thumbActiveClass);
}
} else {
for (let i = 0; i < thumbsToActivate; i += 1) {
thumbsSwiper.slides[swiper.realIndex + i].addClass(thumbActiveClass);
}
}
}
on('beforeInit', () => {
const {
thumbs
} = swiper.params;
if (!thumbs || !thumbs.swiper) return;
init();
update(true);
});
on('slideChange update resize observerUpdate', () => {
if (!swiper.thumbs.swiper) return;
update();
});
on('setTransition', (_s, duration) => {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
thumbsSwiper.setTransition(duration);
});
on('beforeDestroy', () => {
const thumbsSwiper = swiper.thumbs.swiper;
if (!thumbsSwiper) return;
if (swiperCreated && thumbsSwiper) {
thumbsSwiper.destroy();
}
});
Object.assign(swiper.thumbs, {
init,
update,
});
}
.swiper-thumbs {
}
.swiper-slide-thumb {
opacity: 0.4;
}
.swiper-slide-thumb-active {
// Styles for active thumb slide
opacity: 1;
}
\ No newline at end of file
export default function Virtual({
swiper,
extendParams,
on
}) {
extendParams({
virtual: {
enabled: false,
slides: [],
cache: true,
renderSlide: null,
renderExternal: null,
renderExternalUpdate: true,
addSlidesBefore: 0,
addSlidesAfter: 0,
},
});
let cssModeTimeout;
swiper.virtual = {
cache: {},
from: undefined,
to: undefined,
slides: [],
offset: 0,
slidesGrid: [],
};
function renderSlide(slide, index) {
const params = swiper.params.virtual;
if (params.cache && swiper.virtual.cache[index]) {
return swiper.virtual.cache[index];
}
// const $slideEl = params.renderSlide ?
// $(params.renderSlide.call(swiper, slide, index)) :
// $(
// `<div class="${swiper.params.slideClass}" data-swiper-slide-index="${index}">${slide}</div>`,
// );
// if (!$slideEl.attr('data-swiper-slide-index')) $slideEl.attr('data-swiper-slide-index', index);
// if (params.cache) swiper.virtual.cache[index] = $slideEl;
// return $slideEl;
}
function onRendered() {
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
if (swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
}
async function update(force) {
const {
slidesPerView,
slidesPerGroup,
centeredSlides
} = swiper.params;
const {
addSlidesBefore,
addSlidesAfter
} = swiper.params.virtual;
const {
from: previousFrom,
to: previousTo,
slides,
slidesGrid: previousSlidesGrid,
offset: previousOffset,
} = swiper.virtual;
if (!swiper.params.cssMode) {
swiper.updateActiveIndex();
}
const activeIndex = swiper.activeIndex || 0;
let offsetProp;
if (swiper.rtlTranslate) offsetProp = 'right';
else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
let slidesAfter;
let slidesBefore;
if (centeredSlides) {
slidesAfter = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesAfter;
slidesBefore = Math.floor(slidesPerView / 2) + slidesPerGroup + addSlidesBefore;
} else {
slidesAfter = slidesPerView + (slidesPerGroup - 1) + addSlidesAfter;
slidesBefore = slidesPerGroup + addSlidesBefore;
}
const from = Math.max((activeIndex || 0) - slidesBefore, 0);
const to = Math.min((activeIndex || 0) + slidesAfter, slides.length - 1);
const offset = (swiper.slidesGrid[from] || 0) - (swiper.slidesGrid[0] || 0);
Object.assign(swiper.virtual, {
from,
to,
offset,
slidesGrid: swiper.slidesGrid,
});
function onRendered() {
swiper.updateSlides();
swiper.updateProgress();
swiper.updateSlidesClasses();
if (swiper.lazy && swiper.params.lazy.enabled) {
swiper.lazy.load();
}
}
if (previousFrom === from && previousTo === to && !force) {
if (swiper.slidesGrid !== previousSlidesGrid && offset !== previousOffset) {
swiper.slides.css(offsetProp, `${offset}px`);
}
swiper.updateProgress();
return;
}
if (swiper.params.virtual.renderExternal) {
swiper.params.virtual.renderExternal.call(swiper, {
offset,
from,
to,
slides: (function getSlides() {
const slidesToRender = [];
if (swiper.params.virtual.type == 'keep') {
for (let i = 0; i < from; i += 1) {
slidesToRender.push("");
}
}
for (let i = from; i <= to; i += 1) {
slidesToRender.push(slides[i]);
}
return slidesToRender;
})(),
});
if (swiper.params.virtual.renderExternalUpdate) {
onRendered();
}
return;
}
const prependIndexes = [];
const appendIndexes = [];
if (force) {
swiper.$wrapperEl.find(`.${swiper.params.slideClass}`).remove();
} else {
for (let i = previousFrom; i <= previousTo; i += 1) {
if (i < from || i > to) {
swiper.virtualList.splice(swiper.virtualList.findIndex((item) => {
return item == slides[i]
}), 1)
swiper.virtualIndexList.splice(swiper.virtualIndexList.findIndex((item) => {
return item == i
}), 1)
// swiper.slides[i].virtualShow = false;
}
}
}
for (let i = 0; i < slides.length; i += 1) {
if (i >= from && i <= to) {
if (typeof previousTo === 'undefined' || force) {
appendIndexes.push(i);
} else {
if (i > previousTo) appendIndexes.push(i);
if (i < previousFrom) prependIndexes.push(i);
}
}
}
// let list = [];
appendIndexes.forEach((index) => {
// if (swiper.slides[index]) {
// swiper.slides[index].virtualShow = true;
// } else {
swiper.virtualList.push(slides[index]);
swiper.virtualIndexList.push(index)
// }
// renderSlide(slides[index], index)
// renderSlide(slides[index], index)
// swiper.$wrapperEl.append(renderSlide(slides[index], index));
});
prependIndexes
.sort((a, b) => b - a)
.forEach((index) => {
// swiper.slides[index].virtualShow = true;
swiper.virtualList.unshift(slides[index]);
swiper.virtualIndexList.unshift(index)
// swiper.$wrapperEl.prepend(renderSlide(slides[index], index));
});
swiper.native.emit("input", [swiper.virtualList])
onRendered();
}
function appendSlide(slides) {
if (typeof slides === 'object' && 'length' in slides) {
for (let i = 0; i < slides.length; i += 1) {
if (slides[i]) swiper.virtual.slides.push(slides[i]);
}
} else {
swiper.virtual.slides.push(slides);
}
update(true);
}
function prependSlide(slides) {
const activeIndex = swiper.activeIndex;
let newActiveIndex = activeIndex + 1;
let numberOfNewSlides = 1;
if (Array.isArray(slides)) {
for (let i = 0; i < slides.length; i += 1) {
if (slides[i]) swiper.virtual.slides.unshift(slides[i]);
}
newActiveIndex = activeIndex + slides.length;
numberOfNewSlides = slides.length;
} else {
swiper.virtual.slides.unshift(slides);
}
if (swiper.params.virtual.cache) {
const cache = swiper.virtual.cache;
const newCache = {};
Object.keys(cache).forEach((cachedIndex) => {
const $cachedEl = cache[cachedIndex];
const cachedElIndex = $cachedEl.attr('data-swiper-slide-index');
if (cachedElIndex) {
$cachedEl.attr(
'data-swiper-slide-index',
parseInt(cachedElIndex, 10) + numberOfNewSlides,
);
}
newCache[parseInt(cachedIndex, 10) + numberOfNewSlides] = $cachedEl;
});
swiper.virtual.cache = newCache;
}
update(true);
swiper.slideTo(newActiveIndex, 0);
}
function removeSlide(slidesIndexes) {
if (typeof slidesIndexes === 'undefined' || slidesIndexes === null) return;
let activeIndex = swiper.activeIndex;
if (Array.isArray(slidesIndexes)) {
for (let i = slidesIndexes.length - 1; i >= 0; i -= 1) {
swiper.virtual.slides.splice(slidesIndexes[i], 1);
if (swiper.params.virtual.cache) {
delete swiper.virtual.cache[slidesIndexes[i]];
}
if (slidesIndexes[i] < activeIndex) activeIndex -= 1;
activeIndex = Math.max(activeIndex, 0);
}
} else {
swiper.virtual.slides.splice(slidesIndexes, 1);
if (swiper.params.virtual.cache) {
delete swiper.virtual.cache[slidesIndexes];
}
if (slidesIndexes < activeIndex) activeIndex -= 1;
activeIndex = Math.max(activeIndex, 0);
}
update(true);
swiper.slideTo(activeIndex, 0);
}
function removeAllSlides() {
swiper.virtual.slides = [];
if (swiper.params.virtual.cache) {
swiper.virtual.cache = {};
}
update(true);
swiper.slideTo(0, 0);
}
on('beforeInit', () => {
if (!swiper.params.virtual.enabled) return;
swiper.virtual.slides = swiper.params.virtual.slides;
swiper.classNames.push(`${swiper.params.containerModifierClass}virtual`);
swiper.params.watchSlidesProgress = true;
swiper.originalParams.watchSlidesProgress = true;
if (!swiper.params.initialSlide) {
update();
}
});
// on('beforeUpdate', () => {
// if (!swiper.params.virtual.enabled) return;
// let offsetProp;
// if (swiper.rtlTranslate) offsetProp = 'right';
// else offsetProp = swiper.isHorizontal() ? 'left' : 'top';
// swiper.slides.forEach((item, index) => {
// item.dataSwiperSlideIndex = swiper.virtualIndexList[index];
// item.css({
// [offsetProp]: `${swiper.virtual.offset}px`
// })
// })
// })
on('setTranslate', async () => {
if (!swiper.params.virtual.enabled) return;
if (swiper.params.cssMode && !swiper._immediateVirtual) {
clearTimeout(cssModeTimeout);
cssModeTimeout = setTimeout(() => {
update();
}, 100);
} else {
console.log("update==========")
clearTimeout(cssModeTimeout);
cssModeTimeout = setTimeout(() => {
update();
}, 100);
// update();
}
});
Object.assign(swiper.virtual, {
appendSlide,
prependSlide,
removeSlide,
removeAllSlides,
update,
});
}
.swiper-virtual.swiper-css-mode {
.swiper-wrapper::after {
content: '';
position: absolute;
left: 0;
top: 0;
pointer-events: none;
}
&.swiper-horizontal .swiper-wrapper::after {
height: 1px;
width: var(--swiper-virtual-size);
}
&.swiper-vertical .swiper-wrapper::after {
width: 1px;
height: var(--swiper-virtual-size);
}
}
export default function WillChange({
swiper,
extendParams,
on
}) {
on('setTransition', (s, duration) => {
if (!swiper.params.willChange) return;
if (swiper.params.effect == "slide" || swiper.params.effect == "cube" || swiper.params.effect ==
"coverflow" || swiper.params.effect == "panorama") {
swiper.$wrapperEl.willChange("transform");
}
});
on('transitionEnd', (s, duration) => {
if (!swiper.params.willChange) return;
swiper.$wrapperEl.willChange("auto");
swiper.slides.forEach((item) => {
item.$itemEl.willChange("auto");
})
});
}
{
"name": "@zebra-ui/swiper",
"id": "zebra-swiper",
"displayName": "zebra-swiper 3D轮播,全面对标swiperjs并实现全端兼容。",
"version": "2.2.6",
"description": "适配多端的高自定义轮播组件,多种3D效果。全面对标swiperjs。",
"main": "index.js",
"keywords": [
"zebra",
"swiper",
"轮播",
"3D",
"banner"
],
"repository": "https://github.com/zebra-ui/zebra-uniapp-swiper",
"bugs": {
"url": "https://github.com/zebra-ui/zebra-uniapp-swiper/issues"
},
"homepage": "https://github.com/zebra-ui/zebra-uniapp-swiper#readme",
"author": "zebra-ui",
"license": "ISC",
"publishConfig": {
"access": "public"
},
"engines": {
"HBuilderX": "^3.1.0"
},
"dcloudext": {
"sale": {
"regular": {
"price": "0.00"
},
"sourcecode": {
"price": "0.00"
}
},
"contact": {
"qq": ""
},
"declaration": {
"ads": "无",
"data": "插件不采集任何数据",
"permissions": "无"
},
"npmurl": "https://www.npmjs.com/package/@zebra-ui/swiper",
"type": "component-vue"
},
"uni_modules": {
"dependencies": [],
"encrypt": [],
"platforms": {
"cloud": {
"tcb": "y",
"aliyun": "y"
},
"client": {
"Vue": {
"vue2": "y",
"vue3": "y"
},
"App": {
"app-vue": "y",
"app-nvue": "n"
},
"H5-mobile": {
"Safari": "y",
"Android Browser": "y",
"微信浏览器(Android)": "y",
"QQ浏览器(Android)": "y"
},
"H5-pc": {
"Chrome": "y",
"IE": "y",
"Edge": "y",
"Firefox": "y",
"Safari": "y"
},
"小程序": {
"微信": "y",
"阿里": "y",
"百度": "y",
"字节跳动": "y",
"QQ": "y",
"钉钉": "u",
"快手": "y",
"飞书": "y",
"京东": "u"
},
"快应用": {
"华为": "y",
"联盟": "y"
}
}
}
}
}
export default function classesToSelector(classes = '') {
return `.${classes.trim().replace(/([\.:!\/])/g, '\\$1') // eslint-disable-line
.replace(/ /g, '.')}`;
}
\ No newline at end of file
export default function effectInit(params) {
const {
effect,
swiper,
on,
setTranslate,
setTransition,
overwriteParams,
perspective
} = params;
on('beforeInit', () => {
if (swiper.params.effect !== effect) return;
swiper.classNames.push(`${swiper.params.containerModifierClass}${effect}`);
if (perspective && perspective()) {
swiper.classNames.push(`${swiper.params.containerModifierClass}3d`);
}
const overwriteParamsResult = overwriteParams ? overwriteParams() : {};
Object.assign(swiper.params, overwriteParamsResult);
Object.assign(swiper.originalParams, overwriteParamsResult);
});
on('setTranslate', () => {
if (swiper.params.effect !== effect) return;
setTranslate();
});
on('setTransition', (_s, duration) => {
if (swiper.params.effect !== effect) return;
setTransition(duration);
});
}
\ No newline at end of file
export default function effectTarget(effectParams, $slideEl) {
if (effectParams.transformEl) {
return $slideEl.find(effectParams.transformEl).css({
'backface-visibility': 'hidden',
'-webkit-backface-visibility': 'hidden'
});
}
return $slideEl;
}
\ No newline at end of file
export default function effectVirtualTransitionEnd({
swiper,
duration,
transformEl,
allSlides
}) {
const {
slides,
activeIndex,
$wrapperEl
} = swiper;
if (swiper.params.virtualTranslate && duration !== 0) {
let eventTriggered = false;
let $transitionEndTarget;
if (allSlides) {
$transitionEndTarget = transformEl ? slides.find(transformEl) : slides;
} else {
$transitionEndTarget = transformEl ? slides.eq(activeIndex).find(transformEl) : slides[activeIndex];
}
for (let i = 0; i < $transitionEndTarget.length; i += 1) {
$transitionEndTarget[i].transitionEnd(() => {
if (eventTriggered) return;
if (!swiper || swiper.destroyed) return;
eventTriggered = true;
swiper.animating = false;
// const triggerEvents = ['webkitTransitionEnd', 'transitionend'];
swiper.emit('transitionEnd');
// for (let i = 0; i < triggerEvents.length; i += 1) {
// $wrapperEl.trigger(triggerEvents[i]);
// }
}, duration);
}
}
}
let browser;
function calcBrowser() {
function isSafari() {
const res = uni.getSystemInfoSync();
return res.model;
}
return {
isSafari: isSafari(),
isWebView: /(iPhone|iPod|iPad).*AppleWebKit(?!.*Safari)/i.test(isSafari())
};
}
function getBrowser() {
if (!browser) {
browser = calcBrowser();
}
return browser;
}
export {
getBrowser
};
import {
getSupport
} from './get-support.js';
let deviceCached;
function calcDevice({
userAgent
} = {}) {
const support = getSupport();
const device = {
ios: false,
android: false
};
const res = uni.getSystemInfoSync();
if (res.platform == "android") {
device.os = 'android';
device.android = true;
}
if (res.platform == "ios") {
device.os = 'ios';
device.ios = true;
} // Export object
return device;
}
function getDevice(overrides = {}) {
if (!deviceCached) {
deviceCached = calcDevice(overrides);
}
return deviceCached;
}
export {
getDevice
};
let support;
function getMobile() {
if (navigator.userAgent.indexOf('Mobile') > -1) {
return true;
} else {
return false;
}
}
function calcSupport() {
return {
smoothScroll: true,
// #ifdef H5
touch: getMobile(),
// #endif
// #ifndef H5
touch: true,
// #endif
passiveListener: function checkPassiveListener() {
let supportsPassive = false;
try {
const opts = Object.defineProperty({}, 'passive', {
// eslint-disable-next-line
get() {
supportsPassive = true;
}
});
} catch (e) { // No support
}
return supportsPassive;
}(),
gestures: function checkGestures() {
return false;
}()
};
}
function getSupport() {
if (!support) {
support = calcSupport();
}
return support;
}
export {
getSupport
};
function deleteProps(obj) {
const object = obj;
Object.keys(object).forEach(key => {
try {
object[key] = null;
} catch (e) { // no getter for object
}
try {
delete object[key];
} catch (e) { // something got wrong
}
});
}
function getTranslate(el, axis = 'x') {
let curTransform;
if (axis === 'x') {
curTransform = el.translate;
}
if (axis === 'y') {
curTransform = el.translate;
}
return curTransform || 0;
}
function isObject(o) {
return typeof o === 'object' && o !== null && o.constructor && Object.prototype.toString.call(o).slice(8, -1) ===
'Object';
}
function now() {
return Date.now();
}
function nextTick(callback, delay = 0) {
return setTimeout(callback, delay);
}
function extend(...args) {
const to = Object(args[0]);
const noExtend = ['__proto__', 'constructor', 'prototype'];
for (let i = 1; i < args.length; i += 1) {
const nextSource = args[i];
if (nextSource !== undefined && nextSource !== null) {
const keysArray = Object.keys(Object(nextSource)).filter(key => noExtend.indexOf(key) < 0);
for (let nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex += 1) {
const nextKey = keysArray[nextIndex];
const desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
if (desc !== undefined && desc.enumerable) {
if (isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
if (nextSource[nextKey].__swiper__) {
to[nextKey] = nextSource[nextKey];
} else {
extend(to[nextKey], nextSource[nextKey]);
}
} else if (!isObject(to[nextKey]) && isObject(nextSource[nextKey])) {
to[nextKey] = {};
if (nextSource[nextKey].__swiper__) {
to[nextKey] = nextSource[nextKey];
} else {
extend(to[nextKey], nextSource[nextKey]);
}
} else {
to[nextKey] = nextSource[nextKey];
}
}
}
}
}
return to;
}
function setCSSProperty(el, varName, varValue) {
el.style.setProperty(varName, varValue);
}
function animateCSSModeScroll({
swiper,
targetPosition,
side
}) {
const window = getWindow();
const startPosition = -swiper.translate;
let startTime = null;
let time;
const duration = swiper.params.speed;
swiper.wrapperEl.style.scrollSnapType = 'none';
window.cancelAnimationFrame(swiper.cssModeFrameID);
const dir = targetPosition > startPosition ? 'next' : 'prev';
const isOutOfBound = (current, target) => {
return dir === 'next' && current >= target || dir === 'prev' && current <= target;
};
const animate = () => {
time = new Date().getTime();
if (startTime === null) {
startTime = time;
}
const progress = Math.max(Math.min((time - startTime) / duration, 1), 0);
const easeProgress = 0.5 - Math.cos(progress * Math.PI) / 2;
let currentPosition = startPosition + easeProgress * (targetPosition - startPosition);
if (isOutOfBound(currentPosition, targetPosition)) {
currentPosition = targetPosition;
}
swiper.wrapperEl.scrollTo({
[side]: currentPosition
});
if (isOutOfBound(currentPosition, targetPosition)) {
swiper.wrapperEl.style.overflow = 'hidden';
swiper.wrapperEl.style.scrollSnapType = '';
setTimeout(() => {
swiper.wrapperEl.style.overflow = '';
swiper.wrapperEl.scrollTo({
[side]: currentPosition
});
});
window.cancelAnimationFrame(swiper.cssModeFrameID);
return;
}
swiper.cssModeFrameID = window.requestAnimationFrame(animate);
};
animate();
}
export {
deleteProps,
extend,
nextTick,
now,
setCSSProperty,
animateCSSModeScroll,
getTranslate,
isObject
};
@font-face {
font-family: 'iconfont';
/* project id 3161382 */
src: url('?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_3161382_m9empg4v7s.woff2') format('woff2'),
url('//at.alicdn.com/t/font_3161382_m9empg4v7s.woff') format('woff'),
url('//at.alicdn.com/t/font_3161382_m9empg4v7s.ttf') format('truetype'),
url('#iconfont') format('svg');
}
.zebra-icon {
font-family: "iconfont" !important;
font-size: inherit;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.zebra-icon-circle_chevron_left:before {
content: "\e611";
}
.zebra-icon-circle_chevron_right:before {
content: "\e615";
}
$gray-3: #ebedf0;
$gray-8: #323233;
$animation-duration-fast: 0.2s;
$swipe-indicator-size: 12rpx;
$swipe-indicator-margin: 24rpx;
$swipe-indicator-active-opacity: 1;
$swipe-indicator-inactive-opacity: 0.3;
$swipe-indicator-active-background-color: #1989fa;
$swipe-indicator-inactive-background-color: #323233;
\ No newline at end of file
function onTouchStartWxs(event, ins) {
ins.callMethod("onTouchStartSwiperWxs", {
changedTouches: event.changedTouches,
currentTarget: event.currentTarget,
touches: event.touches,
type: event.type
})
}
function onTouchMoveWxs(event, ins) {
ins.callMethod("onTouchMoveSwiperWxs", {
changedTouches: event.changedTouches,
currentTarget: event.currentTarget,
touches: event.touches,
type: event.type
})
}
function onTouchEndWxs(event, ins) {
ins.callMethod("onTouchEndSwiperWxs", {
changedTouches: event.changedTouches,
currentTarget: event.currentTarget,
touches: event.touches,
type: event.type
})
}
function wxsTransformObserver(newValue, oldValue, ownerInstance, instance) {
instance.setStyle({
transform: newValue
})
}
function wxsItemTransformObserver(newValue, oldValue, ownerInstance, instance) {
instance.setStyle({
transform: newValue
})
}
module.exports = {
onTouchStartWxs: onTouchStartWxs,
onTouchMoveWxs: onTouchMoveWxs,
onTouchEndWxs: onTouchEndWxs,
wxsTransformObserver: wxsTransformObserver,
wxsItemTransformObserver: wxsItemTransformObserver
}
var system_info = {};
if (uni) {
system_info = uni.getSystemInfoSync();
}
export default {
app: "150414001",
secret: "5C7B92CF77E1535BE41F45A0F04057EA",
server_url: {
app_host: "https://app.ydniu.com/",
// 192.168.1.97
//app_host:"http://192.168.1.97:4000/",
},
/*#ifdef H5*/
//对应逻辑
is_h5: true,
/*#endif*/
app_info: {
"AppName": "一定牛", //system_info.appName
"PromoterId": 419,
"Version": "1.0.1", //system_info.appVersion
"platform": system_info.platform, //
"device": system_info.model, //system_info.model
"appId": "com.qh.sports", //system_info.appId
"deviceId": system_info.deviceId
}
}
/**
* 对比版本号,如需要,请自行修改判断规则
* 支持比对 ("3.0.0.0.0.1.0.1", "3.0.0.0.0.1") ("3.0.0.1", "3.0") ("3.1.1", "3.1.1.1") 之类的
* @param {Object} v1
* @param {Object} v2
* v1 > v2 return 1
* v1 < v2 return -1
* v1 == v2 return 0
*/
const compare = {
compare(v1 = '0', v2 = '0') {
v1 = String(v1).split('.')
v2 = String(v2).split('.')
const minVersionLens = Math.min(v1.length, v2.length);
let result = 0;
for (let i = 0; i < minVersionLens; i++) {
const curV1 = Number(v1[i])
const curV2 = Number(v2[i])
if (curV1 > curV2) {
result = 1
break;
} else if (curV1 < curV2) {
result = -1
break;
}
}
if (result === 0 && (v1.length !== v2.length)) {
const v1BiggerThenv2 = v1.length > v2.length;
const maxLensVersion = v1BiggerThenv2 ? v1 : v2;
for (let i = minVersionLens; i < maxLensVersion.length; i++) {
const curVersion = Number(maxLensVersion[i])
if (curVersion > 0) {
v1BiggerThenv2 ? result = 1 : result = -1
break;
}
}
}
return result;
}
}
var updateUseModal = (packageInfo) => {
const {
title, // 标题
contents, // 升级内容
is_mandatory, // 是否强制更新
url, // 安装包下载地址
platform, // 安装包平台
type // 安装包类型
} = packageInfo;
let isWGT = type === 'wgt'
let isiOS = !isWGT ? platform.includes('iOS') : false;
let confirmText = isiOS ? '立即跳转更新' : '立即下载更新';
return uni.showModal({
title,
content: contents,
showCancel: !is_mandatory,
confirmText,
success: res => {
if (res.cancel) return;
var data = new Date();
uni.setStorageSync("updateUseModal", data.getDate());
// 安装包下载
if (isiOS) {
plus.runtime.openURL(url);
return;
}
console.log("")
let waiting = plus.nativeUI.showWaiting("正在下载 - 0%");
// uni.showLoading({
// title: '安装包下载中'
// });
// wgt 和 安卓下载更新
const downloadTask = uni.downloadFile({
url,
success: res => {
if (res.statusCode !== 200) {
console.error('下载安装包失败', err);
return;
}
// 下载好直接安装,下次启动生效
plus.runtime.install(res.tempFilePath, {
force: false
}, () => {
uni.hideLoading()
if (is_mandatory) {
//更新完重启app
plus.runtime.restart();
return;
}
uni.showModal({
title: '安装成功是否重启?',
success: res => {
if (res.confirm) {
//更新完重启app
plus.runtime.restart();
}
}
});
}, err => {
uni.hideLoading()
uni.showModal({
title: '更新失败',
content: err.message,
showCancel: false
});
});
},
//接口调用结束
complete: () => {
console.log("complete")
waiting.close();
uni.hideLoading();
downloadTask.offProgressUpdate(); //取消监听加载进度
plus.runtime.restart();
}
});
//监听下载进度
downloadTask.onProgressUpdate(res => {
// state.percent = res.progress;
if (res.progress) {
waiting.setTitle("正在下载 - " + res.progress + "%");
console.log('下载进度百分比:' + res.progress); // 下载进度百分比
}
// console.log('已经下载的数据长度:' + res.totalBytesWritten); // 已经下载的数据长度,单位 Bytes
// console.log('预期需要下载的数据总长度:' + res.totalBytesExpectedToWrite); // 预期需要下载的数据总长度,单位 Bytes
});
}
});
}
export {
updateUseModal,
compare
}
const common = {
statusBarH: 0,
customBarH: 0,
info_config: {
"qq_number": "2464595068",
"weixin": "a2025a",
"phone_code" : "400-176-6115",
"public_key": "520520",
"is_show_gp": false,
"is_show_cps": false,
"is_use_umeng_login": true,
"umeng_app_key": "54476386fd98c5c2b8022b90",
"umeng_app_secret": "TtyNv4W366hccrq5wiPAFuW0HQHEJ+p5YflK/7w6QQUmLe4BpYh/rujKChVPDH5k12SiaLhjfVo+adGkTzg6G1as/PxmlS3RAdfVnY9olWUDQBsuAiVzerzhs2IYi0kzBYgQQ/oV/6G12M+aiUURVMfggtKQUV6eCoErWwKWl2l6R1ixkzUuaZ4z7Ssg+jNMFSulLpkrr2j4st/f8Yow7MU+4HrkzjBIgqEcw1aPH/IQ8F7BJGt8V0n/dtMZRQFF4VNmNopTaSKntmEVPMJrhzu6qeAg3hsTs9D9shfHH9Q=",
"tencent_captcha": "2063970092",
"eshop_page": "https://app.ydniu.com/eshop/tv/list",
"is_show_eshop": false,
"model_data": {
"url": "http://www.xuanyutiyu.cn/share/dsjyqs/",
"photo": "http://xuanyutiyu.cn/share/images/t.png",
"title": "牛牛大数据",
"content": "精准分析大数据模型,全面大奖助力工具"
},
"ydn_show_interest": true,
"app_open_option": [{
"code": "home",
"name": "默认",
"pic": "https://img2.ydniu.com/app/images/start/home.png",
"is_show_experts": 0,
"is_show_start": true,
"home_url": ""
}, {
"code": "eshop",
"name": "店主服务",
"pic": "https://img2.ydniu.com/app/images/start/cd.png",
"is_show_experts": 0,
"is_show_start": true,
"home_url": "https://app.ydniu.com/eshop?noheader=true"
}, {
"code": "kl8",
"name": "快乐8",
"pic": "https://img2.ydniu.com/app/images/start/kl8.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_kl8/"
}, {
"code": "fc3d",
"name": "福彩3D",
"pic": "https://img2.ydniu.com/app/images/start/sd.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_sd/"
}, {
"code": "pl3",
"name": "排列3",
"pic": "https://img2.ydniu.com/app/images/start/pl3.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_pl3/"
}, {
"code": "ssq",
"name": "双色球",
"pic": "https://img2.ydniu.com/app/images/start/ssq.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_ssq/"
}, {
"code": "dlt",
"name": "大乐透",
"pic": "https://img2.ydniu.com/app/images/start/dlt.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_dlt/"
}, {
"code": "pl5",
"name": "排列5",
"pic": "https://img2.ydniu.com/app/images/start/pl5.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/index_pl5/"
}, {
"code": "qlc",
"name": "七乐彩",
"pic": "https://img2.ydniu.com/app/images/home/7lc.png",
"is_show_experts": 0,
"is_show_start": false
}, {
"code": "qxc",
"name": "七星彩",
"pic": "https://img2.ydniu.com/app/images/home/7xc.png",
"is_show_experts": 0,
"is_show_start": false
}, {
"code": "zq",
"name": "足球",
"pic": "https://img2.ydniu.com/app/images/start/zq.png",
"is_show_experts": 1,
"is_show_start": true,
"home_url": "https://app.ydniu.com/sports/"
}],
"index_lottery_config": {
"kl8": {
"杀码": [{
"key": "sm1",
"name": "杀一码",
"qs": 50,
"order": 1
}, {
"key": "sm2",
"name": "杀二码",
"qs": 10,
"order": 1
}, {
"key": "sm3",
"name": "杀三码",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "td2",
"name": "选三两胆",
"qs": 10,
"order": 1
}, {
"key": "td3",
"name": "选四三胆",
"qs": 10,
"order": 1
}, {
"key": "td4",
"name": "选五四胆",
"qs": 10,
"order": 1
}]
},
"ssq": {
"杀码": [{
"key": "红球杀一",
"name": "杀一红",
"qs": 50,
"order": 1
}, {
"key": "sm_h2",
"name": "杀双红",
"qs": 20,
"order": 1
}, {
"key": "红球杀三",
"name": "杀三红",
"qs": 20,
"order": 1
}],
"推胆": [{
"key": "红球双胆",
"name": "红球双胆",
"qs": 10,
"order": 1
}, {
"key": "td_h3",
"name": "红球三胆",
"qs": 10,
"order": 1
}, {
"key": "td_h4",
"name": "红球四胆",
"qs": 10,
"order": 1
}]
},
"dlt": {
"杀码": [{
"key": "前区杀一",
"name": "前区杀一",
"qs": 50,
"order": 1
}, {
"key": "sm_q2",
"name": "前区杀二",
"qs": 20,
"order": 1
}, {
"key": "前区杀三",
"name": "前区杀三",
"qs": 20,
"order": 1
}],
"推胆": [{
"key": "前区双胆",
"name": "前区双胆",
"qs": 10,
"order": 1
}, {
"key": "前区三胆",
"name": "前区三胆",
"qs": 10,
"order": 1
}, {
"key": "td_4",
"name": "前区四胆",
"qs": 10,
"order": 1
}]
},
"sd": {
"杀码": [{
"key": "杀一码",
"name": "杀一码",
"qs": 20,
"order": 1
}, {
"key": "杀二码",
"name": "杀二码",
"qs": 10,
"order": 1
}, {
"key": "杀三码",
"name": "杀三码",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "独胆",
"name": "独胆",
"qs": 10,
"order": 1
}, {
"key": "双胆",
"name": "双胆",
"qs": 20,
"order": 1
}, {
"key": "三胆",
"name": "三胆",
"qs": 20,
"order": 1
}]
},
"pl3": {
"杀码": [{
"key": "杀一码",
"name": "杀一码",
"qs": 20,
"order": 1
}, {
"key": "杀二码",
"name": "杀二码",
"qs": 10,
"order": 1
}, {
"key": "杀三码",
"name": "杀三码",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "独胆",
"name": "独胆",
"qs": 10,
"order": 1
}, {
"key": "双胆",
"name": "双胆",
"qs": 20,
"order": 1
}, {
"key": "三胆",
"name": "三胆",
"qs": 20,
"order": 1
}]
},
"pl5": {
"杀码": [{
"key": "g_sm1",
"name": "杀一码",
"qs": 10,
"order": 1
}, {
"key": "g_sm2",
"name": "杀二码",
"qs": 10,
"order": 1
}, {
"key": "g_sm3",
"name": "杀三码",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "g_d1",
"name": "独胆",
"qs": 10,
"order": 1
}, {
"key": "g_d2",
"name": "双胆",
"qs": 20,
"order": 1
}, {
"key": "g_d3",
"name": "三胆",
"qs": 20,
"order": 1
}]
},
"qxc": {
"杀码": [{
"key": "qq_sm1",
"name": "前区杀一",
"qs": 10,
"order": 1
}, {
"key": "qq_sm2",
"name": "前区杀二",
"qs": 10,
"order": 1
}, {
"key": "qq_sm3",
"name": "前区杀三",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "qq_d1",
"name": "前区独胆",
"qs": 10,
"order": 1
}, {
"key": "qq_d2",
"name": "前区双胆",
"qs": 10,
"order": 1
}, {
"key": "qq_d3",
"name": "前区三胆",
"qs": 10,
"order": 1
}]
},
"qlc": {
"杀码": [{
"key": "sm1",
"name": "杀一码",
"qs": 10,
"order": 1
}, {
"key": "sm2",
"name": "杀二码",
"qs": 10,
"order": 1
}, {
"key": "sm3",
"name": "杀三码",
"qs": 10,
"order": 1
}],
"推胆": [{
"key": "dm_d1",
"name": "独胆",
"qs": 10,
"order": 1
}, {
"key": "dm_d2",
"name": "双胆",
"qs": 10,
"order": 1
}, {
"key": "dm_d3",
"name": "三胆",
"qs": 10,
"order": 1
}]
}
}
},
getChannelCode() { // 获取渠道号
if (uni.getSystemInfoSync().platform == "android") {
var channels = new Map();
channels.set("yyb", 401);
channels.set("xiaomi", 402);
channels.set("huawei", 403);
channels.set("baidu", 404);
channels.set("360", 405);
channels.set("oppo", 406);
channels.set("vivo", 407);
channels.set("meizu", 408);
channels.set("anzhi", 409);
channels.set("liangxiang", 410);
channels.set("sougou", 411);
channels.set("mumayi", 412);
channels.set("samsung", 413);
channels.set("ali", 414);
channels.set("beiyong1", 415);
channels.set("beiyong2", 416);
channels.set("beiyong3", 417);
channels.set("beiyong4", 418);
channels.set("xm20210831", 419);
if (plus.runtime.channel) {
var channel_int = channels.get(plus.runtime.channel, 419)
return channel_int;
}
console.log("channel:" + plus.runtime.channel)
// 获取walle 的渠道名
// var main = plus.android.runtimeMainActivity();
// var walle = plus.android.importClass("com.meituan.android.walle.WalleChannelReader");
// if (walle) {
// var channel_str = walle.getChannel(main, "xm20210831");
// var channel_int = channels.get(channel_str, 419);
// return channel_int;
// }
return 419;
} else {
return 420;
}
}
}
export default common
var detaultHeaderOption = { 'Content-Type': 'application/json; charset=utf-8' };
import {default as app_config} from '../utils/app.js';
const http = {
async gql(parmas, loadding = false) {
console.debug("----http---", app_config.app_info)
return new Promise((resolve, reject) => {
let token = uni.getStorageSync('uni_cookie');
let header = {
'Cookie': token,
'AppVersion': encodeURI(JSON.stringify(app_config.app_info)),
...detaultHeaderOption
};
if(!token){
delete header.Cookie;
}
uni.request({
url: `${app_config.server_url.app_host}graphql`,
method:"POST",
data: parmas,
header: header,
success: (res) => {
let tokens = res.cookies;
if(res.header['connect.sid']){
uni.setStorageSync('uni_cookie',res.header['connect.sid'])
}
resolve(res.data)
},
fail: (error) => {
reject(error.data)
}
})
})
}
}
export default http;
\ No newline at end of file
function transformImageCodeToUri(code) {
if(!code) {
return ''
}
return "https://img2.ydniu.com/user/" + code + ".jpg/small"
}
export {
transformImageCodeToUri
}
\ No newline at end of file
let hasLogin = false;
let info = null;
const loginHelper = {
login(userInfo, appToken) {
console.log("login" + userInfo + "appToken:" + appToken)
uni.setStorageSync("appToken", appToken);
uni.setStorageSync("userName", userInfo.NickName);
uni.setStorageSync("headIcon", userInfo.FaceImageCode);
uni.setStorageSync('userInfo', userInfo)
if(!hasLogin) {
uni.$emit("loginStatus", true)
}
hasLogin = true;
info = userInfo;
},
logout() {
console.log("logout" + hasLogin)
uni.removeStorageSync('userName')
uni.removeStorageSync('headIcon')
uni.removeStorageSync('userInfo')
uni.removeStorageSync('appToken')
if(hasLogin) {
uni.$emit("loginStatus", false)
}
hasLogin = false;
info = null;
},
hasLogin() {
info = uni.getStorageSync('userInfo')
console.log(info)
if(info) {
hasLogin = true
} else {
hasLogin = false
}
return hasLogin;
},
getDefaultHeadIcon() {
return "/static/head_portrait.webp";
},
getUserInfo() {
if(!info) {
info = uni.getStorageSync('userInfo')
}
return info;
},
setUserInfo(userInfo) {
uni.setStorageSync('userInfo', userInfo)
info = userInfo;
},
getAppToken() {
return uni.getStorageSync("appToken");
}
}
export default loginHelper;
const str_const = {
is_first_open: "qh_is_fist_open",//是否首次打开app
is_first_show_guid: "qh_is_first_show_guid",//是否首次打开app,展示引导
is_remember_pass: 'qh_is_remember_pass',//是否记住密码
is_auto_login: 'qh_is_auto_login',//是否自动登录
}
export default str_const
\ No newline at end of file
const utils = {
getweekDay(time) {
let temp_data = new Date(time)
if (temp_data.getDay() === 0) return "星期天"
if (temp_data.getDay() === 1) return "星期一"
if (temp_data.getDay() === 2) return "星期二"
if (temp_data.getDay() === 3) return "星期三"
if (temp_data.getDay() === 4) return "星期四"
if (temp_data.getDay() === 5) return "星期五"
if (temp_data.getDay() === 6) return "星期六"
},
getweekDayZhou(time) {
let temp_data = new Date(time)
if (temp_data.getDay() === 0) return "周日"
if (temp_data.getDay() === 1) return "周一"
if (temp_data.getDay() === 2) return "周二"
if (temp_data.getDay() === 3) return "周三"
if (temp_data.getDay() === 4) return "周四"
if (temp_data.getDay() === 5) return "周五"
if (temp_data.getDay() === 6) return "周六"
},
dateFormat(time) {
let date = new Date(time);
let year = date.getFullYear();
// 在日期格式中,月份是从0开始的,因此要加0,使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
let hours = date.getHours() < 10 ? "0" + date.getHours() : date.getHours();
let minutes = date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes();
let seconds = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
// 拼接
return year + "-" + month + "-" + day + " " + hours + ":" + minutes;
},
dateFormatYear(time) {
let date = new Date(time);
let year = date.getFullYear();
// 在日期格式中,月份是从0开始的,因此要加0,使用三元表达式在小于10的前面加0,以达到格式统一 如 09:11:05
let month = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1;
let day = date.getDate() < 10 ? "0" + date.getDate() : date.getDate();
// 拼接
return year + "-" + month + "-" + day;
},
getTimeByISO(time) {
let temp_data = new Date(time).toJSON()
let bj_time = new Date(+new Date(temp_data) + 8 * 3600 * 1000).toISOString().replace(/T/g, ' ').replace(
/\.[\d]{3}Z/, '')
return bj_time
},
getWebView(header, top, height) {
let wv = plus.webview.create("", "square-webview", {
additionalHttpHeaders: {
header: header,
},
plusrequire: "none", //禁止远程网页使用plus的API,有些使用mui制作的网页可能会监听plus.key,造成关闭页面混乱,可以通过这种方式禁止
'uni-app': 'none', //不加载uni-app渲染层框架,避免样式冲突
top: top,
height: height,
})
wv.overrideUrlLoading({
mode: "reject"
}, (e) => {
console.log('-------拦截请求', e.url)
if (e.url.indexOf("?zq") !== -1) {
let tempData = {
url: e.url,
}
uni.navigateTo({
url: `/pages/notitle_h5/notitle_h5?info=${encodeURIComponent(JSON.stringify(tempData))}`
})
} else if (e.url.indexOf("login") !== -1) {
uni.navigateTo({
url: `/pages/login_account/login_account`
})
} else if (e.url.indexOf("?ydn_back") !== -1) {
uni.navigateBack({
})
} else {
if (e.url === 'https://app.ydniu.com/' || e.url === 'https://app.ydniu.com') {
uni.navigateBack({
})
}
}
})
return wv
},
getPassUrl() {
return 'https://app.ydniu.com/sports,https://app.ydniu.com/jczq/index'
},
getCurrentState(state, time) {
var result = "未";
switch (state) {
case 4:
case 10:
case 12:
result = "完";
break;
case 2:
result = "中场";
break;
case 5:
result = "中断";
break;
case 6:
result = "取消";
break;
case 13:
result = "延期";
break;
case 14:
result = "腰斩";
break;
case 15:
result = "待定";
break;
default:
if (state == 3) {
result = (time / (1000 * 60) + 45) + "'";
if ((time / (1000 * 60)) > 45) {
result = 90 + "+";
}
} else if (state == 1) {
result = time / (1000 * 60) + "'";
if (time / (1000 * 60) > 45) {
result = 45 + "+";
} else if (time / (1000 * 60) == 0) {
result = 1 + "'";
}
} else {
result = time / (1000 * 60) + "'";
}
break;
}
return result
},
diffCurrentDay(time) { // 获取相差天数
// 将时间字符串转换为 Date 对象
var targetDate = new Date(time);
// 获取当前时间
const currentDate = new Date();
// 计算当前时间与目标时间之间的差距(以毫秒为单位)
const timeDifference = currentDate.getTime() - targetDate.getTime();
// 计算差距的天数
const daysDifference = Math.abs(Math.floor(timeDifference / (1000 * 3600 * 24)));
return daysDifference
},
diffCurrentTime(time) { // 获取相差时间
// 将时间字符串转换为 Date 对象
var targetDate = new Date(time);
// 获取当前时间
const currentDate = new Date();
// 计算当前时间与目标时间之间的差距(以毫秒为单位)
const timeDifference = currentDate.getTime() - targetDate.getTime();
return timeDifference
}
}
export default utils;
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!