This commit is contained in:
hhh 2023-01-23 03:54:35 +08:00
parent 6b0731fff0
commit 881eb98bc1
12 changed files with 220 additions and 133 deletions

View File

@ -16,7 +16,7 @@ specifiers:
pinyin: 2.11.1 pinyin: 2.11.1
vconsole: ^3.15.0 vconsole: ^3.15.0
vite: 4.0.4 vite: 4.0.4
vue: ^3.2.45 vue: 3.2.45
vue-router: 4.0.14 vue-router: 4.0.14
vue-switches: 2.0.1 vue-switches: 2.0.1
vuex: 4.0.2 vuex: 4.0.2

View File

@ -5,6 +5,7 @@
@second-btn-color-tran: rgba(58, 58, 70, .4); @second-btn-color-tran: rgba(58, 58, 70, .4);
@line-color: rgb(37, 45, 66); @line-color: rgb(37, 45, 66);
@line-color2: rgb(56, 54, 67); @line-color2: rgb(56, 54, 67);
@footer-color:#020202;
@primary-btn-color: rgb(252, 47, 86); @primary-btn-color: rgb(252, 47, 86);
@disable-primary-btn-color: rgba(252, 47, 86, .5); @disable-primary-btn-color: rgba(252, 47, 86, .5);

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="footer"> <div v-if="visible" class="footer">
<div class="l-button" @click="refresh(1)"> <div class="l-button" @click="refresh(1)">
<span v-if="!isRefresh1" :class="{active:currentTab===1}">首页</span> <span v-if="!isRefresh1" :class="{active:currentTab===1}">首页</span>
<img v-if="isRefresh1 " src="../assets/img/icon/refresh1.png" alt="" class="refresh"> <img v-if="isRefresh1 " src="../assets/img/icon/refresh1.png" alt="" class="refresh">
@ -26,6 +26,8 @@
</template> </template>
<script> <script>
import bus from "../utils/bus";
export default { export default {
name: "Footer", name: "Footer",
props: ['initTab'], props: ['initTab'],
@ -34,8 +36,14 @@ export default {
isRefresh1: false, isRefresh1: false,
isRefresh2: false, isRefresh2: false,
currentTab: this.initTab, currentTab: this.initTab,
visible: true
} }
}, },
created() {
bus.on('setFooterVisible', (e) => this.visible = e)
bus.on('enterFullscreen', (e) => this.visible = false)
bus.on('exitFullscreen', (e) => this.visible = true)
},
methods: { methods: {
tab(index) { tab(index) {
switch (index) { switch (index) {
@ -84,7 +92,7 @@ export default {
// 使footerbottom0 // 使footerbottom0
top: calc(100vh - @footer-height); top: calc(100vh - @footer-height);
//bottom: 0; //bottom: 0;
background: #020202; background: @footer-color;
color: white; color: white;
display: flex; display: flex;
//justify-content: space-between; //justify-content: space-between;

View File

@ -52,7 +52,7 @@ const state = reactive({
</script> </script>
<template> <template>
<div class="item-desc"> <div class="item-desc">
<div class="content ml1r mb2r" v-if="!isMy"> <div class="content ml1r mb1r" v-if="!isMy">
<div class="location-wrapper" v-if=" item.city || item.address"> <div class="location-wrapper" v-if=" item.city || item.address">
<div class="location"> <div class="location">
<img src="../../assets/img/icon/location.webp" alt=""> <img src="../../assets/img/icon/location.webp" alt="">

View File

@ -1,6 +1,5 @@
<template> <template>
<!--不知为啥touch事件在下部20px的空间内不触发加上click事件不好了 --> <div id="SlideAlbum">
<div id="SlideImgs">
<div class="img-slide-wrapper"> <div class="img-slide-wrapper">
<div class="img-slide-list" <div class="img-slide-list"
ref="wrapperEl" ref="wrapperEl"
@ -13,8 +12,7 @@
</div> </div>
</div> </div>
</div> </div>
<template v-if="!state.isPreview"> <template v-if=" state.operationStatus === SlideAlbumOperationStatus.Normal">
<template v-if="false">
<ItemToolbar :item="props.modelValue" <ItemToolbar :item="props.modelValue"
:index="0" :index="0"
prefix="sadfa" prefix="sadfa"
@ -25,7 +23,10 @@
prefix="sadfa" prefix="sadfa"
/> />
</template> </template>
<!--不知为啥touch事件在下部20px的空间内不触发加上click事件不好了 -->
<div class="progress-bar" <div class="progress-bar"
v-if="!state.isPreview && state.operationStatus!== SlideAlbumOperationStatus.Zooming"
@click="null"
@touchstart="progressBarTouchStart" @touchstart="progressBarTouchStart"
@touchmove="progressBarTouchMove" @touchmove="progressBarTouchMove"
@touchend="progressBarTouchMEnd" @touchend="progressBarTouchMEnd"
@ -35,9 +36,8 @@
:style="getProgressWidth(index)"></div> :style="getProgressWidth(index)"></div>
</div> </div>
</div> </div>
<Teleport to="#slideHook" v-if="state.isPreview">
</template> <div class="preview">
<div class="preview" v-if="state.isPreview">
<div class="preview-wrapper"> <div class="preview-wrapper">
<img :src="img" <img :src="img"
:class="{'preview-img':index === state.localIndex}" :class="{'preview-img':index === state.localIndex}"
@ -49,6 +49,17 @@
<span class="index">{{ state.localIndex + 1 }}</span>&nbsp;/&nbsp;{{ props.modelValue.imgs.length }} <span class="index">{{ state.localIndex + 1 }}</span>&nbsp;/&nbsp;{{ props.modelValue.imgs.length }}
</div> </div>
</div> </div>
</Teleport>
<Teleport to="#slideHook" v-if="state.operationStatus === SlideAlbumOperationStatus.Detail">
<div class="album-toolbar">
<div class="left">关闭</div>
<div class="right">
<div class="option">评论</div>
<div class="option">切换</div>
<div class="option">下载</div>
</div>
</div>
</Teleport>
</div> </div>
</template> </template>
@ -56,7 +67,7 @@
import enums from "../../utils/enums"; import enums from "../../utils/enums";
import Utils from '../../utils' import Utils from '../../utils'
import {mat4} from 'gl-matrix' import {mat4} from 'gl-matrix'
import {onMounted, onBeforeUpdate, reactive, ref, watch} from "vue"; import {onMounted, onBeforeUpdate, reactive, ref, watch, computed} from "vue";
import { import {
getSlideDistance, getSlideDistance,
slideInit, slideInit,
@ -65,15 +76,12 @@ import {
slideTouchMove, slideTouchMove,
slideTouchStart slideTouchStart
} from "../../pages/slideHooks/common"; } from "../../pages/slideHooks/common";
import {SlideType} from "../../utils/const_var"; import {SlideAlbumOperationStatus, SlideType} from "../../utils/const_var";
import ItemToolbar from "./ItemToolbar"; import ItemToolbar from "./ItemToolbar";
import ItemDesc from "./ItemDesc"; import ItemDesc from "./ItemDesc";
import GM from "../../utils"; import GM from "../../utils";
import {cloneDeep} from "lodash"; import {cloneDeep} from "lodash";
import bus from "../../utils/bus";
function c() {
console.log('console.log()')
}
let out = new Float32Array([ let out = new Float32Array([
0, 0, 0, 0, 0, 0, 0, 0,
@ -199,7 +207,8 @@ const state = reactive({
localIndex: 0, localIndex: 0,
needCheck: true, needCheck: true,
isPreview: false, isPreview: false,
isTwo: true, isZoom: false,
operationStatus: SlideAlbumOperationStatus.Normal,
next: false, next: false,
wrapper: {width: 0, height: 0, childrenLength: 0}, wrapper: {width: 0, height: 0, childrenLength: 0},
last: { last: {
@ -258,6 +267,21 @@ watch(
} }
) )
watch(
() => state.operationStatus,
(newVal) => {
if (newVal === SlideAlbumOperationStatus.Zooming) {
bus.emit('enterFullscreen')
} else {
bus.emit('exitFullscreen')
}
}
)
const isZooming = computed(() => {
return state.operationStatus === SlideAlbumOperationStatus.Zooming
})
function calcCurrentIndex(e) { function calcCurrentIndex(e) {
state.isPreview = true state.isPreview = true
let x = e.touches[0].pageX let x = e.touches[0].pageX
@ -277,39 +301,26 @@ function calcCurrentIndex(e) {
} }
function progressBarTouchStart(e) { function progressBarTouchStart(e) {
console.log('progressBarTouchStart')
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
} }
function progressBarTouchMove(e) { function progressBarTouchMove(e) {
console.log('progressBarTouchMove') Utils.$stopPropagation(e)
let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} calcCurrentIndex(e)
// let rect = wrapperEl.value.getBoundingClientRect()
// if (rect.height - 15 < current1.y && current1.y < rect.height) {
// console.log('')
// state.isPreview = true
// // Utils.$stopPropagation(e)
// }
// calcCurrentIndex(e)
} }
function progressBarTouchMEnd(e) { function progressBarTouchMEnd(e) {
console.log('progressBarTouchEnd')
if (state.isPreview){
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
}
state.isPreview = false state.isPreview = false
} }
function touchStart(e) { function touchStart(e) {
console.log('start', e.touches.length) console.log('start', e.touches.length)
if (e.touches.length === 1) { if (e.touches.length === 1) {
state.isTwo = false
slideTouchStart(e, wrapperEl.value, state) slideTouchStart(e, wrapperEl.value, state)
} else { } else {
if (state.isTwo) return if (isZooming.value) return
state.isTwo = true state.operationStatus = SlideAlbumOperationStatus.Zooming
state.itemRefs[state.localIndex].style['transition-duration'] = '0ms'; state.itemRefs[state.localIndex].style['transition-duration'] = '0ms';
state.last.point1 = state.start.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}; state.last.point1 = state.start.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY};
state.last.point2 = state.start.point2 = {x: e.touches[1].pageX, y: e.touches[1].pageY}; state.last.point2 = state.start.point2 = {x: e.touches[1].pageX, y: e.touches[1].pageY};
@ -318,9 +329,10 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
console.log('move', e.touches.length) console.log('move', e.touches.length,)
let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
if (state.isTwo && e.touches.length === 1) { if (isZooming.value && e.touches.length === 1) {
console.log('m1')
state.status = 'pause' state.status = 'pause'
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
@ -334,16 +346,19 @@ function touchMove(e) {
state.last.point1 = current1 state.last.point1 = current1
} else { } else {
if (e.touches.length === 1) { if (e.touches.length === 1) {
state.isTwo = false console.log('m2')
if (state.isPreview) { slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext,
// Utils.$stopPropagation(e) () => {
}else {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, () => {
state.status = 'pause' state.status = 'pause'
}, SlideType.HORIZONTAL) }, SlideType.HORIZONTAL,
() => {
if (state.operationStatus === SlideAlbumOperationStatus.Detail) {
Utils.$stopPropagation(e)
} }
})
} else { } else {
state.isTwo = true console.log('m3')
state.operationStatus = SlideAlbumOperationStatus.Zooming
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
state.status = 'pause' state.status = 'pause'
@ -398,13 +413,14 @@ function touchMove(e) {
function touchEnd(e) { function touchEnd(e) {
state.isPreview = false state.isPreview = false
// console.log('end', e.touches.length, state.isTwo) console.log('end', e.touches.length, state.operationStatus)
// //
if (state.isTwo && e.touches.length === 1) { if (isZooming.value && e.touches.length === 1) {
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
state.last.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} state.last.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
} else { } else {
if (state.isTwo) { if (isZooming.value) {
state.operationStatus = SlideAlbumOperationStatus.Detail
ov = origin ov = origin
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
state.itemRefs[state.localIndex].style['transition-duration'] = '300ms'; state.itemRefs[state.localIndex].style['transition-duration'] = '300ms';
@ -416,6 +432,8 @@ function touchEnd(e) {
state.progress = (state.localIndex + 1) * 100 state.progress = (state.localIndex + 1) * 100
}, },
() => { () => {
console.log('notNextCb')
state.operationStatus = SlideAlbumOperationStatus.Normal
if (state.status !== 'custom') { if (state.status !== 'custom') {
state.status = 'play' state.status = 'play'
requestAnimationFrame(state.cycleFn) requestAnimationFrame(state.cycleFn)
@ -436,16 +454,21 @@ function setItemRef(el, key) {
el && state[key].push(el) el && state[key].push(el)
} }
function canNext(isNext) { function canNext(isNext, e) {
return !((state.localIndex === 0 && !isNext) || (state.localIndex === props.modelValue.imgs.length - 1 && isNext)); let res = !((state.localIndex === 0 && !isNext) || (state.localIndex === props.modelValue.imgs.length - 1 && isNext));
if (!res && state.operationStatus === SlideAlbumOperationStatus.Detail && e) {
Utils.$stopPropagation(e)
}
return res
} }
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
#SlideImgs { @import "@/assets/less/index";
#SlideAlbum {
position: relative; position: relative;
background: blue;
width: 100%; width: 100%;
height: 100%; height: 100%;
overflow: hidden; overflow: hidden;
@ -488,8 +511,8 @@ function canNext(isNext) {
padding: 0 5rem; padding: 0 5rem;
@h: 4rem; @h: 4rem;
//height: @h; //height: @h;
height: 30rem; height: 10rem;
background-color: red; //background-color: red;
align-items: flex-end; align-items: flex-end;
justify-content: space-between; justify-content: space-between;
@ -498,7 +521,7 @@ function canNext(isNext) {
flex: 1; flex: 1;
margin: 0 2rem; margin: 0 2rem;
height: @h; height: @h;
background: gray; background: rgba(#000, .5);
position: relative; position: relative;
overflow: hidden; overflow: hidden;
@ -512,10 +535,15 @@ function canNext(isNext) {
} }
} }
}
</style>
<style lang="less">
@import "@/assets/less/index";
.preview { .preview {
transition: opacity .3s; transition: opacity .3s;
position: fixed; position: fixed;
bottom: 20rem; bottom: 0;
width: 100%; width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
@ -540,13 +568,52 @@ function canNext(isNext) {
} }
.indicator { .indicator {
margin-top: 10rem; background: @footer-color;
width: 100%;
height: @footer-height;
color: gray; color: gray;
display: flex;
align-items: center;
justify-content: center;
.index { .index {
color: white; color: white;
} }
} }
} }
.album-toolbar {
position: absolute;
bottom: 0;
background: @footer-color;
width: 100%;
box-sizing: border-box;
height: @footer-height;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10rem;
@padding: 12rem;
.left {
height: 34rem;
background-color: gray;
border-radius: 6rem;
padding: 0 @padding;
display: flex;
align-items: center;
justify-content: center;
} }
.right {
.left;
.option {
margin: 0 5rem;
}
}
}
</style> </style>

View File

@ -9,14 +9,13 @@ import store from "./store";
import mixin from "./utils/mixin"; import mixin from "./utils/mixin";
import VueLazyload from '@jambonn/vue-lazyload' import VueLazyload from '@jambonn/vue-lazyload'
import VConsole from 'vconsole'; import VConsole from 'vconsole';
const vConsole = new VConsole(); const vConsole = new VConsole();
const app = Vue.createApp(App) const app = Vue.createApp(App)
app.config.globalProperties.$api = {...api} app.config.globalProperties.$api = {...api}
const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href const loadImage = new URL('./assets/img/icon/img-loading.png', import.meta.url).href
app.provide('mitt', mitt()) app.provide('mitt', mitt())
app.mixin(mixin) app.mixin(mixin)
app.use(VueLazyload, { app.use(VueLazyload, {

View File

@ -36,13 +36,13 @@ export function canSlide(state, judgeValue, type = SlideType.HORIZONTAL) {
return state.next return state.next
} }
export function slideTouchMove(e, el, state, judgeValue, canNextCb, nextCb, type = SlideType.HORIZONTAL) { export function slideTouchMove(e, el, state, judgeValue, canNextCb, nextCb, type = SlideType.HORIZONTAL,notNextCb) {
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
let isNext = type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0 let isNext = type === SlideType.HORIZONTAL ? state.move.x < 0 : state.move.y < 0
if (!canNextCb?.(isNext)) return if (!canNextCb?.(isNext, e)) return
if (canSlide(state, judgeValue, type)) { if (canSlide(state, judgeValue, type)) {
nextCb?.() nextCb?.()
@ -58,6 +58,8 @@ export function slideTouchMove(e, el, state, judgeValue, canNextCb, nextCb, type
} }
Utils.$setCss(el, 'transition-duration', `0ms`) Utils.$setCss(el, 'transition-duration', `0ms`)
Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`) Utils.$setCss(el, 'transform', `translate3d(${dx1}px, ${dx2}px, 0)`)
}else {
notNextCb?.()
} }
} }
@ -65,7 +67,7 @@ export function slideTouchEnd(e, state, canNextCb, nextCb, notNextCb, type = Sli
let isHorizontal = type === SlideType.HORIZONTAL; let isHorizontal = type === SlideType.HORIZONTAL;
let isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0 let isNext = isHorizontal ? state.move.x < 0 : state.move.y < 0
if (!canNextCb?.(isNext)) return if (!canNextCb?.(isNext)) return notNextCb?.()
if (state.next) { if (state.next) {
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
let endTime = Date.now() let endTime = Date.now()
@ -80,12 +82,11 @@ export function slideTouchEnd(e, state, canNextCb, nextCb, notNextCb, type = Sli
} else { } else {
state.localIndex-- state.localIndex--
} }
nextCb?.() return nextCb?.()
} else { }
}
notNextCb?.() notNextCb?.()
} }
}
}
export function slideReset(el, state, type, emit) { export function slideReset(el, state, type, emit) {
Utils.$setCss(el, 'transition-duration', `300ms`) Utils.$setCss(el, 'transition-duration', `300ms`)

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="test-slide-wrapper"> <div class="test-slide-wrapper" id="slideHook">
<H v-model:index="state.baseIndex"> <H v-model:index="state.baseIndex">
<SlideItem class=" gray"> <SlideItem class=" gray">
<H class="h" v-model:index="state.navIndex"> <H class="h" v-model:index="state.navIndex">
@ -54,7 +54,7 @@ import VInfinite from './VInfinite.vue'
import SlideItem from './SlideItem' import SlideItem from './SlideItem'
import SlideVideo from "../../components/slide/SlideVideo"; import SlideVideo from "../../components/slide/SlideVideo";
import SlideUser from "../../components/slide/SlideUser"; import SlideUser from "../../components/slide/SlideUser";
import SlideImgs from "../../components/slide/SlideImgs"; import SlideImgs from "../../components/slide/SlideAlbum";
import BVideo from "../../components/slide/BVideo"; import BVideo from "../../components/slide/BVideo";
import resource from "../../assets/data/resource.js"; import resource from "../../assets/data/resource.js";
@ -235,6 +235,8 @@ function render(item, itemIndex, play,prefix) {
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@import "@/assets/less/index";
.test-slide-wrapper { .test-slide-wrapper {
font-size: 14rem; font-size: 14rem;
width: 100%; width: 100%;

View File

@ -15,7 +15,7 @@
import TestSlide from "./TestSlide"; import TestSlide from "./TestSlide";
import SlideUser from "../../components/slide/SlideUser"; import SlideUser from "../../components/slide/SlideUser";
import SlideImgs from "../../components/slide/SlideImgs"; import SlideImgs from "../../components/slide/SlideAlbum";
import TestImg from "./TestImg"; import TestImg from "./TestImg";
import slideHooks from '../slideHooks' import slideHooks from '../slideHooks'
import {mat4} from "gl-matrix"; import {mat4} from "gl-matrix";

View File

@ -30,7 +30,7 @@
import Slide from "./slide.jsx"; import Slide from "./slide.jsx";
import SlideVideo from "../../components/slide/SlideVideo"; import SlideVideo from "../../components/slide/SlideVideo";
import SlideUser from "../../components/slide/SlideUser"; import SlideUser from "../../components/slide/SlideUser";
import SlideImgs from "../../components/slide/SlideImgs"; import SlideImgs from "../../components/slide/SlideAlbum";
import resource from "../../assets/data/resource.js"; import resource from "../../assets/data/resource.js";
import CONST_VAR from "../../utils/const_var"; import CONST_VAR from "../../utils/const_var";
import Dom from "../../utils/dom"; import Dom from "../../utils/dom";

View File

@ -67,10 +67,7 @@ import Uploader from "../pages/me/Uploader";
import Slide from "../pages/slide/Slide"; import Slide from "../pages/slide/Slide";
const routes = [ const routes = [
{ {path: '/', redirect: '/test'},
path: '/',
redirect: '/test'
},
{path: '/slide', component: Slide}, {path: '/slide', component: Slide},
{path: '/test', component: Test}, {path: '/test', component: Test},
{path: '/test4', component: Test4}, {path: '/test4', component: Test4},

View File

@ -23,3 +23,15 @@ export const SlideType = {
HORIZONTAL: 0, HORIZONTAL: 0,
VERTICAL: 1, VERTICAL: 1,
} }
/*图集操作状态*/
export const SlideAlbumOperationStatus = {
Normal: 'Normal',
Zooming: 'Zooming',
Detail: 'Detail',
}
/*图集播放状态*/
export const SlideAlbumPlayStatus = {
HORIZONTAL: 0,
VERTICAL: 1,
}