refactor: save
This commit is contained in:
parent
6976f58757
commit
db6a7b9aaf
21
src/App.vue
21
src/App.vue
@ -6,16 +6,16 @@
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
<BaseMask v-if="!isMobile" />
|
||||
<div v-if="!isMobile" class="guide">
|
||||
<Icon icon="mynaui:danger-triangle" />
|
||||
<div class="txt">
|
||||
<h2>切换至手机模式才可正常使用</h2>
|
||||
<h3>1. 按 F12 调出控制台</h3>
|
||||
<h3>2. 按 Ctrl+Shift+M,或点击下面图标</h3>
|
||||
</div>
|
||||
<img src="@/assets/img/guide.png" alt="" />
|
||||
<BaseMask v-if="!isMobile" />
|
||||
<div v-if="!isMobile" class="guide">
|
||||
<Icon icon="mynaui:danger-triangle" />
|
||||
<div class="txt">
|
||||
<h2>切换至手机模式才可正常使用</h2>
|
||||
<h3>1. 按 F12 调出控制台</h3>
|
||||
<h3>2. 按 Ctrl+Shift+M,或点击下面图标</h3>
|
||||
</div>
|
||||
<img src="@/assets/img/guide.png" alt="" />
|
||||
</div>
|
||||
<Call />
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
@ -34,7 +34,8 @@ import { BASE_URL } from '@/config'
|
||||
|
||||
const store = useBaseStore()
|
||||
const route = useRoute()
|
||||
const isMobile = ref(/Mobi|Android|iPhone/i.test(navigator.userAgent))
|
||||
// const isMobile = ref(/Mobi|Android|iPhone/i.test(navigator.userAgent))
|
||||
const isMobile = ref(true)
|
||||
const transitionName = ref('go')
|
||||
|
||||
// watch $route 决定使用哪种过渡
|
||||
|
||||
@ -128,6 +128,7 @@ export default {
|
||||
}
|
||||
|
||||
.add-ctn {
|
||||
cursor: pointer;
|
||||
@height: 27rem;
|
||||
@width: 36rem;
|
||||
height: @height;
|
||||
@ -147,6 +148,8 @@ export default {
|
||||
}
|
||||
|
||||
span {
|
||||
cursor: pointer;
|
||||
|
||||
font-weight: bold;
|
||||
opacity: 0.7;
|
||||
|
||||
|
||||
@ -123,6 +123,7 @@ export default {
|
||||
@import '../assets/less/index';
|
||||
|
||||
.scroll-wrapper {
|
||||
touch-action: pan-y;
|
||||
overflow: auto;
|
||||
|
||||
.scroll-content {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="UserPanel" @scroll="scroll" ref="page">
|
||||
<div id="UserPanel" @scroll="scroll" @dragstart="(e) => Utils.$stopPropagation(e)" ref="page">
|
||||
<div ref="float" class="float" :class="state.floatFixed ? 'fixed' : ''">
|
||||
<div class="left">
|
||||
<Icon @click="emit('back')" class="icon" icon="eva:arrow-ios-back-fill" />
|
||||
@ -405,6 +405,7 @@ function touchEnd() {
|
||||
}
|
||||
|
||||
#UserPanel {
|
||||
touch-action: pan-y;
|
||||
position: fixed;
|
||||
background: var(--color-user);
|
||||
height: 100%;
|
||||
|
||||
@ -23,13 +23,13 @@
|
||||
/>
|
||||
|
||||
<template v-if="state.operationStatus === SlideAlbumOperationStatus.Normal">
|
||||
<ItemToolbar
|
||||
class="mb3r"
|
||||
v-model:item="state.localItem"
|
||||
:position="position"
|
||||
v-bind="$attrs"
|
||||
/>
|
||||
<ItemDesc class="mb3r" v-model:item="state.localItem" :position="position" />
|
||||
<!-- <ItemToolbar-->
|
||||
<!-- class="mb3r"-->
|
||||
<!-- v-model:item="state.localItem"-->
|
||||
<!-- :position="position"-->
|
||||
<!-- v-bind="$attrs"-->
|
||||
<!-- />-->
|
||||
<!-- <ItemDesc class="mb3r" v-model:item="state.localItem" :position="position" />-->
|
||||
</template>
|
||||
<!--不知为啥touch事件,在下部20px的空间内不触发,加上click事件不好了 -->
|
||||
<div
|
||||
@ -106,8 +106,8 @@ import {
|
||||
slideInit,
|
||||
slideReset,
|
||||
slideTouchEnd,
|
||||
slidePointerMove,
|
||||
slidePointerDown
|
||||
slideTouchMove,
|
||||
slideTouchStart
|
||||
} from '@/utils/slide'
|
||||
import { SlideAlbumOperationStatus, SlideItemPlayStatus, SlideType } from '../../utils/const_var'
|
||||
import ItemToolbar from './ItemToolbar'
|
||||
@ -409,7 +409,7 @@ function touchStart(e) {
|
||||
// Utils.$showNoticeDialog('start'+e.touches.length)
|
||||
console.log('start', e.touches.length)
|
||||
if (e.touches.length === 1) {
|
||||
slidePointerDown(e, wrapperEl.value, state)
|
||||
slideTouchStart(e, wrapperEl.value, state)
|
||||
} else {
|
||||
if (state.operationStatus === SlideAlbumOperationStatus.Zooming) {
|
||||
// state.start.center = Utils.getCenter(state.start.point1, state.start.point2)
|
||||
@ -452,7 +452,7 @@ function touchMove(e) {
|
||||
} else {
|
||||
// console.log('m2')
|
||||
state.isAutoPlay = false
|
||||
slidePointerMove(
|
||||
slideTouchMove(
|
||||
e,
|
||||
wrapperEl.value,
|
||||
state,
|
||||
@ -579,7 +579,7 @@ function touchEnd(e) {
|
||||
startLoop()
|
||||
}
|
||||
)
|
||||
slideReset(wrapperEl.value, state)
|
||||
slideReset(e, wrapperEl.value, state)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,8 +4,8 @@ import GM from '../../utils'
|
||||
import {
|
||||
getSlideOffset,
|
||||
slideInit,
|
||||
slidePointerDown,
|
||||
slidePointerMove,
|
||||
slideTouchStart,
|
||||
slideTouchMove,
|
||||
slideReset,
|
||||
slideTouchEnd
|
||||
} from '@/utils/slide'
|
||||
@ -39,16 +39,20 @@ const props = defineProps({
|
||||
const emit = defineEmits(['update:index'])
|
||||
|
||||
let ob = null
|
||||
//slide-list的ref引用
|
||||
const wrapperEl = ref(null)
|
||||
|
||||
const state = reactive({
|
||||
judgeValue: 20,
|
||||
type: SlideType.HORIZONTAL,
|
||||
judgeValue: 20, //一个用于判断滑动朝向的固定值
|
||||
type: SlideType.HORIZONTAL, //组件类型
|
||||
name: props.name,
|
||||
localIndex: props.index,
|
||||
needCheck: true,
|
||||
next: false,
|
||||
start: { x: 0, y: 0, time: 0 },
|
||||
move: { x: 0, y: 0 },
|
||||
localIndex: props.index, //当前下标
|
||||
needCheck: true, //是否需要检测,每次按下都需要检测,up事件会重置为true
|
||||
next: false, //能否滑动
|
||||
isDown: false, //是否按下,用于move事件判断
|
||||
start: { x: 0, y: 0, time: 0 }, //按下时的起点坐标
|
||||
move: { x: 0, y: 0 }, //移动时的坐标
|
||||
//slide-list的宽度和子元素数量
|
||||
wrapper: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
@ -99,17 +103,17 @@ onUnmounted(() => {
|
||||
ob.disconnect()
|
||||
})
|
||||
|
||||
function touchStart(e: TouchEvent) {
|
||||
slidePointerDown(e, wrapperEl.value, state)
|
||||
function touchStart(e) {
|
||||
slideTouchStart(e, wrapperEl.value, state)
|
||||
}
|
||||
|
||||
function touchMove(e: TouchEvent) {
|
||||
slidePointerMove(e, wrapperEl.value, state)
|
||||
function touchMove(e) {
|
||||
slideTouchMove(e, wrapperEl.value, state)
|
||||
}
|
||||
|
||||
function touchEnd(e: TouchEvent) {
|
||||
function touchEnd(e) {
|
||||
slideTouchEnd(e, state)
|
||||
slideReset(wrapperEl.value, state, emit)
|
||||
slideReset(e, wrapperEl.value, state, emit)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -127,9 +131,9 @@ function touchEnd(e: TouchEvent) {
|
||||
<div
|
||||
class="slide-list"
|
||||
ref="wrapperEl"
|
||||
@touchstart="touchStart"
|
||||
@touchmove="touchMove"
|
||||
@touchend="touchEnd"
|
||||
@pointerdown="touchStart"
|
||||
@pointermove="touchMove"
|
||||
@pointerup="touchEnd"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
@ -141,16 +145,16 @@ function touchEnd(e: TouchEvent) {
|
||||
position: absolute;
|
||||
bottom: 10rem;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
gap: 7rem;
|
||||
|
||||
.bullet {
|
||||
@width: 5rem;
|
||||
width: @width;
|
||||
height: @width;
|
||||
margin: 0 3rem;
|
||||
border-radius: 50%;
|
||||
background: var(--second-btn-color);
|
||||
|
||||
|
||||
@ -6,8 +6,8 @@ import {
|
||||
slideInit,
|
||||
slideReset,
|
||||
slideTouchEnd,
|
||||
slidePointerMove,
|
||||
slidePointerDown
|
||||
slideTouchMove,
|
||||
slideTouchStart
|
||||
} from '@/utils/slide'
|
||||
import { SlideType } from '@/utils/const_var'
|
||||
|
||||
@ -22,21 +22,34 @@ const props = defineProps({
|
||||
changeActiveIndexUseAnim: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: () => 'SlideVertical'
|
||||
}
|
||||
})
|
||||
const emit = defineEmits(['update:index'])
|
||||
|
||||
//slide-list的ref引用
|
||||
const wrapperEl = ref(null)
|
||||
|
||||
const state = reactive({
|
||||
judgeValue: 20,
|
||||
type: SlideType.HORIZONTAL,
|
||||
name: 'SlideVertical',
|
||||
localIndex: props.index,
|
||||
needCheck: true,
|
||||
next: false,
|
||||
start: { x: 0, y: 0, time: 0 },
|
||||
move: { x: 0, y: 0 },
|
||||
wrapper: { width: 0, height: 0, childrenLength: 0 }
|
||||
judgeValue: 20, //一个用于判断滑动朝向的固定值
|
||||
type: SlideType.VERTICAL, //组件类型
|
||||
name: props.name,
|
||||
localIndex: props.index, //当前下标
|
||||
needCheck: true, //是否需要检测,每次按下都需要检测,up事件会重置为true
|
||||
next: false, //能否滑动
|
||||
isDown: false, //是否按下,用于move事件判断
|
||||
start: { x: 0, y: 0, time: 0 }, //按下时的起点坐标
|
||||
move: { x: 0, y: 0 }, //移动时的坐标
|
||||
//slide-list的宽度和子元素数量
|
||||
wrapper: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
//childrenLength用于canNext方法判断当前页是否是最后一页,是则不能滑动,不捕获事件
|
||||
childrenLength: 0
|
||||
}
|
||||
})
|
||||
|
||||
watch(
|
||||
@ -61,16 +74,16 @@ onMounted(() => {
|
||||
})
|
||||
|
||||
function touchStart(e) {
|
||||
slidePointerDown(e, wrapperEl.value, state)
|
||||
slideTouchStart(e, wrapperEl.value, state)
|
||||
}
|
||||
|
||||
function touchMove(e) {
|
||||
slidePointerMove(e, wrapperEl.value, state)
|
||||
slideTouchMove(e, wrapperEl.value, state)
|
||||
}
|
||||
|
||||
function touchEnd(e) {
|
||||
slideTouchEnd(e, state)
|
||||
slideReset(wrapperEl.value, state, emit)
|
||||
slideReset(e, wrapperEl.value, state, emit)
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -79,9 +92,9 @@ function touchEnd(e) {
|
||||
<div
|
||||
class="slide-list flex-direction-column"
|
||||
ref="wrapperEl"
|
||||
@touchstart="touchStart"
|
||||
@touchmove="touchMove"
|
||||
@touchend="touchEnd"
|
||||
@pointerdown="touchStart"
|
||||
@pointermove="touchMove"
|
||||
@pointerup="touchEnd"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
@ -6,8 +6,8 @@ import {
|
||||
slideInit,
|
||||
slideReset,
|
||||
slideTouchEnd,
|
||||
slidePointerMove,
|
||||
slidePointerDown
|
||||
slideTouchMove,
|
||||
slideTouchStart
|
||||
} from '@/utils/slide'
|
||||
import { SlideType } from '@/utils/const_var'
|
||||
import SlideItem from '@/components/slide/SlideItem.vue'
|
||||
@ -68,6 +68,7 @@ const state = reactive({
|
||||
localIndex: props.index,
|
||||
needCheck: true,
|
||||
next: false,
|
||||
isDown: false,
|
||||
start: { x: 0, y: 0, time: 0 },
|
||||
move: { x: 0, y: 0 },
|
||||
wrapper: { width: 0, height: 0, childrenLength: 0 }
|
||||
@ -226,12 +227,12 @@ function getInsEl(item, index, play = false) {
|
||||
}
|
||||
|
||||
function touchStart(e) {
|
||||
slidePointerDown(e, wrapperEl.value, state)
|
||||
slideTouchStart(e, wrapperEl.value, state)
|
||||
}
|
||||
|
||||
//TODO 2022-3-28:在最顶部,反复滑动会抖动一下,初步猜测是因为方向变了,导致的加判断距离变成了减
|
||||
function touchMove(e) {
|
||||
slidePointerMove(e, wrapperEl.value, state, canNext)
|
||||
slideTouchMove(e, wrapperEl.value, state, canNext)
|
||||
}
|
||||
|
||||
function touchEnd(e) {
|
||||
@ -310,7 +311,7 @@ function touchEnd(e) {
|
||||
state.wrapper.childrenLength = wrapperEl.value.children.length
|
||||
}
|
||||
})
|
||||
slideReset(wrapperEl.value, state, emit)
|
||||
slideReset(e, wrapperEl.value, state, emit)
|
||||
}
|
||||
|
||||
function canNext(state, isNext) {
|
||||
@ -328,9 +329,9 @@ function canNext(state, isNext) {
|
||||
class="slide-list flex-direction-column"
|
||||
ref="wrapperEl"
|
||||
@click="null"
|
||||
@touchstart="touchStart"
|
||||
@touchmove="touchMove"
|
||||
@touchend="touchEnd"
|
||||
@pointerdown="touchStart"
|
||||
@pointermove="touchMove"
|
||||
@pointerup="touchEnd"
|
||||
>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
||||
25
src/main.ts
25
src/main.ts
@ -8,6 +8,31 @@ import mixin from './utils/mixin'
|
||||
import VueLazyload from '@jambonn/vue-lazyload'
|
||||
import { createPinia } from 'pinia'
|
||||
|
||||
HTMLElement.prototype._rawAddEventListener_ = HTMLElement.prototype.addEventListener
|
||||
HTMLElement.prototype._rawRemoveEventListener_ = HTMLElement.prototype.removeEventListener
|
||||
window.isMoved = false
|
||||
HTMLElement.prototype.addEventListener = new Proxy(HTMLElement.prototype.addEventListener, {
|
||||
apply(target, ctx, args) {
|
||||
const eventName = args[0]
|
||||
const listener = args[1]
|
||||
// console.log('e', eventName, '')
|
||||
if (listener instanceof Function && eventName === 'click') {
|
||||
args[1] = new Proxy(listener, {
|
||||
apply(target, ctx, args) {
|
||||
// console.log('点击', window.isMoved)
|
||||
if (window.isMoved) return
|
||||
try {
|
||||
return target.apply(ctx, args)
|
||||
} catch (e) {
|
||||
console.error(`[proxyPlayerEvent][${eventName}]`, listener, e)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
return target.apply(ctx, args)
|
||||
}
|
||||
})
|
||||
|
||||
const pinia = createPinia()
|
||||
const emitter = mitt()
|
||||
const app = createApp(App)
|
||||
|
||||
@ -28,26 +28,74 @@ const t = [
|
||||
type: 'imgs',
|
||||
src: `https://imgapi.cn/bing.php`,
|
||||
author: {
|
||||
unique_id: 1
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'user',
|
||||
src: `https://imgapi.cn/bing.php`,
|
||||
author: {
|
||||
unique_id: 2
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 'img',
|
||||
src: `https://imgapi.cn/bing.php`,
|
||||
author: {
|
||||
unique_id: 3
|
||||
unique_id: 1,
|
||||
avatar_168x168: {
|
||||
url_list: []
|
||||
},
|
||||
avatar_300x300: {
|
||||
url_list: []
|
||||
},
|
||||
cover_url: [
|
||||
{
|
||||
url_list: []
|
||||
}
|
||||
],
|
||||
white_cover_url: [
|
||||
{
|
||||
url_list: []
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
// {
|
||||
// type: 'user',
|
||||
// src: `https://imgapi.cn/bing.php`,
|
||||
// author: {
|
||||
// unique_id: 2,
|
||||
// avatar_168x168: {
|
||||
// url_list: []
|
||||
// },
|
||||
// avatar_300x300: {
|
||||
// url_list: []
|
||||
// },
|
||||
// cover_url: [
|
||||
// {
|
||||
// url_list: []
|
||||
// }
|
||||
// ],
|
||||
// white_cover_url: [
|
||||
// {
|
||||
// url_list: []
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// type: 'img',
|
||||
// src: `https://imgapi.cn/bing.php`,
|
||||
// author: {
|
||||
// unique_id: 3,
|
||||
// avatar_168x168: {
|
||||
// url_list: []
|
||||
// },
|
||||
// avatar_300x300: {
|
||||
// url_list: []
|
||||
// },
|
||||
// cover_url: [
|
||||
// {
|
||||
// url_list: []
|
||||
// }
|
||||
// ],
|
||||
// white_cover_url: [
|
||||
// {
|
||||
// url_list: []
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
]
|
||||
|
||||
// allRecommendVideos.unshift(...t)
|
||||
allRecommendVideos.unshift(...t)
|
||||
// {
|
||||
// type: 'user-imgs',
|
||||
// src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`,
|
||||
|
||||
@ -346,6 +346,7 @@ function dislike() {
|
||||
overflow: hidden;
|
||||
|
||||
.sidebar {
|
||||
touch-action: pan-y;
|
||||
width: 80vw;
|
||||
height: calc(var(--vh, 1vh) * 100);
|
||||
overflow: auto;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div id="Community">
|
||||
<div id="Community" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedPost">
|
||||
<template v-slot="{ list }">
|
||||
<div class="search" @click="nav('/home/search')">
|
||||
@ -47,7 +47,7 @@
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { $no, _checkImgUrl, cloneDeep } from '@/utils'
|
||||
import Utils, { $no, _checkImgUrl, cloneDeep } from '@/utils'
|
||||
import { recommendedPost } from '@/api/user'
|
||||
import { useNav } from '@/utils/hooks/useNav'
|
||||
import { Icon } from '@iconify/vue'
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import { reactive, ref, watch } from 'vue'
|
||||
import { _checkImgUrl, _duration, _formatNumber } from '@/utils'
|
||||
import Utils, { _checkImgUrl, _duration, _formatNumber } from '@/utils'
|
||||
import { recommendedVideo } from '@/api/videos'
|
||||
import ScrollList from '@/components/ScrollList.vue'
|
||||
import { useNav } from '@/utils/hooks/useNav'
|
||||
@ -78,7 +78,7 @@ const nav = useNav()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="long-video">
|
||||
<div class="long-video" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedVideo">
|
||||
<template v-slot="{ list }">
|
||||
<div class="list">
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="goods-detail">
|
||||
<div class="goods-detail" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||
<header>
|
||||
<Icon @click="close" icon="material-symbols-light:arrow-back-ios-new" />
|
||||
<div class="option" @click="nav('/home/search')">
|
||||
@ -99,7 +99,7 @@ import SlideItem from '@/components/slide/SlideItem.vue'
|
||||
import { reactive, ref } from 'vue'
|
||||
import { useNav } from '@/utils/hooks/useNav'
|
||||
import { Icon } from '@iconify/vue'
|
||||
import { _checkImgUrl } from '@/utils'
|
||||
import Utils, { _checkImgUrl } from '@/utils'
|
||||
|
||||
const nav = useNav()
|
||||
|
||||
@ -181,7 +181,6 @@ function close() {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
object-fit: cover;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.indicator-bar {
|
||||
|
||||
@ -4,6 +4,21 @@ import GM from '@/utils/index'
|
||||
import { SlideType } from '@/utils/const_var'
|
||||
import { nextTick } from 'vue'
|
||||
|
||||
function checkEvent(e) {
|
||||
const isMobile = /Mobi|Android|iPhone/i.test(navigator.userAgent)
|
||||
if (!isMobile || (isMobile && e instanceof PointerEvent)) {
|
||||
e.touches = [
|
||||
{
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY,
|
||||
pageX: e.pageX,
|
||||
pageY: e.pageY
|
||||
}
|
||||
]
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
//初始化信息,获取slide dom的长宽、子元素数量,用于move事件判断能否滑动
|
||||
export function slideInit(el, state) {
|
||||
state.wrapper.width = GM.$getCss(el, 'width')
|
||||
@ -13,7 +28,7 @@ export function slideInit(el, state) {
|
||||
})
|
||||
|
||||
//获取偏移量
|
||||
let t = getSlideOffset(state, el)
|
||||
const t = getSlideOffset(state, el)
|
||||
let dx1 = 0,
|
||||
dx2 = 0
|
||||
if (state.type === SlideType.HORIZONTAL) dx1 = t
|
||||
@ -21,18 +36,9 @@ export function slideInit(el, state) {
|
||||
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
||||
}
|
||||
|
||||
export function slidePointerDown(e, el, state) {
|
||||
Utils.$setCss(el, 'transition-duration', `0ms`)
|
||||
//记录起点坐标,用于move事件计算移动距离
|
||||
state.start.x = e.touches[0].pageX
|
||||
state.start.y = e.touches[0].pageY
|
||||
//记录按下时间,用于up事件判断滑动时间
|
||||
state.start.time = Date.now()
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测能否滑动
|
||||
* @param state
|
||||
* 检测在对应方向上能否允许滑动,比如SlideHorizontal组件就只处理左右滑动事件,SlideVertical只处理上下滑动事件
|
||||
* * @param state
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function canSlide(state) {
|
||||
@ -41,7 +47,7 @@ export function canSlide(state) {
|
||||
//判断move x和y的距离是否大于判断值,因为距离太小无法判断滑动方向
|
||||
if (Math.abs(state.move.x) > state.judgeValue || Math.abs(state.move.y) > state.judgeValue) {
|
||||
//放大再相除,根据长宽比判断方向,angle大于1就是左右滑动,小于是上下滑动
|
||||
let angle = (Math.abs(state.move.x) * 10) / (Math.abs(state.move.y) * 10)
|
||||
const angle = (Math.abs(state.move.x) * 10) / (Math.abs(state.move.y) * 10)
|
||||
//根据当前slide的类型,判断能否滑动,并记录下来,后续不再判断,直接返回记录值
|
||||
state.next = state.type === SlideType.HORIZONTAL ? angle > 1 : angle <= 1
|
||||
// console.log('angle', angle, state.next)
|
||||
@ -66,6 +72,25 @@ function canNext(state, isNext) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始滑动
|
||||
* @param e
|
||||
* @param el
|
||||
* @param state
|
||||
*/
|
||||
export function slideTouchStart(e, el, state) {
|
||||
console.log('e', e, state.name)
|
||||
return
|
||||
if (!checkEvent(e)) return
|
||||
Utils.$setCss(el, 'transition-duration', `0ms`)
|
||||
//记录起点坐标,用于move事件计算移动距离
|
||||
state.start.x = e.touches[0].pageX
|
||||
state.start.y = e.touches[0].pageY
|
||||
//记录按下时间,用于up事件判断滑动时间
|
||||
state.start.time = Date.now()
|
||||
state.isDown = true
|
||||
}
|
||||
|
||||
/**
|
||||
* move事件
|
||||
* @param e
|
||||
@ -75,7 +100,7 @@ function canNext(state, isNext) {
|
||||
* @param notNextCb 不能继续滑的回调
|
||||
* @param slideOtherDirectionCb 滑动其他方向时的回调,目前用于图集进于放大模式后,上下滑动推出放大模式
|
||||
*/
|
||||
export function slidePointerMove(
|
||||
export function slideTouchMove(
|
||||
e,
|
||||
el,
|
||||
state,
|
||||
@ -83,16 +108,20 @@ export function slidePointerMove(
|
||||
notNextCb = null,
|
||||
slideOtherDirectionCb = null
|
||||
) {
|
||||
if (!checkEvent(e)) return
|
||||
if (!state.isDown) return
|
||||
// console.log('move', state.name)
|
||||
|
||||
//计算移动距离
|
||||
state.move.x = e.touches[0].pageX - state.start.x
|
||||
state.move.y = e.touches[0].pageY - state.start.y
|
||||
// console.log('move', state.name)
|
||||
|
||||
//检测能否滑动
|
||||
let canSlideRes = canSlide(state)
|
||||
const canSlideRes = canSlide(state)
|
||||
|
||||
//是否是往下(右)滑动
|
||||
let isNext = state.type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
|
||||
//是否在往到头或尾滑动
|
||||
const isNext = state.type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
|
||||
|
||||
//特别处理:竖直的slide组件,在第一页往下滑动时,向外发送事件
|
||||
//用于首页顶部导航栏的刷新动画
|
||||
@ -107,13 +136,14 @@ export function slidePointerMove(
|
||||
//无限滑动组件,要特别判断,所以需要传canNextCb
|
||||
if (!canNextCb) canNextCb = canNext
|
||||
if (canNextCb(state, isNext)) {
|
||||
window.isMoved = true
|
||||
//能滑动,那就把事件捕获,不能给父组件处理
|
||||
Utils.$stopPropagation(e)
|
||||
if (state.type === SlideType.HORIZONTAL) {
|
||||
bus.emit(state.name + '-moveX', state.move.x)
|
||||
}
|
||||
//获取偏移量
|
||||
let t = getSlideOffset(state, el) + (isNext ? state.judgeValue : -state.judgeValue)
|
||||
const t = getSlideOffset(state, el) + (isNext ? state.judgeValue : -state.judgeValue)
|
||||
let dx1 = 0,
|
||||
dx2 = 0
|
||||
//偏移量加当前手指移动的距离就是slide要偏移的值
|
||||
@ -143,25 +173,28 @@ export function slidePointerMove(
|
||||
* @returns {*}
|
||||
*/
|
||||
export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNextCb = null) {
|
||||
let isHorizontal = state.type === SlideType.HORIZONTAL
|
||||
let isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
||||
if (!checkEvent(e)) return
|
||||
if (!state.isDown) return
|
||||
|
||||
const isHorizontal = state.type === SlideType.HORIZONTAL
|
||||
const isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
||||
|
||||
if (state.next) {
|
||||
//同move事件
|
||||
if (!canNextCb) canNextCb = canNext
|
||||
if (canNextCb(state, isNext)) {
|
||||
//能滑动,那就把事件捕获,不能给父组件处理
|
||||
Utils.$stopPropagation(e)
|
||||
// Utils.$stopPropagation(e)
|
||||
//结合时间、距离来判断是否成功滑动
|
||||
let endTime = Date.now()
|
||||
const endTime = Date.now()
|
||||
let gapTime = endTime - state.start.time
|
||||
let distance = isHorizontal ? state.move.x : state.move.y
|
||||
let judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
|
||||
const distance = isHorizontal ? state.move.x : state.move.y
|
||||
const judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
|
||||
//1、距离太短,直接不通过
|
||||
if (Math.abs(distance) < 20) gapTime = 1000
|
||||
//2、距离太长,直接通过
|
||||
if (Math.abs(distance) > judgeValue / 3) gapTime = 100
|
||||
//3、若不在上面那个情况,那么只需要判断时间即可
|
||||
//3、若不在上述两种情况,那么只需要判断时间即可
|
||||
if (gapTime < 150) {
|
||||
if (isNext) {
|
||||
state.localIndex++
|
||||
@ -184,9 +217,11 @@ export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNext
|
||||
* @param state
|
||||
* @param emit
|
||||
*/
|
||||
export function slideReset(el, state, emit = null) {
|
||||
export function slideReset(e, el, state, emit = null) {
|
||||
if (!checkEvent(e)) return
|
||||
|
||||
Utils.$setCss(el, 'transition-duration', `300ms`)
|
||||
let t = getSlideOffset(state, el)
|
||||
const t = getSlideOffset(state, el)
|
||||
let dx1 = 0
|
||||
let dx2 = 0
|
||||
if (state.type === SlideType.HORIZONTAL) {
|
||||
@ -200,6 +235,11 @@ export function slideReset(el, state, emit = null) {
|
||||
state.start.x = state.start.y = state.start.time = state.move.x = state.move.y = 0
|
||||
state.next = false
|
||||
state.needCheck = true
|
||||
state.isDown = false
|
||||
// e.target.style.pointerEvents = null
|
||||
setTimeout(() => {
|
||||
window.isMoved = false
|
||||
}, 200)
|
||||
emit?.('update:index', state.localIndex)
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user