Merge branch 'dev'
This commit is contained in:
commit
5007e88093
@ -9,3 +9,4 @@
|
|||||||
|
|
||||||
- 双指缩放
|
- 双指缩放
|
||||||
- AutoInput组件,在真机上无法输入
|
- AutoInput组件,在真机上无法输入
|
||||||
|
- 真机上100vh显示异常的问题
|
||||||
|
|||||||
4
env.d.ts
vendored
4
env.d.ts
vendored
@ -3,6 +3,10 @@
|
|||||||
declare const LATEST_COMMIT_HASH: string
|
declare const LATEST_COMMIT_HASH: string
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
interface Window {
|
||||||
|
isMoved: boolean
|
||||||
|
}
|
||||||
|
|
||||||
interface Navigator {
|
interface Navigator {
|
||||||
control: any
|
control: any
|
||||||
webkitGetUserMedia: any
|
webkitGetUserMedia: any
|
||||||
|
|||||||
@ -137,6 +137,9 @@
|
|||||||
},
|
},
|
||||||
"interact_info": { "liked_count": "2147", "liked": false },
|
"interact_info": { "liked_count": "2147", "liked": false },
|
||||||
"cover": { "url_default": "daZ662BX0lVMTq0Y6hIwR.png" },
|
"cover": { "url_default": "daZ662BX0lVMTq0Y6hIwR.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "daZ662BX0lVMTq0Y6hIwR.png" }] }
|
||||||
|
],
|
||||||
"type": "normal",
|
"type": "normal",
|
||||||
"display_title": "无所谓了,互联网没有我在乎的人"
|
"display_title": "无所谓了,互联网没有我在乎的人"
|
||||||
},
|
},
|
||||||
@ -176,7 +179,10 @@
|
|||||||
"nickname": "芙•"
|
"nickname": "芙•"
|
||||||
},
|
},
|
||||||
"interact_info": { "liked": false, "liked_count": "1966" },
|
"interact_info": { "liked": false, "liked_count": "1966" },
|
||||||
"cover": { "url_default": "4a4TtExpq7RXnKK3hylKU.png" }
|
"cover": { "url_default": "4a4TtExpq7RXnKK3hylKU.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "4a4TtExpq7RXnKK3hylKU.png" }] }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"track_id": "2d0udv0xvhqne0t0nmd83",
|
"track_id": "2d0udv0xvhqne0t0nmd83",
|
||||||
"ignore": false,
|
"ignore": false,
|
||||||
@ -233,6 +239,9 @@
|
|||||||
},
|
},
|
||||||
"interact_info": { "liked": false, "liked_count": "1005" },
|
"interact_info": { "liked": false, "liked_count": "1005" },
|
||||||
"cover": { "url_default": "dg16eh25m2SSI9Hc1fJuE.png" },
|
"cover": { "url_default": "dg16eh25m2SSI9Hc1fJuE.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "dg16eh25m2SSI9Hc1fJuE.png" }] }
|
||||||
|
],
|
||||||
"type": "normal",
|
"type": "normal",
|
||||||
"display_title": "拍旗袍没人看 办公室随手拍就有流量是吧"
|
"display_title": "拍旗袍没人看 办公室随手拍就有流量是吧"
|
||||||
},
|
},
|
||||||
@ -321,7 +330,10 @@
|
|||||||
"nick_name": "林木婷子"
|
"nick_name": "林木婷子"
|
||||||
},
|
},
|
||||||
"interact_info": { "liked": false, "liked_count": "2700" },
|
"interact_info": { "liked": false, "liked_count": "2700" },
|
||||||
"cover": { "url_default": "z-XSh-g9MhKpYrFDHcxQT.png" }
|
"cover": { "url_default": "z-XSh-g9MhKpYrFDHcxQT.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "z-XSh-g9MhKpYrFDHcxQT.png" }] }
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"track_id": "2d0udv0xvhqne0t0nmd83"
|
"track_id": "2d0udv0xvhqne0t0nmd83"
|
||||||
},
|
},
|
||||||
@ -629,7 +641,10 @@
|
|||||||
"user_id": "5bf37f6651783a194c1e1da2"
|
"user_id": "5bf37f6651783a194c1e1da2"
|
||||||
},
|
},
|
||||||
"interact_info": { "liked": false, "liked_count": "119" },
|
"interact_info": { "liked": false, "liked_count": "119" },
|
||||||
"cover": { "url_default": "UaxqkI4aZ5LDu7k8KLw48.png" }
|
"cover": { "url_default": "UaxqkI4aZ5LDu7k8KLw48.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "UaxqkI4aZ5LDu7k8KLw48.png" }] }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -888,6 +903,7 @@
|
|||||||
},
|
},
|
||||||
"interact_info": { "liked": false, "liked_count": "1786" },
|
"interact_info": { "liked": false, "liked_count": "1786" },
|
||||||
"cover": { "url_default": "n0SAcEY5gLucU7Ik7yP2P.png" },
|
"cover": { "url_default": "n0SAcEY5gLucU7Ik7yP2P.png" },
|
||||||
|
"image_list": [{ "info_list": [{ "url": "n0SAcEY5gLucU7Ik7yP2P.png" }] }],
|
||||||
"type": "normal"
|
"type": "normal"
|
||||||
},
|
},
|
||||||
"track_id": "2d0udv0xvhqne0t0nmd83",
|
"track_id": "2d0udv0xvhqne0t0nmd83",
|
||||||
@ -936,6 +952,9 @@
|
|||||||
"model_type": "note",
|
"model_type": "note",
|
||||||
"note_card": {
|
"note_card": {
|
||||||
"cover": { "url_default": "Sf5mzf68e2GwZHZv7h1G2.png" },
|
"cover": { "url_default": "Sf5mzf68e2GwZHZv7h1G2.png" },
|
||||||
|
"image_list": [
|
||||||
|
{ "info_list": [{ "url": "Sf5mzf68e2GwZHZv7h1G2.png" }] }
|
||||||
|
],
|
||||||
"type": "normal",
|
"type": "normal",
|
||||||
"display_title": "行吧,我重发 ",
|
"display_title": "行吧,我重发 ",
|
||||||
"user": {
|
"user": {
|
||||||
|
|||||||
Binary file not shown.
39
src/App.vue
39
src/App.vue
@ -6,16 +6,17 @@
|
|||||||
</keep-alive>
|
</keep-alive>
|
||||||
</transition>
|
</transition>
|
||||||
</router-view>
|
</router-view>
|
||||||
<BaseMask v-if="!isMobile" />
|
<BaseMask v-if="!isMobile" @click="isMobile = true" />
|
||||||
<div v-if="!isMobile" class="guide">
|
<div v-if="!isMobile" class="guide">
|
||||||
<Icon icon="mynaui:danger-triangle" />
|
<Icon class="danger" icon="mynaui:danger-triangle" />
|
||||||
<div class="txt">
|
<Icon class="close" icon="simple-line-icons:close" @click="isMobile = true" />
|
||||||
<h2>切换至手机模式才可正常使用</h2>
|
<div class="txt">
|
||||||
<h3>1. 按 F12 调出控制台</h3>
|
<h2>切换至手机模式获取最佳体验</h2>
|
||||||
<h3>2. 按 Ctrl+Shift+M,或点击下面图标</h3>
|
<h3>1. 按 F12 调出控制台</h3>
|
||||||
</div>
|
<h3>2. 按 Ctrl+Shift+M,或点击下面图标</h3>
|
||||||
<img src="@/assets/img/guide.png" alt="" />
|
|
||||||
</div>
|
</div>
|
||||||
|
<img src="@/assets/img/guide.png" alt="" />
|
||||||
|
</div>
|
||||||
<Call />
|
<Call />
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -92,6 +93,15 @@ onMounted(() => {
|
|||||||
font-size: 14rem;
|
font-size: 14rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 500px) {
|
||||||
|
#app {
|
||||||
|
width: 500px !important;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.guide {
|
.guide {
|
||||||
color: white;
|
color: white;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
@ -104,12 +114,21 @@ onMounted(() => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
svg {
|
.danger {
|
||||||
margin-top: 10rem;
|
margin-top: 10rem;
|
||||||
font-size: 40rem;
|
font-size: 40rem;
|
||||||
color: red;
|
color: red;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 18rem;
|
||||||
|
color: white;
|
||||||
|
position: absolute;
|
||||||
|
right: 15rem;
|
||||||
|
top: 15rem;
|
||||||
|
}
|
||||||
|
|
||||||
.txt {
|
.txt {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 0 24rem;
|
padding: 0 24rem;
|
||||||
|
|||||||
@ -128,6 +128,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.add-ctn {
|
.add-ctn {
|
||||||
|
cursor: pointer;
|
||||||
@height: 27rem;
|
@height: 27rem;
|
||||||
@width: 36rem;
|
@width: 36rem;
|
||||||
height: @height;
|
height: @height;
|
||||||
@ -147,6 +148,8 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
|
||||||
|
|||||||
@ -87,11 +87,12 @@ function getMonth(time) {
|
|||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.posters {
|
.posters {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 33.33vw 33.33vw 33.33vw;
|
grid-template-columns: 33.33% 33.33% 33.33%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.poster-item {
|
.poster-item {
|
||||||
height: calc(33.33vw * 1.2);
|
height: 200rem;
|
||||||
|
max-height: calc(33.33vw * 1.2);
|
||||||
border: 0.5px solid black;
|
border: 0.5px solid black;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -123,6 +123,7 @@ export default {
|
|||||||
@import '../assets/less/index';
|
@import '../assets/less/index';
|
||||||
|
|
||||||
.scroll-wrapper {
|
.scroll-wrapper {
|
||||||
|
touch-action: pan-y;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|
||||||
.scroll-content {
|
.scroll-content {
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<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 ref="float" class="float" :class="state.floatFixed ? 'fixed' : ''">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Icon @click="emit('back')" class="icon" icon="eva:arrow-ios-back-fill" />
|
<Icon @click="emit('back')" class="icon" icon="eva:arrow-ios-back-fill" />
|
||||||
@ -405,6 +405,7 @@ function touchEnd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#UserPanel {
|
#UserPanel {
|
||||||
|
touch-action: pan-y;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
background: var(--color-user);
|
background: var(--color-user);
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -500,7 +501,7 @@ function touchEnd() {
|
|||||||
grid-template-columns: 33.33% 33.33% 33.33%;
|
grid-template-columns: 33.33% 33.33% 33.33%;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
height: calc(33.33vw * 1.3);
|
height: calc(33.33% * 1.3);
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -28,8 +28,9 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Dom from '../../utils/dom'
|
import Dom, { _css } from '../../utils/dom'
|
||||||
import bus, { EVENT_KEY } from '@/utils/bus'
|
import bus, { EVENT_KEY } from '@/utils/bus'
|
||||||
|
import Utils from '@/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FromBottomDialog',
|
name: 'FromBottomDialog',
|
||||||
@ -74,7 +75,7 @@ export default {
|
|||||||
modelValue(newVal) {
|
modelValue(newVal) {
|
||||||
let page = document.getElementById(this.pageId)
|
let page = document.getElementById(this.pageId)
|
||||||
if (newVal) {
|
if (newVal) {
|
||||||
this.pagePosition = this.$getCss2(page, 'position')
|
this.pagePosition = _css(page, 'position')
|
||||||
page.style.position = 'absolute'
|
page.style.position = 'absolute'
|
||||||
this.scroll = document.documentElement.scrollTop
|
this.scroll = document.documentElement.scrollTop
|
||||||
document.body.style.position = 'fixed'
|
document.body.style.position = 'fixed'
|
||||||
@ -113,28 +114,28 @@ export default {
|
|||||||
created() {},
|
created() {},
|
||||||
methods: {
|
methods: {
|
||||||
beforeEnter(el) {
|
beforeEnter(el) {
|
||||||
this.$setCss(el, 'transition-duration', `250ms`)
|
_css(el, 'transition-duration', `250ms`)
|
||||||
this.$setCss(el, 'transform', `translate3d(0,${this.height},0)`)
|
_css(el, 'transform', `translate3d(0,${this.height},0)`)
|
||||||
},
|
},
|
||||||
enter(el, done) {
|
enter(el, done) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$setCss(el, 'transform', `translate3d(0,0,0)`)
|
_css(el, 'transform', `translate3d(0,0,0)`)
|
||||||
}, 0)
|
}, 0)
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// this.$setCss(el, 'transition-duration', `0ms`)
|
// _css(el, 'transition-duration', `0ms`)
|
||||||
this.$setCss(el, 'transform', `none`)
|
_css(el, 'transform', `none`)
|
||||||
done()
|
done()
|
||||||
}, 250)
|
}, 250)
|
||||||
},
|
},
|
||||||
afterEnter() {},
|
afterEnter() {},
|
||||||
beforeLeave(el) {
|
beforeLeave(el) {
|
||||||
this.$setCss(el, 'transition-duration', `250ms`)
|
_css(el, 'transition-duration', `250ms`)
|
||||||
this.$setCss(el, 'transform', `translate3d(0,0,0)`)
|
_css(el, 'transform', `translate3d(0,0,0)`)
|
||||||
},
|
},
|
||||||
leave(el, done) {
|
leave(el, done) {
|
||||||
//ref获取不到
|
//ref获取不到
|
||||||
let maxHeight = new Dom('.FromBottomDialog').css('max-height')
|
let maxHeight = new Dom('.FromBottomDialog').css('max-height')
|
||||||
this.$setCss(el, 'transform', `translate3d(0,${maxHeight},0)`)
|
_css(el, 'transform', `translate3d(0,${maxHeight},0)`)
|
||||||
setTimeout(done, 250)
|
setTimeout(done, 250)
|
||||||
},
|
},
|
||||||
afterLeave() {},
|
afterLeave() {},
|
||||||
@ -147,7 +148,7 @@ export default {
|
|||||||
if (this.$refs.dialog.scrollTop !== 0) return
|
if (this.$refs.dialog.scrollTop !== 0) return
|
||||||
this.startLocationY = e.touches[0].pageY
|
this.startLocationY = e.touches[0].pageY
|
||||||
this.startTime = Date.now()
|
this.startTime = Date.now()
|
||||||
this.$setCss(this.$refs.dialog, 'transition-duration', `0ms`)
|
_css(this.$refs.dialog, 'transition-duration', `0ms`)
|
||||||
},
|
},
|
||||||
move(e) {
|
move(e) {
|
||||||
if (this.$refs.dialog.scrollTop !== 0) return
|
if (this.$refs.dialog.scrollTop !== 0) return
|
||||||
@ -157,7 +158,7 @@ export default {
|
|||||||
tag: this.tag,
|
tag: this.tag,
|
||||||
e: this.moveYDistance
|
e: this.moveYDistance
|
||||||
})
|
})
|
||||||
this.$setCss(this.$refs.dialog, 'transform', `translate3d(0,${this.moveYDistance}px,0)`)
|
_css(this.$refs.dialog, 'transform', `translate3d(0,${this.moveYDistance}px,0)`)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
end() {
|
end() {
|
||||||
@ -168,17 +169,17 @@ export default {
|
|||||||
//滑动
|
//滑动
|
||||||
if (this.$refs.dialog.scrollTop !== 0) return
|
if (this.$refs.dialog.scrollTop !== 0) return
|
||||||
let clientHeight = this.$refs.dialog.clientHeight
|
let clientHeight = this.$refs.dialog.clientHeight
|
||||||
this.$setCss(this.$refs.dialog, 'transition-duration', `250ms`)
|
_css(this.$refs.dialog, 'transition-duration', `250ms`)
|
||||||
if (Math.abs(this.moveYDistance) > clientHeight / 2) {
|
if (Math.abs(this.moveYDistance) > clientHeight / 2) {
|
||||||
this.$setCss(this.$refs.dialog, 'transform', `translate3d(0,${clientHeight}px,0)`)
|
_css(this.$refs.dialog, 'transform', `translate3d(0,${clientHeight}px,0)`)
|
||||||
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: true })
|
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: true })
|
||||||
setTimeout(this.hide, 250)
|
setTimeout(this.hide, 250)
|
||||||
} else {
|
} else {
|
||||||
this.$setCss(this.$refs.dialog, 'transform', `translate3d(0,0,0)`)
|
_css(this.$refs.dialog, 'transform', `translate3d(0,0,0)`)
|
||||||
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: false })
|
bus.emit(EVENT_KEY.DIALOG_END, { tag: this.tag, isClose: false })
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$setCss(this.$refs.dialog, 'transform', 'none')
|
_css(this.$refs.dialog, 'transform', 'none')
|
||||||
// this.$setCss(this.$refs.dialog, 'transition-duration', `0ms`)
|
// _css(this.$refs.dialog, 'transition-duration', `0ms`)
|
||||||
}, 250)
|
}, 250)
|
||||||
}
|
}
|
||||||
this.moveYDistance = 0
|
this.moveYDistance = 0
|
||||||
|
|||||||
@ -23,13 +23,13 @@
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<template v-if="state.operationStatus === SlideAlbumOperationStatus.Normal">
|
<template v-if="state.operationStatus === SlideAlbumOperationStatus.Normal">
|
||||||
<ItemToolbar
|
<!-- <ItemToolbar-->
|
||||||
class="mb3r"
|
<!-- class="mb3r"-->
|
||||||
v-model:item="state.localItem"
|
<!-- v-model:item="state.localItem"-->
|
||||||
:position="position"
|
<!-- :position="position"-->
|
||||||
v-bind="$attrs"
|
<!-- v-bind="$attrs"-->
|
||||||
/>
|
<!-- />-->
|
||||||
<ItemDesc class="mb3r" v-model:item="state.localItem" :position="position" />
|
<!-- <ItemDesc class="mb3r" v-model:item="state.localItem" :position="position" />-->
|
||||||
</template>
|
</template>
|
||||||
<!--不知为啥touch事件,在下部20px的空间内不触发,加上click事件不好了 -->
|
<!--不知为啥touch事件,在下部20px的空间内不触发,加上click事件不好了 -->
|
||||||
<div
|
<div
|
||||||
@ -106,15 +106,12 @@ import {
|
|||||||
slideInit,
|
slideInit,
|
||||||
slideReset,
|
slideReset,
|
||||||
slideTouchEnd,
|
slideTouchEnd,
|
||||||
slidePointerMove,
|
slideTouchMove,
|
||||||
slidePointerDown
|
slideTouchStart
|
||||||
} from '@/utils/slide'
|
} from '@/utils/slide'
|
||||||
import { SlideAlbumOperationStatus, SlideItemPlayStatus, SlideType } from '../../utils/const_var'
|
import { SlideAlbumOperationStatus, SlideItemPlayStatus, SlideType } from '../../utils/const_var'
|
||||||
import ItemToolbar from './ItemToolbar'
|
|
||||||
import ItemDesc from './ItemDesc'
|
|
||||||
import { cloneDeep } from '@/utils'
|
import { cloneDeep } from '@/utils'
|
||||||
import bus, { EVENT_KEY } from '../../utils/bus'
|
import bus, { EVENT_KEY } from '../../utils/bus'
|
||||||
import $ from 'jquery'
|
|
||||||
|
|
||||||
let out = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
let out = new Float32Array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||||
let ov = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
let ov = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1])
|
||||||
@ -409,7 +406,7 @@ function touchStart(e) {
|
|||||||
// Utils.$showNoticeDialog('start'+e.touches.length)
|
// Utils.$showNoticeDialog('start'+e.touches.length)
|
||||||
console.log('start', e.touches.length)
|
console.log('start', e.touches.length)
|
||||||
if (e.touches.length === 1) {
|
if (e.touches.length === 1) {
|
||||||
slidePointerDown(e, wrapperEl.value, state)
|
slideTouchStart(e, wrapperEl.value, state)
|
||||||
} else {
|
} else {
|
||||||
if (state.operationStatus === SlideAlbumOperationStatus.Zooming) {
|
if (state.operationStatus === SlideAlbumOperationStatus.Zooming) {
|
||||||
// state.start.center = Utils.getCenter(state.start.point1, state.start.point2)
|
// state.start.center = Utils.getCenter(state.start.point1, state.start.point2)
|
||||||
@ -430,6 +427,9 @@ function touchStart(e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function touchMove(e) {
|
function touchMove(e) {
|
||||||
|
const s = true
|
||||||
|
if (s) return
|
||||||
|
|
||||||
// Utils.$showNoticeDialog('move'+e.touches.length)
|
// Utils.$showNoticeDialog('move'+e.touches.length)
|
||||||
// console.log('move', e.touches.length, state.operationStatus)
|
// console.log('move', e.touches.length, state.operationStatus)
|
||||||
let current1 = { x: e.touches[0].pageX, y: e.touches[0].pageY }
|
let current1 = { x: e.touches[0].pageX, y: e.touches[0].pageY }
|
||||||
@ -452,7 +452,7 @@ function touchMove(e) {
|
|||||||
} else {
|
} else {
|
||||||
// console.log('m2')
|
// console.log('m2')
|
||||||
state.isAutoPlay = false
|
state.isAutoPlay = false
|
||||||
slidePointerMove(
|
slideTouchMove(
|
||||||
e,
|
e,
|
||||||
wrapperEl.value,
|
wrapperEl.value,
|
||||||
state,
|
state,
|
||||||
@ -481,10 +481,11 @@ function touchMove(e) {
|
|||||||
if (rectMap.has(state.localIndex)) {
|
if (rectMap.has(state.localIndex)) {
|
||||||
rect = rectMap.get(state.localIndex)
|
rect = rectMap.get(state.localIndex)
|
||||||
} else {
|
} else {
|
||||||
|
//TODO 这里去掉jquery
|
||||||
//getBoundingClientRect在手机上获取不到值
|
//getBoundingClientRect在手机上获取不到值
|
||||||
let offset = $(state.itemRefs[state.localIndex]).offset()
|
// let offset = $(state.itemRefs[state.localIndex]).offset()
|
||||||
rect = { x: offset.left, y: offset.top }
|
// rect = { x: offset.left, y: offset.top }
|
||||||
rectMap.set(state.localIndex, rect)
|
// rectMap.set(state.localIndex, rect)
|
||||||
}
|
}
|
||||||
|
|
||||||
let current2 = { x: e.touches[1].pageX, y: e.touches[1].pageY }
|
let current2 = { x: e.touches[1].pageX, y: e.touches[1].pageY }
|
||||||
@ -579,7 +580,7 @@ function touchEnd(e) {
|
|||||||
startLoop()
|
startLoop()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
slideReset(wrapperEl.value, state)
|
slideReset(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import GM from '../../utils'
|
|||||||
import {
|
import {
|
||||||
getSlideOffset,
|
getSlideOffset,
|
||||||
slideInit,
|
slideInit,
|
||||||
slidePointerDown,
|
slideTouchStart,
|
||||||
slidePointerMove,
|
slideTouchMove,
|
||||||
slideReset,
|
slideReset,
|
||||||
slideTouchEnd
|
slideTouchEnd
|
||||||
} from '@/utils/slide'
|
} from '@/utils/slide'
|
||||||
@ -39,16 +39,20 @@ const props = defineProps({
|
|||||||
const emit = defineEmits(['update:index'])
|
const emit = defineEmits(['update:index'])
|
||||||
|
|
||||||
let ob = null
|
let ob = null
|
||||||
|
//slide-list的ref引用
|
||||||
const wrapperEl = ref(null)
|
const wrapperEl = ref(null)
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
judgeValue: 20,
|
judgeValue: 20, //一个用于判断滑动朝向的固定值
|
||||||
type: SlideType.HORIZONTAL,
|
type: SlideType.HORIZONTAL, //组件类型
|
||||||
name: props.name,
|
name: props.name,
|
||||||
localIndex: props.index,
|
localIndex: props.index, //当前下标
|
||||||
needCheck: true,
|
needCheck: true, //是否需要检测,每次按下都需要检测,up事件会重置为true
|
||||||
next: false,
|
next: false, //能否滑动
|
||||||
start: { x: 0, y: 0, time: 0 },
|
isDown: false, //是否按下,用于move事件判断
|
||||||
move: { x: 0, y: 0 },
|
start: { x: 0, y: 0, time: 0 }, //按下时的起点坐标
|
||||||
|
move: { x: 0, y: 0 }, //移动时的坐标
|
||||||
|
//slide-list的宽度和子元素数量
|
||||||
wrapper: {
|
wrapper: {
|
||||||
width: 0,
|
width: 0,
|
||||||
height: 0,
|
height: 0,
|
||||||
@ -99,17 +103,17 @@ onUnmounted(() => {
|
|||||||
ob.disconnect()
|
ob.disconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
function touchStart(e: TouchEvent) {
|
function touchStart(e) {
|
||||||
slidePointerDown(e, wrapperEl.value, state)
|
slideTouchStart(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchMove(e: TouchEvent) {
|
function touchMove(e) {
|
||||||
slidePointerMove(e, wrapperEl.value, state)
|
slideTouchMove(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchEnd(e: TouchEvent) {
|
function touchEnd(e) {
|
||||||
slideTouchEnd(e, state)
|
slideTouchEnd(e, state)
|
||||||
slideReset(wrapperEl.value, state, emit)
|
slideReset(e, wrapperEl.value, state, emit)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -127,9 +131,9 @@ function touchEnd(e: TouchEvent) {
|
|||||||
<div
|
<div
|
||||||
class="slide-list"
|
class="slide-list"
|
||||||
ref="wrapperEl"
|
ref="wrapperEl"
|
||||||
@touchstart="touchStart"
|
@pointerdown="touchStart"
|
||||||
@touchmove="touchMove"
|
@pointermove="touchMove"
|
||||||
@touchend="touchEnd"
|
@pointerup="touchEnd"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
@ -141,16 +145,16 @@ function touchEnd(e: TouchEvent) {
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 10rem;
|
bottom: 10rem;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
left: 0;
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
gap: 7rem;
|
||||||
|
|
||||||
.bullet {
|
.bullet {
|
||||||
@width: 5rem;
|
@width: 5rem;
|
||||||
width: @width;
|
width: @width;
|
||||||
height: @width;
|
height: @width;
|
||||||
margin: 0 3rem;
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--second-btn-color);
|
background: var(--second-btn-color);
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,8 @@ import {
|
|||||||
slideInit,
|
slideInit,
|
||||||
slideReset,
|
slideReset,
|
||||||
slideTouchEnd,
|
slideTouchEnd,
|
||||||
slidePointerMove,
|
slideTouchMove,
|
||||||
slidePointerDown
|
slideTouchStart
|
||||||
} from '@/utils/slide'
|
} from '@/utils/slide'
|
||||||
import { SlideType } from '@/utils/const_var'
|
import { SlideType } from '@/utils/const_var'
|
||||||
|
|
||||||
@ -22,21 +22,34 @@ const props = defineProps({
|
|||||||
changeActiveIndexUseAnim: {
|
changeActiveIndexUseAnim: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: String,
|
||||||
|
default: () => 'SlideVertical'
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update:index'])
|
const emit = defineEmits(['update:index'])
|
||||||
|
|
||||||
|
//slide-list的ref引用
|
||||||
const wrapperEl = ref(null)
|
const wrapperEl = ref(null)
|
||||||
|
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
judgeValue: 20,
|
judgeValue: 20, //一个用于判断滑动朝向的固定值
|
||||||
type: SlideType.HORIZONTAL,
|
type: SlideType.VERTICAL, //组件类型
|
||||||
name: 'SlideVertical',
|
name: props.name,
|
||||||
localIndex: props.index,
|
localIndex: props.index, //当前下标
|
||||||
needCheck: true,
|
needCheck: true, //是否需要检测,每次按下都需要检测,up事件会重置为true
|
||||||
next: false,
|
next: false, //能否滑动
|
||||||
start: { x: 0, y: 0, time: 0 },
|
isDown: false, //是否按下,用于move事件判断
|
||||||
move: { x: 0, y: 0 },
|
start: { x: 0, y: 0, time: 0 }, //按下时的起点坐标
|
||||||
wrapper: { width: 0, height: 0, childrenLength: 0 }
|
move: { x: 0, y: 0 }, //移动时的坐标
|
||||||
|
//slide-list的宽度和子元素数量
|
||||||
|
wrapper: {
|
||||||
|
width: 0,
|
||||||
|
height: 0,
|
||||||
|
//childrenLength用于canNext方法判断当前页是否是最后一页,是则不能滑动,不捕获事件
|
||||||
|
childrenLength: 0
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
@ -61,16 +74,16 @@ onMounted(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
function touchStart(e) {
|
function touchStart(e) {
|
||||||
slidePointerDown(e, wrapperEl.value, state)
|
slideTouchStart(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchMove(e) {
|
function touchMove(e) {
|
||||||
slidePointerMove(e, wrapperEl.value, state)
|
slideTouchMove(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchEnd(e) {
|
function touchEnd(e) {
|
||||||
slideTouchEnd(e, state)
|
slideTouchEnd(e, state)
|
||||||
slideReset(wrapperEl.value, state, emit)
|
slideReset(e, wrapperEl.value, state, emit)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@ -79,9 +92,9 @@ function touchEnd(e) {
|
|||||||
<div
|
<div
|
||||||
class="slide-list flex-direction-column"
|
class="slide-list flex-direction-column"
|
||||||
ref="wrapperEl"
|
ref="wrapperEl"
|
||||||
@touchstart="touchStart"
|
@pointerdown="touchStart"
|
||||||
@touchmove="touchMove"
|
@pointermove="touchMove"
|
||||||
@touchend="touchEnd"
|
@pointerup="touchEnd"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
<script setup lang="jsx">
|
<script setup lang="tsx">
|
||||||
import { createApp, onMounted, reactive, ref, render as vueRender, watch } from 'vue'
|
import { createApp, onMounted, reactive, ref, render as vueRender, watch } from 'vue'
|
||||||
import GM from '../../utils'
|
import GM from '../../utils'
|
||||||
import {
|
import {
|
||||||
@ -6,15 +6,15 @@ import {
|
|||||||
slideInit,
|
slideInit,
|
||||||
slideReset,
|
slideReset,
|
||||||
slideTouchEnd,
|
slideTouchEnd,
|
||||||
slidePointerMove,
|
slideTouchMove,
|
||||||
slidePointerDown
|
slideTouchStart
|
||||||
} from '@/utils/slide'
|
} from '@/utils/slide'
|
||||||
import { SlideType } from '@/utils/const_var'
|
import { SlideType } from '@/utils/const_var'
|
||||||
import SlideItem from '@/components/slide/SlideItem.vue'
|
import SlideItem from '@/components/slide/SlideItem.vue'
|
||||||
import bus, { EVENT_KEY } from '../../utils/bus'
|
import bus, { EVENT_KEY } from '../../utils/bus'
|
||||||
import Loading from '@/components/Loading.vue'
|
import Loading from '@/components/Loading.vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import $ from 'jquery'
|
import { _css } from '@/utils/dom'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
index: {
|
index: {
|
||||||
@ -60,14 +60,15 @@ const emit = defineEmits(['update:index', 'loadMore', 'refresh'])
|
|||||||
|
|
||||||
const appInsMap = new Map()
|
const appInsMap = new Map()
|
||||||
const itemClassName = 'slide-item'
|
const itemClassName = 'slide-item'
|
||||||
const wrapperEl = ref(null)
|
const wrapperEl = ref<HTMLDivElement>(null)
|
||||||
const state = reactive({
|
const state = reactive({
|
||||||
judgeValue: 20,
|
judgeValue: 20,
|
||||||
type: SlideType.VERTICAL,
|
type: SlideType.VERTICAL_INFINITE,
|
||||||
name: props.name,
|
name: props.name,
|
||||||
localIndex: props.index,
|
localIndex: props.index,
|
||||||
needCheck: true,
|
needCheck: true,
|
||||||
next: false,
|
next: false,
|
||||||
|
isDown: false,
|
||||||
start: { x: 0, y: 0, time: 0 },
|
start: { x: 0, y: 0, time: 0 },
|
||||||
move: { x: 0, y: 0 },
|
move: { x: 0, y: 0 },
|
||||||
wrapper: { width: 0, height: 0, childrenLength: 0 }
|
wrapper: { width: 0, height: 0, childrenLength: 0 }
|
||||||
@ -85,17 +86,17 @@ watch(
|
|||||||
if (oldVal.length === 0) {
|
if (oldVal.length === 0) {
|
||||||
insertContent()
|
insertContent()
|
||||||
} else {
|
} else {
|
||||||
let lastSlideItem = $(wrapperEl.value).find(`.${itemClassName}:last`)
|
let lastSlideItem = wrapperEl.value.querySelector(`.${itemClassName}:last-child`)
|
||||||
let top = lastSlideItem.css('top')
|
let top = _css(lastSlideItem, 'top')
|
||||||
let lastIndex = Number(lastSlideItem.attr('data-index')) + 1
|
let lastIndex = Number(lastSlideItem.getAttribute('data-index')) + 1
|
||||||
console.log('lastIndex', lastIndex)
|
// console.log('lastIndex', lastIndex)
|
||||||
newVal.slice(lastIndex, lastIndex + 3).map((item, index) => {
|
newVal.slice(lastIndex, lastIndex + 3).map((item, index) => {
|
||||||
let el = getInsEl(item, lastIndex + index)
|
let el = getInsEl(item, lastIndex + index)
|
||||||
//这里必须要设置个top值,不然会把前面的条目给覆盖掉
|
//这里必须要设置个top值,不然会把前面的条目给覆盖掉
|
||||||
//2022-3-27,这里不用计算,直接用已用slide-item最后一条的top值,
|
//2022-3-27,这里不用计算,直接用已用slide-item最后一条的top值,
|
||||||
//因为有一条情况:当滑动最后一条和二条的时候top值不会继续加。此时新增的数据如果还
|
//因为有一条情况:当滑动最后一条和二条的时候top值不会继续加。此时新增的数据如果还
|
||||||
// 计算top值的,会和前面的对不上
|
// 计算top值的,会和前面的对不上
|
||||||
$(el).css('top', top)
|
_css(el, 'top', top)
|
||||||
wrapperEl.value.appendChild(el)
|
wrapperEl.value.appendChild(el)
|
||||||
state.wrapper.childrenLength++
|
state.wrapper.childrenLength++
|
||||||
})
|
})
|
||||||
@ -146,13 +147,13 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
slideInit(wrapperEl.value, state, SlideType.VERTICAL)
|
slideInit(wrapperEl.value, state)
|
||||||
insertContent()
|
insertContent()
|
||||||
})
|
})
|
||||||
|
|
||||||
function insertContent(list = props.list) {
|
function insertContent(list = props.list) {
|
||||||
if (!list.length) return
|
if (!list.length) return
|
||||||
$(wrapperEl.value).empty()
|
wrapperEl.value.innerHTML = ''
|
||||||
let half = (props.virtualTotal - 1) / 2
|
let half = (props.virtualTotal - 1) / 2
|
||||||
let start = 0
|
let start = 0
|
||||||
if (state.localIndex >= half) {
|
if (state.localIndex >= half) {
|
||||||
@ -170,18 +171,21 @@ function insertContent(list = props.list) {
|
|||||||
let el = getInsEl(item, start + index, start + index === state.localIndex)
|
let el = getInsEl(item, start + index, start + index === state.localIndex)
|
||||||
wrapperEl.value.appendChild(el)
|
wrapperEl.value.appendChild(el)
|
||||||
})
|
})
|
||||||
GM.$setCss(wrapperEl.value, 'transform', `translate3d(0px,${getSlideOffset(state)}px, 0px)`)
|
GM.$setCss(
|
||||||
|
wrapperEl.value,
|
||||||
|
'transform',
|
||||||
|
`translate3d(0px,${getSlideOffset(state, wrapperEl.value)}px, 0px)`
|
||||||
|
)
|
||||||
|
|
||||||
if (state.localIndex > 2 && list.length > 5) {
|
if (state.localIndex > 2 && list.length > 5) {
|
||||||
$(wrapperEl.value)
|
let list = wrapperEl.value.querySelectorAll(`.${itemClassName}`)
|
||||||
.find(`.${itemClassName}`)
|
list.forEach((item) => {
|
||||||
.each(function () {
|
if (list.length - state.localIndex > 2) {
|
||||||
if (list.length - state.localIndex > 2) {
|
_css(item, 'top', (state.localIndex - 2) * state.wrapper.height)
|
||||||
$(this).css('top', (state.localIndex - 2) * state.wrapper.height)
|
} else {
|
||||||
} else {
|
_css(item, 'top', start * state.wrapper.height)
|
||||||
$(this).css('top', start * state.wrapper.height)
|
}
|
||||||
}
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
state.wrapper.childrenLength = wrapperEl.value.children.length
|
state.wrapper.childrenLength = wrapperEl.value.children.length
|
||||||
// console.log('list[state.localIndex]',list[state.localIndex])
|
// console.log('list[state.localIndex]',list[state.localIndex])
|
||||||
@ -189,10 +193,10 @@ function insertContent(list = props.list) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function dislike(item) {
|
function dislike(item) {
|
||||||
let currentItem = $(wrapperEl.value).find(`.${itemClassName}[data-index=${state.localIndex}]`)
|
// let currentItem = $(wrapperEl.value).find(`.${itemClassName}[data-index=${state.localIndex}]`)
|
||||||
let replaceItem = getInsEl(item, state.localIndex, true)
|
// let replaceItem = getInsEl(item, state.localIndex, true)
|
||||||
$(replaceItem).css('top', currentItem.css('top'))
|
// $(replaceItem).css('top', currentItem.css('top'))
|
||||||
currentItem.replaceWith(replaceItem)
|
// currentItem.replaceWith(replaceItem)
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({ dislike })
|
defineExpose({ dislike })
|
||||||
@ -226,12 +230,12 @@ function getInsEl(item, index, play = false) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function touchStart(e) {
|
function touchStart(e) {
|
||||||
slidePointerDown(e, wrapperEl.value, state)
|
slideTouchStart(e, wrapperEl.value, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO 2022-3-28:在最顶部,反复滑动会抖动一下,初步猜测是因为方向变了,导致的加判断距离变成了减
|
//TODO 2022-3-28:在最顶部,反复滑动会抖动一下,初步猜测是因为方向变了,导致的加判断距离变成了减
|
||||||
function touchMove(e) {
|
function touchMove(e) {
|
||||||
slidePointerMove(e, wrapperEl.value, state, canNext)
|
slideTouchMove(e, wrapperEl.value, state, canNext)
|
||||||
}
|
}
|
||||||
|
|
||||||
function touchEnd(e) {
|
function touchEnd(e) {
|
||||||
@ -251,9 +255,9 @@ function touchEnd(e) {
|
|||||||
emit('loadMore')
|
emit('loadMore')
|
||||||
}
|
}
|
||||||
let addItemIndex = state.localIndex + 2
|
let addItemIndex = state.localIndex + 2
|
||||||
let res = $(wrapperEl.value).find(`.${itemClassName}[data-index=${addItemIndex}]`)
|
let res = wrapperEl.value.querySelector(`.${itemClassName}[data-index='${addItemIndex}']`)
|
||||||
if (state.wrapper.childrenLength < props.virtualTotal) {
|
if (state.wrapper.childrenLength < props.virtualTotal) {
|
||||||
if (res.length === 0) {
|
if (!res) {
|
||||||
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
|
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -262,55 +266,56 @@ function touchEnd(e) {
|
|||||||
state.localIndex >= (props.virtualTotal + 1) / 2 &&
|
state.localIndex >= (props.virtualTotal + 1) / 2 &&
|
||||||
state.localIndex <= props.list.length - 3
|
state.localIndex <= props.list.length - 3
|
||||||
) {
|
) {
|
||||||
if (res.length === 0) {
|
if (!res) {
|
||||||
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
|
wrapperEl.value.appendChild(getInsEl(props.list[addItemIndex], addItemIndex))
|
||||||
appInsMap
|
let index = wrapperEl.value
|
||||||
.get($(wrapperEl.value).find(`.${itemClassName}:first`).data('index'))
|
.querySelector(`.${itemClassName}:first-child`)
|
||||||
.unmount()
|
.getAttribute('data-index')
|
||||||
// $(wrapperEl.value).find(".base-slide-item:first").remove()
|
appInsMap.get(Number(index)).unmount()
|
||||||
$(wrapperEl.value)
|
wrapperEl.value.querySelectorAll(`.${itemClassName}`).forEach((item) => {
|
||||||
.find(`.${itemClassName}`)
|
_css(item, 'top', (state.localIndex - 2) * state.wrapper.height)
|
||||||
.each(function () {
|
})
|
||||||
$(this).css('top', (state.localIndex - 2) * state.wrapper.height)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state.wrapper.childrenLength > props.virtualTotal) {
|
if (state.wrapper.childrenLength > props.virtualTotal) {
|
||||||
$(wrapperEl.value)
|
wrapperEl.value.querySelectorAll(`.${itemClassName}`).forEach((item) => {
|
||||||
.find(`.${itemClassName}`)
|
let index = Number(item.getAttribute('data-index'))
|
||||||
.each(function () {
|
if (index < state.localIndex - 2) {
|
||||||
let index = $(this).data('index')
|
console.log(2, appInsMap.get(Number(index)))
|
||||||
if (index < state.localIndex - 2) {
|
appInsMap.get(index).unmount()
|
||||||
appInsMap.get(index).unmount()
|
}
|
||||||
}
|
_css(item, 'top', (state.localIndex - 2) * state.wrapper.height)
|
||||||
$(this).css('top', (state.localIndex - 2) * state.wrapper.height)
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let addItemIndex = state.localIndex - 2
|
let addItemIndex = state.localIndex - 2
|
||||||
let res = $(wrapperEl.value).find(`.${itemClassName}[data-index=${addItemIndex}]`)
|
let res = wrapperEl.value.querySelector(`.${itemClassName}[data-index='${addItemIndex}']`)
|
||||||
|
|
||||||
if (state.localIndex > 1 && state.localIndex <= props.list.length - 4) {
|
if (state.localIndex > 1 && state.localIndex <= props.list.length - 4) {
|
||||||
if (res.length === 0) {
|
if (!res) {
|
||||||
wrapperEl.value.prepend(getInsEl(props.list[addItemIndex], addItemIndex))
|
wrapperEl.value.prepend(getInsEl(props.list[addItemIndex], addItemIndex))
|
||||||
appInsMap.get($(wrapperEl.value).find(`.${itemClassName}:last`).data('index')).unmount()
|
let index = wrapperEl.value
|
||||||
|
.querySelector(`.${itemClassName}:last-child`)
|
||||||
|
.getAttribute('data-index')
|
||||||
|
appInsMap.get(Number(index)).unmount()
|
||||||
// $(wrapperEl.value).find(".base-slide-item:last").remove()
|
// $(wrapperEl.value).find(".base-slide-item:last").remove()
|
||||||
$(wrapperEl.value)
|
wrapperEl.value.querySelectorAll(`.${itemClassName}`).forEach((item) => {
|
||||||
.find(`.${itemClassName}`)
|
_css(item, 'top', (state.localIndex - 2) * state.wrapper.height)
|
||||||
.each(function () {
|
})
|
||||||
$(this).css('top', (state.localIndex - 2) * state.wrapper.height)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.wrapper.childrenLength > props.virtualTotal) {
|
if (state.wrapper.childrenLength > props.virtualTotal) {
|
||||||
appInsMap.get($(wrapperEl.value).find(`.${itemClassName}:last`).data('index')).unmount()
|
let index = wrapperEl.value
|
||||||
|
.querySelector(`.${itemClassName}:last-child`)
|
||||||
|
.getAttribute('data-index')
|
||||||
|
appInsMap.get(Number(index)).unmount()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
state.wrapper.childrenLength = wrapperEl.value.children.length
|
state.wrapper.childrenLength = wrapperEl.value.children.length
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
slideReset(wrapperEl.value, state, emit)
|
slideReset(e, wrapperEl.value, state, emit)
|
||||||
}
|
}
|
||||||
|
|
||||||
function canNext(state, isNext) {
|
function canNext(state, isNext) {
|
||||||
@ -328,9 +333,9 @@ function canNext(state, isNext) {
|
|||||||
class="slide-list flex-direction-column"
|
class="slide-list flex-direction-column"
|
||||||
ref="wrapperEl"
|
ref="wrapperEl"
|
||||||
@click="null"
|
@click="null"
|
||||||
@touchstart="touchStart"
|
@pointerdown="touchStart"
|
||||||
@touchmove="touchMove"
|
@pointermove="touchMove"
|
||||||
@touchend="touchEnd"
|
@pointerup="touchEnd"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
23
src/main.ts
23
src/main.ts
@ -8,6 +8,29 @@ import mixin from './utils/mixin'
|
|||||||
import VueLazyload from '@jambonn/vue-lazyload'
|
import VueLazyload from '@jambonn/vue-lazyload'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
|
||||||
|
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 pinia = createPinia()
|
||||||
const emitter = mitt()
|
const emitter = mitt()
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|||||||
@ -28,23 +28,71 @@ const t = [
|
|||||||
type: 'imgs',
|
type: 'imgs',
|
||||||
src: `https://imgapi.cn/bing.php`,
|
src: `https://imgapi.cn/bing.php`,
|
||||||
author: {
|
author: {
|
||||||
unique_id: 1
|
unique_id: 1,
|
||||||
}
|
avatar_168x168: {
|
||||||
},
|
url_list: []
|
||||||
{
|
},
|
||||||
type: 'user',
|
avatar_300x300: {
|
||||||
src: `https://imgapi.cn/bing.php`,
|
url_list: []
|
||||||
author: {
|
},
|
||||||
unique_id: 2
|
cover_url: [
|
||||||
}
|
{
|
||||||
},
|
url_list: []
|
||||||
{
|
}
|
||||||
type: 'img',
|
],
|
||||||
src: `https://imgapi.cn/bing.php`,
|
white_cover_url: [
|
||||||
author: {
|
{
|
||||||
unique_id: 3
|
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)
|
||||||
|
|||||||
@ -346,6 +346,7 @@ function dislike() {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.sidebar {
|
.sidebar {
|
||||||
|
touch-action: pan-y;
|
||||||
width: 80vw;
|
width: 80vw;
|
||||||
height: calc(var(--vh, 1vh) * 100);
|
height: calc(var(--vh, 1vh) * 100);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -449,7 +450,7 @@ function dislike() {
|
|||||||
.first-horizontal-item {
|
.first-horizontal-item {
|
||||||
//width: 90vw;
|
//width: 90vw;
|
||||||
//height: 80vh;
|
//height: 80vh;
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: calc(var(--vh, 1vh) * 100 - var(--footer-height)) !important;
|
height: calc(var(--vh, 1vh) * 100 - var(--footer-height)) !important;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: 10rem;
|
border-radius: 10rem;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="Community">
|
<div id="Community" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedPost">
|
<ScrollList class="Scroll" v-if="state.show" :api="recommendedPost">
|
||||||
<template v-slot="{ list }">
|
<template v-slot="{ list }">
|
||||||
<div class="search" @click="nav('/home/search')">
|
<div class="search" @click="nav('/home/search')">
|
||||||
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
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 { recommendedPost } from '@/api/user'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
@ -56,9 +56,7 @@ import ScrollList from '@/components/ScrollList.vue'
|
|||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import AlbumDetail from '@/pages/other/AlbumDetail.vue'
|
import AlbumDetail from '@/pages/other/AlbumDetail.vue'
|
||||||
import Mock from 'mockjs'
|
import Mock from 'mockjs'
|
||||||
import $ from 'jquery'
|
import { _css } from '@/utils/dom'
|
||||||
|
|
||||||
//@click="nav('album-detail',{},item)"
|
|
||||||
|
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const baseStore = useBaseStore()
|
const baseStore = useBaseStore()
|
||||||
@ -98,32 +96,32 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
function close() {
|
function close() {
|
||||||
let s = $('.shadow ')
|
let s = document.querySelector('.shadow ')
|
||||||
let domRect = rect.value
|
let domRect = rect.value
|
||||||
let t = '.3'
|
let t = '.3'
|
||||||
s.css('transition', `all ${t}s`)
|
_css(s, 'transition', `all ${t}s`)
|
||||||
s.css('top', domRect.top)
|
_css(s, 'top', domRect.top)
|
||||||
s.css('left', domRect.left)
|
_css(s, 'left', domRect.left)
|
||||||
s.css('width', domRect.width)
|
_css(s, 'width', domRect.width)
|
||||||
s.css('height', domRect.height)
|
_css(s, 'height', domRect.height)
|
||||||
|
|
||||||
let a = $('.goods-detail')
|
let a = document.querySelector('.goods-detail')
|
||||||
a.css('transition', `all ${t}s`)
|
_css(a, 'transition', `all ${t}s`)
|
||||||
a.css('opacity', '0')
|
_css(a, 'opacity', '0')
|
||||||
a.css('width', '100vw')
|
_css(a, 'width', '100vw')
|
||||||
a.css('height', '100vh')
|
_css(a, 'height', '100vh')
|
||||||
a.css('transform', `scale(${domRect.sw},${domRect.sh})`)
|
_css(a, 'transform', `scale(${domRect.sw},${domRect.sh})`)
|
||||||
a.css('transform-origin', `0 0`)
|
_css(a, 'transform-origin', `0 0`)
|
||||||
|
|
||||||
let d = $('.shadow .wrap')
|
let d = document.querySelector('.shadow .wrap')
|
||||||
d.css('transition', `all ${t}s`)
|
_css(d, 'transition', `all ${t}s`)
|
||||||
d.css('opacity', '1')
|
_css(d, 'opacity', '1')
|
||||||
|
|
||||||
// state.d = false
|
// state.d = false
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
s.css('z-index', '-100')
|
_css(s, 'z-index', '-100')
|
||||||
s.css('transition', 'all 0s')
|
_css(s, 'transition', 'all 0s')
|
||||||
s.css('top', '-200vh')
|
_css(s, 'top', '-200vh')
|
||||||
}, 300)
|
}, 300)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,52 +142,54 @@ function showDetail(e, item) {
|
|||||||
// console.log(state.current)
|
// console.log(state.current)
|
||||||
|
|
||||||
state.d = true
|
state.d = true
|
||||||
let domRect = e.currentTarget.getBoundingClientRect()
|
|
||||||
// console.log('e', domRect)
|
|
||||||
let s = $('.shadow ')
|
|
||||||
|
|
||||||
s.css('z-index', '1')
|
let domRect = e.currentTarget.getBoundingClientRect()
|
||||||
s.css('transition', '0s')
|
// // console.log('e', domRect)
|
||||||
s.css('top', domRect.top)
|
|
||||||
s.css('left', domRect.left)
|
let s = document.querySelector('.shadow')
|
||||||
s.css('width', domRect.width)
|
|
||||||
s.css('height', domRect.height)
|
_css(s, 'z-index', '1')
|
||||||
|
_css(s, 'transition', '0s')
|
||||||
|
_css(s, 'top', domRect.top)
|
||||||
|
_css(s, 'left', domRect.left)
|
||||||
|
_css(s, 'width', domRect.width)
|
||||||
|
_css(s, 'height', domRect.height)
|
||||||
|
|
||||||
let t = '.3'
|
let t = '.3'
|
||||||
let d = $('.shadow .wrap')
|
let d = document.querySelector('.shadow .wrap')
|
||||||
d.empty()
|
d.innerHTML = ''
|
||||||
d.show()
|
d.append(e.currentTarget.cloneNode(true))
|
||||||
d.append($(e.currentTarget).clone())
|
_css(d, 'display', 'block')
|
||||||
d.css('transition', `all ${t}s`)
|
_css(d, 'transition', `all ${t}s`)
|
||||||
d.css('opacity', '1')
|
_css(d, 'opacity', '1')
|
||||||
|
|
||||||
let sw = domRect.width / baseStore.bodyWidth
|
let sw = domRect.width / baseStore.bodyWidth
|
||||||
let sh = domRect.height / baseStore.bodyHeight
|
let sh = domRect.height / baseStore.bodyHeight
|
||||||
domRect.sw = sw
|
domRect.sw = sw
|
||||||
domRect.sh = sh
|
domRect.sh = sh
|
||||||
|
|
||||||
let a = $('.goods-detail')
|
let a = document.querySelector('.goods-detail')
|
||||||
a.css('opacity', '0')
|
_css(a, 'opacity', '0')
|
||||||
a.css('width', '100vw')
|
_css(a, 'width', '100vw')
|
||||||
a.css('height', '100vh')
|
_css(a, 'height', '100vh')
|
||||||
a.css('transform', `scale(${domRect.sw},${domRect.sh})`)
|
_css(a, 'transform', `scale(${domRect.sw},${domRect.sh})`)
|
||||||
a.css('transform-origin', `0 0`)
|
_css(a, 'transform-origin', `0 0`)
|
||||||
|
|
||||||
rect.value = domRect
|
rect.value = domRect
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
s.css('transition', `all ${t}s`)
|
_css(s, 'transition', `all ${t}s`)
|
||||||
s.css('top', 0)
|
_css(s, 'top', 0)
|
||||||
s.css('left', 0)
|
_css(s, 'left', 0)
|
||||||
s.css('width', '100vw')
|
_css(s, 'width', '100vw')
|
||||||
s.css('height', '100vh')
|
_css(s, 'height', '100vh')
|
||||||
|
|
||||||
d.css('opacity', '0')
|
_css(d, 'opacity', '0')
|
||||||
d.css('z-index', '-1')
|
_css(d, 'z-index', '-1')
|
||||||
|
|
||||||
a.css('transition', `all ${t}s`)
|
_css(a, 'transition', `all ${t}s`)
|
||||||
a.css('opacity', '1')
|
_css(a, 'opacity', '1')
|
||||||
a.css('transform', `scale(1,1)`)
|
_css(a, 'transform', `scale(1,1)`)
|
||||||
a.css('transform-origin', `0 0`)
|
_css(a, 'transform-origin', `0 0`)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref, watch } from 'vue'
|
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 { recommendedVideo } from '@/api/videos'
|
||||||
import ScrollList from '@/components/ScrollList.vue'
|
import ScrollList from '@/components/ScrollList.vue'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
@ -78,7 +78,7 @@ const nav = useNav()
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="long-video">
|
<div class="long-video" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||||
<ScrollList class="Scroll" v-if="state.show" :api="recommendedVideo">
|
<ScrollList class="Scroll" v-if="state.show" :api="recommendedVideo">
|
||||||
<template v-slot="{ list }">
|
<template v-slot="{ list }">
|
||||||
<div class="list">
|
<div class="list">
|
||||||
|
|||||||
@ -112,7 +112,7 @@
|
|||||||
grid-template-columns: 33.33% 33.33% 33.33%;
|
grid-template-columns: 33.33% 33.33% 33.33%;
|
||||||
|
|
||||||
.item {
|
.item {
|
||||||
height: calc(33.33vw * 1.3);
|
height: calc(33.33% * 1.3);
|
||||||
padding: 2rem;
|
padding: 2rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="Me">
|
<div class="Me">
|
||||||
<SlideRowList name="baseSlide" style="width: 100vw" v-model:active-index="baseActiveIndex">
|
<SlideRowList name="baseSlide" style="width: 100%" v-model:active-index="baseActiveIndex">
|
||||||
<SlideItem>
|
<SlideItem>
|
||||||
<div ref="float" class="float" :class="floatFixed ? 'fixed' : ''">
|
<div ref="float" class="float" :class="floatFixed ? 'fixed' : ''">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@ -191,7 +191,6 @@ import { computed, inject, nextTick, onMounted, onUnmounted, reactive, ref } fro
|
|||||||
import Loading from '@/components/Loading.vue'
|
import Loading from '@/components/Loading.vue'
|
||||||
import { useBaseStore } from '@/store/pinia'
|
import { useBaseStore } from '@/store/pinia'
|
||||||
import { _checkImgUrl, _no, _sleep } from '@/utils'
|
import { _checkImgUrl, _no, _sleep } from '@/utils'
|
||||||
import $ from 'jquery'
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
|
|
||||||
@ -238,6 +237,7 @@ const mitt = inject('mitt')
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
const store = useBaseStore()
|
const store = useBaseStore()
|
||||||
|
const msgWrapper = ref<HTMLDivElement>()
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
previewImg: new URL('../../../assets/img/poster/3.jpg', import.meta.url).href,
|
previewImg: new URL('../../../assets/img/poster/3.jpg', import.meta.url).href,
|
||||||
videoCall: [],
|
videoCall: [],
|
||||||
@ -488,12 +488,16 @@ const data = reactive({
|
|||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
$('img').on('load', scrollBottom)
|
msgWrapper.value
|
||||||
|
.querySelectorAll('img')
|
||||||
|
.forEach((item) => item.addEventListener('load', scrollBottom))
|
||||||
scrollBottom()
|
scrollBottom()
|
||||||
})
|
})
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
$('img').off('load', scrollBottom)
|
msgWrapper.value
|
||||||
|
.querySelectorAll('img')
|
||||||
|
.forEach((item) => item.removeEventListener('load', scrollBottom))
|
||||||
})
|
})
|
||||||
|
|
||||||
const isExpand = computed(() => {
|
const isExpand = computed(() => {
|
||||||
@ -505,8 +509,6 @@ function handleClick() {
|
|||||||
data.showOption = false
|
data.showOption = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const msgWrapper = ref()
|
|
||||||
|
|
||||||
function scrollBottom() {
|
function scrollBottom() {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
let wrapper = msgWrapper.value
|
let wrapper = msgWrapper.value
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="goods-detail">
|
<div class="goods-detail" @dragstart="(e) => Utils.$stopPropagation(e)">
|
||||||
<header>
|
<header>
|
||||||
<Icon @click="close" icon="material-symbols-light:arrow-back-ios-new" />
|
<Icon @click="close" icon="material-symbols-light:arrow-back-ios-new" />
|
||||||
<div class="option" @click="nav('/home/search')">
|
<div class="option" @click="nav('/home/search')">
|
||||||
@ -99,7 +99,7 @@ import SlideItem from '@/components/slide/SlideItem.vue'
|
|||||||
import { reactive, ref } from 'vue'
|
import { reactive, ref } from 'vue'
|
||||||
import { useNav } from '@/utils/hooks/useNav'
|
import { useNav } from '@/utils/hooks/useNav'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { _checkImgUrl } from '@/utils'
|
import Utils, { _checkImgUrl } from '@/utils'
|
||||||
|
|
||||||
const nav = useNav()
|
const nav = useNav()
|
||||||
|
|
||||||
@ -181,7 +181,6 @@ function close() {
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
touch-action: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.indicator-bar {
|
.indicator-bar {
|
||||||
|
|||||||
@ -81,8 +81,6 @@ export default class Dom {
|
|||||||
//情况一:获取样式
|
//情况一:获取样式
|
||||||
if (typeof args[0] === 'string') {
|
if (typeof args[0] === 'string') {
|
||||||
return window.getComputedStyle(this.els[this.els.length - 1], null)[args[0]]
|
return window.getComputedStyle(this.els[this.els.length - 1], null)[args[0]]
|
||||||
// return globalMethods.$getCss2
|
|
||||||
// return this.els[0].style[args[0]]
|
|
||||||
} else {
|
} else {
|
||||||
//情况三:设置多个样式
|
//情况三:设置多个样式
|
||||||
Object.keys(args[0]).map((key) => {
|
Object.keys(args[0]).map((key) => {
|
||||||
@ -142,3 +140,48 @@ export default class Dom {
|
|||||||
return parseInt(val)
|
return parseInt(val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function _css(el, key, value?) {
|
||||||
|
const reg = /^\d+(px|pt|em|rem|vw|vh|%|rpx)$/i
|
||||||
|
if (value === undefined) {
|
||||||
|
let val = null
|
||||||
|
if ('getComputedStyle' in window) {
|
||||||
|
val = window.getComputedStyle(el, null)[key]
|
||||||
|
} else {
|
||||||
|
val = el.currentStyle[key]
|
||||||
|
}
|
||||||
|
return reg.test(val) ? parseFloat(val) : val
|
||||||
|
// return parseFloat(val)
|
||||||
|
} else {
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
'top',
|
||||||
|
'left',
|
||||||
|
'bottom',
|
||||||
|
'right',
|
||||||
|
'width',
|
||||||
|
'height',
|
||||||
|
'font-size',
|
||||||
|
'margin',
|
||||||
|
'padding'
|
||||||
|
].includes(key)
|
||||||
|
) {
|
||||||
|
if (!reg.test(value)) {
|
||||||
|
value += 'px'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// console.log(value)
|
||||||
|
if (key === 'transform') {
|
||||||
|
//直接设置不生效
|
||||||
|
el.style.webkitTransform =
|
||||||
|
el.style.MsTransform =
|
||||||
|
el.style.msTransform =
|
||||||
|
el.style.MozTransform =
|
||||||
|
el.style.OTransform =
|
||||||
|
el.style.transform =
|
||||||
|
value
|
||||||
|
} else {
|
||||||
|
el.style[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -204,26 +204,6 @@ const Utils = {
|
|||||||
// return reg.test(val) ? parseFloat(val) : val
|
// return reg.test(val) ? parseFloat(val) : val
|
||||||
return parseFloat(val)
|
return parseFloat(val)
|
||||||
},
|
},
|
||||||
$getCss2(curEle, attr) {
|
|
||||||
let val = null,
|
|
||||||
reg = null
|
|
||||||
if ('getComputedStyle' in window) {
|
|
||||||
val = window.getComputedStyle(curEle, null)[attr]
|
|
||||||
} else {
|
|
||||||
//ie6~8不支持上面属性
|
|
||||||
//不兼容
|
|
||||||
if (attr === 'opacity') {
|
|
||||||
val = curEle.currentStyle['filter'] //'alpha(opacity=12,345)'
|
|
||||||
reg = /^alphaopacity=(\d+(?:\.\d+)?)opacity=(\d+(?:\.\d+)?)$/i
|
|
||||||
val = reg.test(val) ? reg.exec(val)[1] / 100 : 1
|
|
||||||
} else {
|
|
||||||
val = curEle.currentStyle[attr]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// reg = /^(-?\d+(\.\d)?)(px|pt|em|rem)?$/i
|
|
||||||
// return reg.test(val) ? parseFloat(val) : val
|
|
||||||
return val
|
|
||||||
},
|
|
||||||
$setCss(el, key, value) {
|
$setCss(el, key, value) {
|
||||||
// console.log(value)
|
// console.log(value)
|
||||||
if (key === 'transform') {
|
if (key === 'transform') {
|
||||||
|
|||||||
@ -3,6 +3,22 @@ import Utils from '@/utils/index'
|
|||||||
import GM from '@/utils/index'
|
import GM from '@/utils/index'
|
||||||
import { SlideType } from '@/utils/const_var'
|
import { SlideType } from '@/utils/const_var'
|
||||||
import { nextTick } from 'vue'
|
import { nextTick } from 'vue'
|
||||||
|
import { _css } from '@/utils/dom'
|
||||||
|
|
||||||
|
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事件判断能否滑动
|
//初始化信息,获取slide dom的长宽、子元素数量,用于move事件判断能否滑动
|
||||||
export function slideInit(el, state) {
|
export function slideInit(el, state) {
|
||||||
@ -13,26 +29,17 @@ export function slideInit(el, state) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
//获取偏移量
|
//获取偏移量
|
||||||
let t = getSlideOffset(state, el)
|
const t = getSlideOffset(state, el)
|
||||||
let dx1 = 0,
|
let dx1 = 0,
|
||||||
dx2 = 0
|
dx2 = 0
|
||||||
if (state.type === SlideType.HORIZONTAL) dx1 = t
|
if (state.type === SlideType.HORIZONTAL) dx1 = t
|
||||||
else dx2 = t
|
else dx2 = t
|
||||||
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
_css(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()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测能否滑动
|
* 检测在对应方向上能否允许滑动,比如SlideHorizontal组件就只处理左右滑动事件,SlideVertical只处理上下滑动事件
|
||||||
* @param state
|
* * @param state
|
||||||
* @returns {boolean}
|
* @returns {boolean}
|
||||||
*/
|
*/
|
||||||
export function canSlide(state) {
|
export function canSlide(state) {
|
||||||
@ -41,7 +48,7 @@ export function canSlide(state) {
|
|||||||
//判断move x和y的距离是否大于判断值,因为距离太小无法判断滑动方向
|
//判断move x和y的距离是否大于判断值,因为距离太小无法判断滑动方向
|
||||||
if (Math.abs(state.move.x) > state.judgeValue || Math.abs(state.move.y) > state.judgeValue) {
|
if (Math.abs(state.move.x) > state.judgeValue || Math.abs(state.move.y) > state.judgeValue) {
|
||||||
//放大再相除,根据长宽比判断方向,angle大于1就是左右滑动,小于是上下滑动
|
//放大再相除,根据长宽比判断方向,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的类型,判断能否滑动,并记录下来,后续不再判断,直接返回记录值
|
//根据当前slide的类型,判断能否滑动,并记录下来,后续不再判断,直接返回记录值
|
||||||
state.next = state.type === SlideType.HORIZONTAL ? angle > 1 : angle <= 1
|
state.next = state.type === SlideType.HORIZONTAL ? angle > 1 : angle <= 1
|
||||||
// console.log('angle', angle, state.next)
|
// console.log('angle', angle, state.next)
|
||||||
@ -66,6 +73,24 @@ function canNext(state, isNext) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始滑动
|
||||||
|
* @param e
|
||||||
|
* @param el
|
||||||
|
* @param state
|
||||||
|
*/
|
||||||
|
export function slideTouchStart(e, el, state) {
|
||||||
|
// console.log('e', e, state.name)
|
||||||
|
if (!checkEvent(e)) return
|
||||||
|
_css(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事件
|
* move事件
|
||||||
* @param e
|
* @param e
|
||||||
@ -75,7 +100,7 @@ function canNext(state, isNext) {
|
|||||||
* @param notNextCb 不能继续滑的回调
|
* @param notNextCb 不能继续滑的回调
|
||||||
* @param slideOtherDirectionCb 滑动其他方向时的回调,目前用于图集进于放大模式后,上下滑动推出放大模式
|
* @param slideOtherDirectionCb 滑动其他方向时的回调,目前用于图集进于放大模式后,上下滑动推出放大模式
|
||||||
*/
|
*/
|
||||||
export function slidePointerMove(
|
export function slideTouchMove(
|
||||||
e,
|
e,
|
||||||
el,
|
el,
|
||||||
state,
|
state,
|
||||||
@ -83,16 +108,20 @@ export function slidePointerMove(
|
|||||||
notNextCb = null,
|
notNextCb = null,
|
||||||
slideOtherDirectionCb = 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.x = e.touches[0].pageX - state.start.x
|
||||||
state.move.y = e.touches[0].pageY - state.start.y
|
state.move.y = e.touches[0].pageY - state.start.y
|
||||||
// console.log('move', state.name)
|
// 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组件,在第一页往下滑动时,向外发送事件
|
//特别处理:竖直的slide组件,在第一页往下滑动时,向外发送事件
|
||||||
//用于首页顶部导航栏的刷新动画
|
//用于首页顶部导航栏的刷新动画
|
||||||
@ -107,13 +136,14 @@ export function slidePointerMove(
|
|||||||
//无限滑动组件,要特别判断,所以需要传canNextCb
|
//无限滑动组件,要特别判断,所以需要传canNextCb
|
||||||
if (!canNextCb) canNextCb = canNext
|
if (!canNextCb) canNextCb = canNext
|
||||||
if (canNextCb(state, isNext)) {
|
if (canNextCb(state, isNext)) {
|
||||||
|
window.isMoved = true
|
||||||
//能滑动,那就把事件捕获,不能给父组件处理
|
//能滑动,那就把事件捕获,不能给父组件处理
|
||||||
Utils.$stopPropagation(e)
|
Utils.$stopPropagation(e)
|
||||||
if (state.type === SlideType.HORIZONTAL) {
|
if (state.type === SlideType.HORIZONTAL) {
|
||||||
bus.emit(state.name + '-moveX', state.move.x)
|
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,
|
let dx1 = 0,
|
||||||
dx2 = 0
|
dx2 = 0
|
||||||
//偏移量加当前手指移动的距离就是slide要偏移的值
|
//偏移量加当前手指移动的距离就是slide要偏移的值
|
||||||
@ -122,8 +152,8 @@ export function slidePointerMove(
|
|||||||
} else {
|
} else {
|
||||||
dx2 = t + state.move.y
|
dx2 = t + state.move.y
|
||||||
}
|
}
|
||||||
Utils.$setCss(el, 'transition-duration', `0ms`)
|
_css(el, 'transition-duration', `0ms`)
|
||||||
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
_css(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
||||||
} else {
|
} else {
|
||||||
//SlideAlbum.vue组件在用,用于捕获事件,阻止事件传递给父slide
|
//SlideAlbum.vue组件在用,用于捕获事件,阻止事件传递给父slide
|
||||||
notNextCb?.()
|
notNextCb?.()
|
||||||
@ -143,25 +173,28 @@ export function slidePointerMove(
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNextCb = null) {
|
export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNextCb = null) {
|
||||||
let isHorizontal = state.type === SlideType.HORIZONTAL
|
if (!checkEvent(e)) return
|
||||||
let isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
if (!state.isDown) return
|
||||||
|
|
||||||
|
const isHorizontal = state.type === SlideType.HORIZONTAL
|
||||||
|
const isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
|
||||||
|
|
||||||
if (state.next) {
|
if (state.next) {
|
||||||
//同move事件
|
//同move事件
|
||||||
if (!canNextCb) canNextCb = canNext
|
if (!canNextCb) canNextCb = canNext
|
||||||
if (canNextCb(state, isNext)) {
|
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 gapTime = endTime - state.start.time
|
||||||
let distance = isHorizontal ? state.move.x : state.move.y
|
const distance = isHorizontal ? state.move.x : state.move.y
|
||||||
let judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
|
const judgeValue = isHorizontal ? state.wrapper.width : state.wrapper.height
|
||||||
//1、距离太短,直接不通过
|
//1、距离太短,直接不通过
|
||||||
if (Math.abs(distance) < 20) gapTime = 1000
|
if (Math.abs(distance) < 20) gapTime = 1000
|
||||||
//2、距离太长,直接通过
|
//2、距离太长,直接通过
|
||||||
if (Math.abs(distance) > judgeValue / 3) gapTime = 100
|
if (Math.abs(distance) > judgeValue / 3) gapTime = 100
|
||||||
//3、若不在上面那个情况,那么只需要判断时间即可
|
//3、若不在上述两种情况,那么只需要判断时间即可
|
||||||
if (gapTime < 150) {
|
if (gapTime < 150) {
|
||||||
if (isNext) {
|
if (isNext) {
|
||||||
state.localIndex++
|
state.localIndex++
|
||||||
@ -184,9 +217,11 @@ export function slideTouchEnd(e, state, canNextCb = null, nextCb = null, notNext
|
|||||||
* @param state
|
* @param state
|
||||||
* @param emit
|
* @param emit
|
||||||
*/
|
*/
|
||||||
export function slideReset(el, state, emit = null) {
|
export function slideReset(e, el, state, emit = null) {
|
||||||
Utils.$setCss(el, 'transition-duration', `300ms`)
|
if (!checkEvent(e)) return
|
||||||
let t = getSlideOffset(state, el)
|
|
||||||
|
_css(el, 'transition-duration', `300ms`)
|
||||||
|
const t = getSlideOffset(state, el)
|
||||||
let dx1 = 0
|
let dx1 = 0
|
||||||
let dx2 = 0
|
let dx2 = 0
|
||||||
if (state.type === SlideType.HORIZONTAL) {
|
if (state.type === SlideType.HORIZONTAL) {
|
||||||
@ -196,16 +231,21 @@ export function slideReset(el, state, emit = null) {
|
|||||||
bus.emit(state.name + '-end')
|
bus.emit(state.name + '-end')
|
||||||
dx2 = t
|
dx2 = t
|
||||||
}
|
}
|
||||||
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
_css(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
|
||||||
state.start.x = state.start.y = state.start.time = state.move.x = state.move.y = 0
|
state.start.x = state.start.y = state.start.time = state.move.x = state.move.y = 0
|
||||||
state.next = false
|
state.next = false
|
||||||
state.needCheck = true
|
state.needCheck = true
|
||||||
|
state.isDown = false
|
||||||
|
// e.target.style.pointerEvents = null
|
||||||
|
setTimeout(() => {
|
||||||
|
window.isMoved = false
|
||||||
|
}, 200)
|
||||||
emit?.('update:index', state.localIndex)
|
emit?.('update:index', state.localIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
//根据当前index,获取slide偏移距离
|
//根据当前index,获取slide偏移距离
|
||||||
//如果每个页面的宽度是相同均为100%,只需要当前index * wrapper的宽(高)度即可: -state.localIndex * state.wrapper.width
|
//如果每个页面的宽度是相同均为100%,只需要当前index * wrapper的宽(高)度即可: -state.localIndex * state.wrapper.width
|
||||||
export function getSlideOffset(state, el) {
|
export function getSlideOffset(state: any, el: HTMLDivElement) {
|
||||||
//横竖判断逻辑基本同理
|
//横竖判断逻辑基本同理
|
||||||
if (state.type === SlideType.HORIZONTAL) {
|
if (state.type === SlideType.HORIZONTAL) {
|
||||||
let widths = []
|
let widths = []
|
||||||
@ -222,7 +262,10 @@ export function getSlideOffset(state, el) {
|
|||||||
return 0
|
return 0
|
||||||
// return -state.localIndex * state.wrapper.width
|
// return -state.localIndex * state.wrapper.width
|
||||||
} else {
|
} else {
|
||||||
|
//VERTICAL_INFINITE 列表只需要计算index * 高就行
|
||||||
if (state.type === SlideType.VERTICAL_INFINITE) {
|
if (state.type === SlideType.VERTICAL_INFINITE) {
|
||||||
|
return -state.localIndex * state.wrapper.height
|
||||||
|
} else {
|
||||||
//同上
|
//同上
|
||||||
let heights = []
|
let heights = []
|
||||||
Array.from(el.children).map((v) => {
|
Array.from(el.children).map((v) => {
|
||||||
@ -231,9 +274,6 @@ export function getSlideOffset(state, el) {
|
|||||||
heights = heights.slice(0, state.localIndex)
|
heights = heights.slice(0, state.localIndex)
|
||||||
if (heights.length) return -heights.reduce((a, b) => a + b)
|
if (heights.length) return -heights.reduce((a, b) => a + b)
|
||||||
return 0
|
return 0
|
||||||
} else {
|
|
||||||
//VERTICAL_INFINITE 列表只需要计算index * 高就行
|
|
||||||
return -state.localIndex * state.wrapper.height
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,12 +63,6 @@ export default defineConfig(async () => {
|
|||||||
name: 'mockjs',
|
name: 'mockjs',
|
||||||
var: 'Mock',
|
var: 'Mock',
|
||||||
path: 'https://lib.baomitu.com/Mock.js/1.0.1-beta3/mock-min.js'
|
path: 'https://lib.baomitu.com/Mock.js/1.0.1-beta3/mock-min.js'
|
||||||
},
|
|
||||||
|
|
||||||
{
|
|
||||||
name: 'jquery',
|
|
||||||
var: '$',
|
|
||||||
path: 'https://lib.baomitu.com/jquery/3.6.0/jquery.min.js'
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user