Browse Source

save

pull/29/head
hhh 3 years ago
parent
commit
3cc830560d
  1. 451
      src/components/slide/SlideImgs.vue
  2. 336
      src/components/slide/SlideImgs2.vue
  3. 2
      src/pages/slideHooks/H.vue
  4. 4
      src/pages/slideHooks/SlideItem.vue
  5. 8
      src/pages/slideHooks/V.vue
  6. 4
      src/pages/slideHooks/VInfinite.vue
  7. 12
      src/pages/slideHooks/common.js
  8. 26
      src/pages/slideHooks/index.vue
  9. 14
      src/pages/test/Test.vue
  10. 11
      src/utils/index.jsx

451
src/components/slide/SlideImgs.vue

@ -1,12 +1,12 @@
<template> <template>
<div id="SlideImgs"> <div id="SlideImgs">
<div class="img-slide-wrapper" ref="wap"> <div class="img-slide-wrapper">
<div class="img-slide-list" <div class="img-slide-list"
ref="list" ref="wrapperEl"
@touchstart="touchstart" @touchstart="touchStart"
@touchmove="touchmove" @touchmove="touchMove"
@touchend="touchend"> @touchend="touchEnd">
<div class="img-slide-item" v-for="img in modelValue.imgs"> <div class="img-slide-item" v-for="img in props.modelValue.imgs">
<img :ref="setItemRef" :src="img"> <img :ref="setItemRef" :src="img">
</div> </div>
</div> </div>
@ -20,11 +20,20 @@
</div> </div>
</template> </template>
<script> <script setup lang="jsx">
import enums from "../../utils/enums"; import enums from "../../utils/enums";
import globalMethods from '../../utils' import Utils from '../../utils'
import {mat4} from 'gl-matrix' import {mat4} from 'gl-matrix'
import {cloneDeep} from "lodash"; import {onMounted, reactive, ref} from "vue";
import {
getSlideDistance,
slideInit,
slideReset,
slideTouchEnd,
slideTouchMove,
slideTouchStart
} from "../../pages/slideHooks/common";
import {SlideType} from "../../utils/const_var";
let out = new Float32Array([ let out = new Float32Array([
0, 0, 0, 0, 0, 0, 0, 0,
@ -38,12 +47,8 @@ let ov = new Float32Array([
0, 0, 1, 0, 0, 0, 1, 0,
0, 0, 0, 1, 0, 0, 0, 1,
]); ]);
let original = cloneDeep(ov)
const rectMap = new Map() const rectMap = new Map()
export default { const props = defineProps({
name: "SlideImgs",
components: {},
props: {
modelValue: { modelValue: {
type: Object, type: Object,
default() { default() {
@ -141,323 +146,192 @@ export default {
} }
} }
} }
}, })
data() { const judgeValue = 20
return { const wrapperEl = ref(null)
itemRefs: [],
baseActiveIndex: 0, const state = reactive({
progress: 0, name: 'SlideHorizontal',
cycleFn: null, localIndex: 0,
state: 'play',//stop,custom needCheck: true,
isTwo: true,
startX: 0, next: false,
startY: 0, wrapper: {width: 0, height: 0, childrenLength: 0},
moveX: 0,
moveY: 0,
width: document.body.clientWidth,
startTime: 0,
index: 0,
isDrawRight: false,
isDrawDown: false,
isTwo: false,
store: {
scale: 1
},
result: {
width: 414,
height: 737
},
x: 0,
y: 79,
scale: 1,
maxScale: 3,
minScale: 0.5,
point1: {x: 0, y: 0},
point2: {x: 0, y: 0},
diff: {x: 0, y: 0},
lastPointermove: {x: 0, y: 0},
lastPoint1: {x: 0, y: 0},
lastPoint2: {x: 0, y: 0},
lastCenter: {x: 0, y: 0},
startCenter: {x: 0, y: 0},
a: {},
b: {},
last: { last: {
ratio: 1,
point1: {x: 0, y: 0}, point1: {x: 0, y: 0},
point2: {x: 0, y: 0}, point2: {x: 0, y: 0},
}, },
start: { start: {
x: 0, y: 0,
point1: {x: 0, y: 0}, point1: {x: 0, y: 0},
point2: {x: 0, y: 0}, point2: {x: 0, y: 0},
} center: {x: 0, y: 0},
} time: 0
}, },
created() { move: {x: 0, y: 0},
this.width = document.body.clientWidth itemRefs: [],
}, status: 'play',//stop,custom
watch: { progress: 0,
state(newVal, oldVal) { cycleFn: null,
return })
console.log('newVal', newVal) onMounted(() => {
if (newVal === 'play') requestAnimationFrame(this.cycleFn) slideInit(wrapperEl.value, state, SlideType.HORIZONTAL)
if (newVal === 'stop') cancelAnimationFrame(this.cycleFn)
if (newVal === 'custom') cancelAnimationFrame(this.cycleFn) state.cycleFn = () => {
} if (state.status !== 'play') return cancelAnimationFrame(state.cycleFn)
}, if (state.progress < props.modelValue.imgs.length * 100) {
mounted() { state.progress += .4
this.cycleFn = () => { state.localIndex = parseInt(state.progress / 100)
if (this.state !== 'play') return cancelAnimationFrame(this.cycleFn) if (wrapperEl.value) {
if (this.progress < this.modelValue.imgs.length * 100) { Utils.$setCss(wrapperEl.value, 'transition-duration', `300ms`)
this.progress += .4 Utils.$setCss(wrapperEl.value, 'transform', `translate3d(${getSlideDistance(state)}px, 0px, 0px)`)
this.index = parseInt(this.progress / 100)
if (this.$refs.list) {
globalMethods.$setCss(this.$refs.list, 'transition-duration', `300ms`)
globalMethods.$setCss(this.$refs.list, 'transform',
`translate3d(${-this.getWidth(this.index)}px, 0px, 0px)`)
} }
} else { } else {
this.progress = 0 state.progress = 0
// cancelAnimationFrame(this.cycleFn) // cancelAnimationFrame(this.cycleFn)
} }
requestAnimationFrame(this.cycleFn) requestAnimationFrame(state.cycleFn)
} }
return requestAnimationFrame(state.cycleFn)
// requestAnimationFrame(this.cycleFn) })
let x = 0 function touchStart(e) {
let y = 0
let scale = 1
let isDrag = false //
const image = document.querySelector(`.img-slide-list`);
let tt = new Map()
image.addEventListener('wheel', e => {
this.itemRefs[this.index].style['transition-duration'] = '0ms';
let {clientX, clientY, deltaY} = e;
let rect = {x: 0, y: 0}
if (tt.has(this.index)) {
rect = tt.get(this.index)
} else {
rect = this.itemRefs[this.index].getBoundingClientRect()
tt.set(this.index, rect)
}
clientX -= rect.x
clientY -= rect.y
const zoom = 1 + (deltaY < 0 ? 0.1 : -0.1);
const x = clientX * (1 - zoom);
const y = clientY * (1 - zoom);
const t = new Float32Array([zoom, 0, 0, 0, 0, zoom, 0, 0, 0, 0, 1, 0, x, y, 0, 1,]);
ov = mat4.multiply(out, t, ov);
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
// image.setAttribute("style", `transform:matrix3d(${ov.toString()});`);
})
image.addEventListener('mousedown', () => {
this.itemRefs[this.index].style['transition-duration'] = '0ms';
isDrag = true
});
image.addEventListener('mousemove', (e) => {
e.preventDefault();
if (isDrag) {
const {movementX, movementY} = e;
const t = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, movementX, movementY, 0, 1,]);
ov = mat4.multiply(out, t, ov);
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
}
});
image.addEventListener('mouseup', () => {
this.itemRefs[this.index].style['transition-duration'] = '300ms';
this.itemRefs[this.index].style.transform = `matrix3d(${original.toString()})`;
ov = original
isDrag = false
});
},
methods: {
getCenter(a, b) {
const x = (a.x + b.x) / 2;
const y = (a.y + b.y) / 2;
return {x, y}
},
//
getDistance(start, stop) {
return Math.hypot(stop.x - start.x, stop.y - start.y);
},
touchstart(e) {
console.log('start', e.touches.length) console.log('start', e.touches.length)
if (this.state !== 'custom') { // if (s.state !== 'custom') {
this.state = 'stop' // this.state = 'stop'
} // }
if (e.touches.length === 1) { if (e.touches.length === 1) {
this.isTwo = false state.isTwo = false
globalMethods.$setCss(this.$refs.list, 'transition-duration', `0ms`) slideTouchStart(e, wrapperEl.value, state)
this.startX = e.touches[0].pageX
this.startY = e.touches[0].pageY
this.startTime = Date.now()
} else { } else {
if (this.isTwo) return if (state.isTwo) return
this.isTwo = true state.isTwo = true
this.itemRefs[this.index].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};
if (e.cancelable) { state.last.point2 = state.start.point2 = {x: e.touches[1].pageX, y: e.touches[1].pageY};
e.preventDefault(); state.start.center = Utils.getCenter(state.start.point1, state.start.point2)
} }
}
function touchMove(e) {
// console.log('move', e.touches.length)
if (state.isTwo && e.touches.length === 1) {
state.status = 'pause'
Utils.$stopPropagation(e)
this.last.point1 = this.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY};
this.last.point2 = this.point2 = {x: e.touches[1].pageX, y: e.touches[1].pageY};
this.startCenter = this.getCenter(this.point1, this.point2)
}
},
touchmove(e) {
console.log('move', e.touches.length)
if (this.isTwo && e.touches.length === 1) {
// console.log('',) // console.log('',)
let current = {x: e.touches[0].pageX, y: e.touches[0].pageY} let current = {x: e.touches[0].pageX, y: e.touches[0].pageY}
let movementX = current.x - this.last.point1.x let movementX = current.x - state.last.point1.x
let movementY = current.y - this.last.point1.y let movementY = current.y - state.last.point1.y
console.log(movementX, movementY) // console.log(movementX, movementY)
const t = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, movementX, movementY, 0, 1,]); const t = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, movementX, movementY, 0, 1,]);
let ov1 = mat4.multiply(out, t, ov); ov = mat4.multiply(out, t, ov);
this.itemRefs[this.index].style.transform = `matrix3d(${ov1.toString()})`; state.itemRefs[state.localIndex].style.transform = `matrix3d(${ov.toString()})`;
// this.last.point1 = current state.last.point1 = current
} else { } else {
if (e.touches.length === 1) { if (e.touches.length === 1) {
this.isTwo = false state.isTwo = false
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, () => {
this.moveX = e.touches[0].pageX - this.startX state.status = 'pause'
this.moveY = e.touches[0].pageY - this.startY }, SlideType.HORIZONTAL)
} else {
this.isDrawRight = this.moveX < 0 state.isTwo = true
this.isDrawDown = this.moveY < 0 Utils.$stopPropagation(e)
state.status = 'pause'
if (this.index === 0 && !this.isDrawRight) return
if (this.index === this.modelValue.imgs.length - 1 && this.isDrawRight) return
globalMethods.$setCss(this.$refs.list, 'transform', let rect = {x: 0, y: 0}
`translate3d(${-this.getWidth(this.index) + if (rectMap.has(state.localIndex)) {
this.moveX}px, 0px, 0px)`) rect = rectMap.get(state.localIndex)
} else { } else {
this.isTwo = true //getBoundingClientRect
if (e.cancelable) { let offset = $(state.itemRefs[state.localIndex]).offset()
e.preventDefault(); rect = {x: offset.left, y: offset.top}
rectMap.set(state.localIndex, rect)
} }
let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
let current2 = {x: e.touches[1].pageX, y: e.touches[1].pageY} let current2 = {x: e.touches[1].pageX, y: e.touches[1].pageY}
// //
let ratio = this.getDistance(current1, current2) / this.getDistance(this.point1, this.point2); let currentRatio = Utils.getDistance(current1, current2) / Utils.getDistance(state.start.point1, state.start.point2);
let rect = {x: 0, y: 0} let center = Utils.getCenter(current1, current2)
if (rectMap.has(this.index)) {
rect = rectMap.get(this.index)
} else {
//getBoundingClientRect
let offset = $(this.itemRefs[this.index]).offset()
rect.x = offset.left
rect.y = offset.top
rectMap.set(this.index, rect)
}
let center = cloneDeep(this.startCenter)
center.x -= rect.x center.x -= rect.x
center.y -= rect.y center.y -= rect.y
let zoom = ratio //ratioov[0]
let zoom = currentRatio / ov[0]
const x = center.x * (1 - zoom); const x = center.x * (1 - zoom);
const y = center.y * (1 - zoom); const y = center.y * (1 - zoom);
const t = new Float32Array([zoom, 0, 0, 0, 0, zoom, 0, 0, 0, 0, 1, 0, x, y, 0, 1,]); const t = new Float32Array([zoom, 0, 0, 0, 0, zoom, 0, 0, 0, 0, 1, 0, x, y, 0, 1,]);
//zoom0.15ov //zoomx
//zoomx //zoom0.15ov
ov = mat4.multiply(out, t, original); ov = mat4.multiply(out, t, ov);
let movementX = current1.x - this.last.point1.x let movementRatio = currentRatio - ov[0]
let movementY = current1.y - this.last.point1.y //0.02
let movement2X = current2.x - this.last.point2.x if (Math.abs(movementRatio) <= 0.02) {
let movement2Y = current2.y - this.last.point2.y let movementX = current1.x - state.last.point1.x
let movementY = current1.y - state.last.point1.y
let movement2X = current2.x - state.last.point2.x
let movement2Y = current2.y - state.last.point2.y
let minX = Math.min(movementX, movement2X) let minX = Math.min(movementX, movement2X)
let minY = Math.min(movementY, movement2Y) let minY = Math.min(movementY, movement2Y)
const t1 = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, minX, minY, 0, 1,]);
ov = mat4.multiply(out, t1, ov);
}
console.log('minX', minX, 'minY', minY) state.itemRefs[state.localIndex].style.transform = `matrix3d(${ov.toString()})`;
state.last.point1 = current1
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`; state.last.point2 = current2
this.last.point1 = current1
this.last.point2 = current2
} }
} }
}, }
touchend(e) {
console.log('end', e.touches.length, this.isTwo)
if (this.isTwo && e.touches.length === 1) {
//
this.last.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
} else {
if (this.isTwo) {
ov = original
this.itemRefs[this.index].style['transition-duration'] = '300ms';
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
// if (this.state !== 'custom') {
// this.state = 'play'
// }
// if (e.touches.length) {
// this.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
// }
function touchEnd(e) {
console.log('end', e.touches.length, state.isTwo)
//
if (state.isTwo && e.touches.length === 1) {
Utils.$stopPropagation(e)
state.last.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
} else { } else {
if (this.index === 0 && !this.isDrawRight) return if (state.isTwo) {
if (this.index === this.modelValue.imgs.length - 1 && this.isDrawRight) return Utils.$stopPropagation(e)
state.itemRefs[state.localIndex].style['transition-duration'] = '300ms';
let canSlide = this.width / 5 < Math.abs(this.moveX); state.itemRefs[state.localIndex].style.transform = `matrix3d(${ov.toString()})`;
if (Date.now() - this.startTime < 40) canSlide = false
if (canSlide) {
if (this.isDrawRight) {
this.index += 1
} else {
this.index -= 1
}
this.state = 'custom'
this.progress = (this.index + 1) * 100
} else { } else {
if (this.state !== 'custom') { slideTouchEnd(e, state, canNext,
this.state = 'play' () => {
} state.status = 'custom'
} state.progress = (state.localIndex + 1) * 100
globalMethods.$setCss(this.$refs.list, 'transition-duration', `300ms`)
globalMethods.$setCss(this.$refs.list, 'transform',
`translate3d(${-this.getWidth(this.index)}px, 0px, 0px)`)
}
}
},
getWidth(index) {
return index * this.width
}, },
setItemRef(el) { () => {
if (el) { if (state.status !== 'custom') {
this.itemRefs.push(el) state.status = 'play'
requestAnimationFrame(state.cycleFn)
} }
},
beforeUpdate() {
this.itemRefs = []
},
updated() {
console.log(this.itemRefs)
},
toggle() {
return
if (this.state === 'stop') {
this.state = 'play'
requestAnimationFrame(this.cycleFn)
} else {
this.state = 'stop'
} }
}, )
getProgressWidth(index) { slideReset(wrapperEl.value, state, SlideType.HORIZONTAL, null)
if (this.progress >= (index + 1) * 100) return {width: '100%'}
return {width: `${this.progress - index * 100 < 0 ? 0 : this.progress - index * 100}%`}
} }
} }
} }
function getProgressWidth(index) {
if (state.progress >= (index + 1) * 100) return {width: '100%'}
return {width: `${state.progress - index * 100 < 0 ? 0 : state.progress - index * 100}%`}
}
function setItemRef(el) {
el && state.itemRefs.push(el)
}
function canNext(isNext) {
return !((state.localIndex === 0 && !isNext) || (state.localIndex === props.modelValue.imgs.length - 1 && isNext));
}
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
@ -469,14 +343,10 @@ html {
position: relative; position: relative;
background: black; background: black;
width: 100%; width: 100%;
//height: 100%; height: 100%;
height: calc(100vh - 50rem);
overflow: hidden; overflow: hidden;
color: white; color: white;
font-size: 14rem; font-size: 14rem;
display: flex;
align-items: center;
justify-content: center;
.img-slide-wrapper { .img-slide-wrapper {
height: 100%; height: 100%;
@ -498,30 +368,15 @@ html {
img { img {
transform-origin: 0 0; transform-origin: 0 0;
width: 100vw; width: 100%;
}
}
} }
} }
.content {
width: 100vw;
.base-slide-item {
display: flex;
align-items: center;
justify-content: center;
} }
img {
width: 100vw;
}
} }
.progress-bar { .progress-bar {
position: absolute; position: absolute;
width: 100vw; width: 100%;
bottom: 0; bottom: 0;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;

336
src/components/slide/SlideImgs2.vue

@ -3,9 +3,9 @@
<div class="img-slide-wrapper"> <div class="img-slide-wrapper">
<div class="img-slide-list" <div class="img-slide-list"
ref="list" ref="list"
@touchstart="start" @touchstart="touchstart"
@touchmove="move" @touchmove="touchmove"
@touchend="end"> @touchend="touchend">
<div class="img-slide-item" v-for="img in modelValue.imgs"> <div class="img-slide-item" v-for="img in modelValue.imgs">
<img :ref="setItemRef" :src="img"> <img :ref="setItemRef" :src="img">
</div> </div>
@ -22,8 +22,25 @@
<script> <script>
import enums from "../../utils/enums"; import enums from "../../utils/enums";
import globalMethods from '../../utils' import Utils from '../../utils'
//TODO import GM from '../../utils'
import {mat4} from 'gl-matrix'
import {cloneDeep} from "lodash";
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 original = cloneDeep(ov)
const rectMap = new Map()
export default { export default {
name: "SlideImgs", name: "SlideImgs",
components: {}, components: {},
@ -134,42 +151,27 @@ export default {
cycleFn: null, cycleFn: null,
state: 'play',//stop,custom state: 'play',//stop,custom
startX: 0,
startY: 0,
moveX: 0,
moveY: 0,
width: document.body.clientWidth,
startTime: 0,
index: 0, index: 0,
isDrawRight: false, isNext: false,
isDrawDown: false,
isTwo: false, isTwo: false,
store: { last: {
scale: 1 ratio: 1,
}, point1: {x: 0, y: 0},
result: { point2: {x: 0, y: 0},
width: 414,
height: 737
}, },
x: 0, start: {
y: 79,
scale: 1,
maxScale: 3,
minScale: 0.5,
point1: {x: 0, y: 0}, point1: {x: 0, y: 0},
point2: {x: 0, y: 0}, point2: {x: 0, y: 0},
diff: {x: 0, y: 0}, center: {x: 0, y: 0},
lastPointermove: {x: 0, y: 0}, time: 0
lastPoint1: {x: 0, y: 0}, },
lastPoint2: {x: 0, y: 0}, move: {x: 0, y: 0},
lastCenter: {x: 0, y: 0}, wrapper: {
a: {}, width: 0
b: {}, }
} }
}, },
created() { created() {
this.width = document.body.clientWidth
}, },
watch: { watch: {
state(newVal, oldVal) { state(newVal, oldVal) {
@ -187,9 +189,8 @@ export default {
this.progress += .4 this.progress += .4
this.index = parseInt(this.progress / 100) this.index = parseInt(this.progress / 100)
if (this.$refs.list) { if (this.$refs.list) {
globalMethods.$setCss(this.$refs.list, 'transition-duration', `300ms`) Utils.$setCss(this.$refs.list, 'transition-duration', `300ms`)
globalMethods.$setCss(this.$refs.list, 'transform', Utils.$setCss(this.$refs.list, 'transform', `translate3d(${this.getSlideDistance()}px, 0px, 0px)`)
`translate3d(${-this.getWidth(this.index)}px, 0px, 0px)`)
} }
} else { } else {
this.progress = 0 this.progress = 0
@ -197,6 +198,8 @@ export default {
} }
requestAnimationFrame(this.cycleFn) requestAnimationFrame(this.cycleFn)
} }
this.wrapper.width = GM.$getCss(this.$refs.list, 'width')
return
// requestAnimationFrame(this.cycleFn) // requestAnimationFrame(this.cycleFn)
}, },
methods: { methods: {
@ -205,119 +208,143 @@ export default {
const y = (a.y + b.y) / 2; const y = (a.y + b.y) / 2;
return {x, y} return {x, y}
}, },
start(e) { //
console.log('start') getDistance(start, stop) {
return Math.hypot(stop.x - start.x, stop.y - start.y);
},
touchstart(e) {
console.log('start', e.touches.length)
if (this.state !== 'custom') { if (this.state !== 'custom') {
this.state = 'stop' this.state = 'stop'
} }
if (e.touches && e.touches.length === 1) { if (e.touches.length === 1) {
this.isTwo = false this.isTwo = false
globalMethods.$setCss(this.$refs.list, 'transition-duration', `0ms`) Utils.$setCss(this.$refs.list, 'transition-duration', `0ms`)
this.startX = e.touches[0].pageX this.start = {
this.startY = e.touches[0].pageY point1: {
this.startTime = Date.now() x: e.touches[0].pageX,
y: e.touches[0].pageY,
},
time: Date.now()
}
} else { } else {
if (this.isTwo) return
this.isTwo = true this.isTwo = true
this.itemRefs[this.index].style['transition-duration'] = '0ms'; this.itemRefs[this.index].style['transition-duration'] = '0ms';
let events = e.touches[0]; this.last.point1 = this.start.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY};
let events2 = e.touches[1]; this.last.point2 = this.start.point2 = {x: e.touches[1].pageX, y: e.touches[1].pageY};
this.start.center = this.getCenter(this.start.point1, this.start.point2)
if (e.cancelable) {
e.preventDefault();
}
this.lastPoint1 = this.point1 = {x: events.pageX, y: events.pageY};
this.lastPoint2 = this.point2 = {x: events2.pageX, y: events2.pageY};
this.lastCenter = this.getCenter(this.lastPoint1, this.lastPoint2)
} }
}, },
move(e) { touchmove(e) {
if (e.touches && e.touches.length === 1) { console.log('move', e.touches.length)
if (this.isTwo && e.touches.length === 1) {
Utils.$stopPropagation(e)
// console.log('',)
let current = {x: e.touches[0].pageX, y: e.touches[0].pageY}
let movementX = current.x - this.last.point1.x
let movementY = current.y - this.last.point1.y
console.log(movementX, movementY)
const t = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, movementX, movementY, 0, 1,]);
ov = mat4.multiply(out, t, ov);
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
this.last.point1 = current
} else {
if (e.touches.length === 1) {
this.isTwo = false this.isTwo = false
this.move.x = e.touches[0].pageX - this.start.point1.x
this.moveX = e.touches[0].pageX - this.startX this.move.y = e.touches[0].pageY - this.start.point1.y
this.moveY = e.touches[0].pageY - this.startY this.isNext = this.move.x < 0
if (!this.canNext(this.isNext)) return
this.isDrawRight = this.moveX < 0 Utils.$stopPropagation(e)
this.isDrawDown = this.moveY < 0 Utils.$setCss(this.$refs.list, 'transform', `translate3d(${this.getSlideDistance() + this.move.x}px, 0px, 0px)`)
if (this.index === 0 && !this.isDrawRight) return
if (this.index === this.modelValue.imgs.length - 1 && this.isDrawRight) return
globalMethods.$setCss(this.$refs.list, 'transform',
`translate3d(${-this.getWidth(this.index) +
this.moveX}px, 0px, 0px)`)
} else { } else {
Utils.$stopPropagation(e)
this.isTwo = true this.isTwo = true
if (e.cancelable) {
e.preventDefault();
}
let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} let current1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
let current2 = {x: e.touches[1].pageX, y: e.touches[1].pageY} let current2 = {x: e.touches[1].pageX, y: e.touches[1].pageY}
// //
let getDistance = function (start, stop) { let ratio = this.getDistance(current1, current2) / this.getDistance(this.start.point1, this.start.point2);
return Math.hypot(stop.x - start.x, stop.y - start.y);
};
//
let ratio = getDistance(current1, current2) / getDistance(this.lastPoint1, this.lastPoint2);
let rect = {x: 0, y: 0}
if (rectMap.has(this.index)) {
rect = rectMap.get(this.index)
} else {
//getBoundingClientRect
let offset = $(this.itemRefs[this.index]).offset()
rect.x = offset.left
rect.y = offset.top
rectMap.set(this.index, rect)
}
//
let center = this.getCenter(current1, current2) let center = this.getCenter(current1, current2)
console.log('center', center) center.x -= rect.x
center.y -= rect.y
// transform-origin: 50% 50% //ratioov[0]
// transform-origin: 30% 40%origin.x = (ratio - 1) * result.width * 0.3 let zoom = ratio / ov[0]
// origin.y = (ratio - 1) * result.height * 0.4 const x = center.x * (1 - zoom);
// 使transformtransform-origin const y = center.y * (1 - zoom);
// origin(ratio - 1) * result.width * 0 = 0 const t = new Float32Array([zoom, 0, 0, 0, 0, zoom, 0, 0, 0, 0, 1, 0, x, y, 0, 1,]);
const origin = { //zoomx
x: (ratio - 1) * this.result.width * 0.5, //zoom0.15ov
y: (ratio - 1) * this.result.height * 0.5 ov = mat4.multiply(out, t, ov);
};
// () let dRatio = this.last.ratio - ratio
this.x -= (ratio - 1) * (center.x - this.x) - origin.x - (center.x - this.lastCenter.x); //0.02
this.y -= (ratio - 1) * (center.y - this.y) - origin.y - (center.y - this.lastCenter.y); if (Math.abs(dRatio) <= 0.02) {
let movementX = current1.x - this.last.point1.x
// console.log('this.x', this.x) let movementY = current1.y - this.last.point1.y
// console.log('this.y', this.y) let movement2X = current2.x - this.last.point2.x
let movement2Y = current2.y - this.last.point2.y
//
this.itemRefs[this.index].style.transform = let minX = Math.min(movementX, movement2X)
`translate3d(${this.x}px,${this.y}px,0) scale(${this.store.scale * ratio})`; let minY = Math.min(movementY, movement2Y)
const t1 = new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, minX, minY, 0, 1,]);
this.lastCenter = {x: center.x, y: center.y}; ov = mat4.multiply(out, t1, ov);
this.lastPoint1 = {x: current1.x, y: current1.y}; }
this.lastPoint2 = {x: current2.x, y: current2.y};
this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
this.last.point1 = current1
this.last.point2 = current2
this.last.ratio = ratio
}
} }
}, },
end(e) { touchend(e) {
console.log('end',e.touches) console.log('end', e.touches.length, this.isTwo)
if (this.isTwo && e.touches.length === 1) {
Utils.$stopPropagation(e)
//
this.last.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
} else {
if (this.isTwo) { if (this.isTwo) {
this.store.scale = 1 Utils.$stopPropagation(e)
ov = original
this.itemRefs[this.index].style['transition-duration'] = '300ms'; this.itemRefs[this.index].style['transition-duration'] = '300ms';
this.itemRefs[this.index].style.transform = `translate3d(0,0,0) scale(1)`; this.itemRefs[this.index].style.transform = `matrix3d(${ov.toString()})`;
if (this.state !== 'custom') { // if (this.state !== 'custom') {
this.state = 'play' // this.state = 'play'
} // }
if (e.touches.length){ // if (e.touches.length) {
this.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY} // this.point1 = {x: e.touches[0].pageX, y: e.touches[0].pageY}
} // }
} else { } else {
if (this.index === 0 && !this.isDrawRight) return if (!this.canNext(this.isNext)) return
if (this.index === this.modelValue.imgs.length - 1 && this.isDrawRight) return Utils.$stopPropagation(e)
let canSlide = this.width / 5 < Math.abs(this.moveX); let canSlide = this.wrapper.width / 5 < Math.abs(this.move.x);
if (Date.now() - this.startTime < 40) canSlide = false if (Date.now() - this.start.time < 40) canSlide = false
if (canSlide) { if (canSlide) {
if (this.isDrawRight) { if (this.isNext) {
this.index += 1 this.index += 1
} else { } else {
this.index -= 1 this.index -= 1
@ -329,13 +356,16 @@ export default {
this.state = 'play' this.state = 'play'
} }
} }
globalMethods.$setCss(this.$refs.list, 'transition-duration', `300ms`) Utils.$setCss(this.$refs.list, 'transition-duration', `300ms`)
globalMethods.$setCss(this.$refs.list, 'transform', Utils.$setCss(this.$refs.list, 'transform', `translate3d(${this.getSlideDistance()}px, 0px, 0px)`)
`translate3d(${-this.getWidth(this.index)}px, 0px, 0px)`)
} }
}
},
canNext(isNext) {
return !((this.index === 0 && !isNext) || (this.index === this.modelValue.imgs.length - 1 && isNext));
}, },
getWidth(index) { getSlideDistance() {
return index * this.width return -this.index * this.wrapper.width
}, },
setItemRef(el) { setItemRef(el) {
if (el) { if (el) {
@ -374,76 +404,60 @@ html {
position: relative; position: relative;
background: black; background: black;
width: 100%; width: 100%;
//height: 100%; height: 100%;
height: calc(100vh - 5rem); overflow: hidden;
overflow: auto;
color: white; color: white;
font-size: 1.4rem; font-size: 14rem;
display: flex;
align-items: center;
justify-content: center;
.img-slide-wrapper { .img-slide-wrapper {
width: 100vw; height: 100%;
overflow: hidden; width: 100%;
.img-slide-list { .img-slide-list {
width: 100vw; height: 100%;
width: 100%;
display: flex; display: flex;
position: relative;
.img-slide-item { .img-slide-item {
min-width: 100vw; height: 100%;
width: 100%;
flex-shrink: 0;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
img { img {
//transform-origin: left top; transform-origin: 0 0;
width: 100vw; width: 100%;
//position: absolute;
//height: 100%;
} }
} }
} }
} }
.content {
width: 100vw;
.base-slide-item {
display: flex;
align-items: center;
justify-content: center;
}
img {
width: 100vw;
}
}
.progress-bar { .progress-bar {
position: absolute; position: absolute;
width: 100vw; width: 100%;
bottom: 0; bottom: 0;
display: flex; display: flex;
box-sizing: border-box; box-sizing: border-box;
padding: 0 .5rem; padding: 0 5rem;
justify-content: space-between; justify-content: space-between;
.bar { .bar {
border-radius: 1rem; border-radius: 10rem;
flex: 1; flex: 1;
margin: 0 .2rem; margin: 0 2rem;
height: .2rem; height: 2rem;
background: gray; background: gray;
position: relative; position: relative;
.progress { .progress {
border-radius: 1rem; border-radius: 10rem;
position: absolute; position: absolute;
left: 0; left: 0;
height: .2rem; height: 2rem;
background: white; background: white;
//width: 100%; //width: 100%;
//animation: start 3s linear; //animation: start 3s linear;

2
src/pages/slideHooks/H.vue

@ -47,7 +47,7 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, SlideType.HORIZONTAL) slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext,null, SlideType.HORIZONTAL)
} }
function touchEnd(e) { function touchEnd(e) {

4
src/pages/slideHooks/SlideItem.vue

@ -1,5 +1,5 @@
<template> <template>
<div class="slide-item"> <div class="slide-item2">
<slot></slot> <slot></slot>
</div> </div>
</template> </template>
@ -8,7 +8,7 @@
</script> </script>
<style scoped lang="less"> <style scoped lang="less">
.slide-item { .slide-item2 {
height: 100%; height: 100%;
width: 100%; width: 100%;
flex-shrink: 0; flex-shrink: 0;

8
src/pages/slideHooks/V.vue

@ -1,5 +1,5 @@
<script setup> <script setup>
import {onMounted, reactive, ref,watch} from "vue"; import {onMounted, reactive, ref, watch} from "vue";
import GM from '../../utils' import GM from '../../utils'
import {getSlideDistance, slideInit, slideReset, slideTouchEnd, slideTouchMove, slideTouchStart} from "./common"; import {getSlideDistance, slideInit, slideReset, slideTouchEnd, slideTouchMove, slideTouchStart} from "./common";
import {SlideType} from "../../utils/const_var"; import {SlideType} from "../../utils/const_var";
@ -46,13 +46,11 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, SlideType.VERTICAL) slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext,null, SlideType.VERTICAL)
} }
function touchEnd(e) { function touchEnd(e) {
slideTouchEnd(e, state, canNext, () => { slideTouchEnd(e, state, canNext, null, null, SlideType.VERTICAL)
}, SlideType.VERTICAL)
slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit) slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit)
} }

4
src/pages/slideHooks/VInfinite.vue

@ -124,13 +124,13 @@ function touchStart(e) {
} }
function touchMove(e) { function touchMove(e) {
slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext, SlideType.VERTICAL) slideTouchMove(e, wrapperEl.value, state, judgeValue, canNext,null, SlideType.VERTICAL)
} }
function touchEnd(e) { function touchEnd(e) {
slideTouchEnd(e, state, canNext, () => { slideTouchEnd(e, state, canNext, () => {
}, SlideType.VERTICAL) },null, SlideType.VERTICAL)
slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit) slideReset(wrapperEl.value, state, SlideType.VERTICAL, emit)
} }

12
src/pages/slideHooks/common.js

@ -36,15 +36,16 @@ export function canSlide(state, judgeValue, type = SlideType.HORIZONTAL) {
return state.next return state.next
} }
export function slideTouchMove(e, el, state, judgeValue, cb, type = SlideType.HORIZONTAL) { export function slideTouchMove(e, el, state, judgeValue, canNextCb, nextCb, type = SlideType.HORIZONTAL) {
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 (!cb?.(isNext)) return if (!canNextCb?.(isNext)) return
if (canSlide(state, judgeValue, type)) { if (canSlide(state, judgeValue, type)) {
nextCb?.()
bus.emit(state.name + '-moveX', state.move.x) bus.emit(state.name + '-moveX', state.move.x)
Utils.$stopPropagation(e) Utils.$stopPropagation(e)
let t = getSlideDistance(state, type) + (isNext ? judgeValue : -judgeValue) let t = getSlideDistance(state, type) + (isNext ? judgeValue : -judgeValue)
@ -55,11 +56,12 @@ export function slideTouchMove(e, el, state, judgeValue, cb, type = SlideType.HO
} else { } else {
dx2 = t + state.move.y dx2 = t + state.move.y
} }
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)`)
} }
} }
export function slideTouchEnd(e, state, canNextCb, nextCb, type = SlideType.HORIZONTAL) { export function slideTouchEnd(e, state, canNextCb, nextCb, notNextCb, type = SlideType.HORIZONTAL) {
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
@ -79,6 +81,8 @@ export function slideTouchEnd(e, state, canNextCb, nextCb, type = SlideType.HORI
state.localIndex-- state.localIndex--
} }
nextCb?.() nextCb?.()
} else {
notNextCb?.()
} }
} }
} }
@ -97,7 +101,7 @@ export function slideReset(el, state, type, emit) {
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
emit('update:index', state.localIndex) emit?.('update:index', state.localIndex)
bus.emit(state.name + '-end', state.localIndex) bus.emit(state.name + '-end', state.localIndex)
} }

26
src/pages/slideHooks/index.vue

@ -1,24 +1,24 @@
<template> <template>
<div class="test-slide-wrapper"> <div class="test-slide-wrapper">
<H v-model:index="state.baseIndex"> <H v-model:index="state.baseIndex">
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<H class="h" v-model:index="state.navIndex"> <H class="h" v-model:index="state.navIndex">
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big">找红包</div> <div class="big">找红包</div>
</SlideItem> </SlideItem>
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big">热点</div> <div class="big">热点</div>
</SlideItem> </SlideItem>
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big">社区</div> <div class="big">社区</div>
</SlideItem> </SlideItem>
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big">关注</div> <div class="big">关注</div>
</SlideItem> </SlideItem>
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big">商城</div> <div class="big">商城</div>
</SlideItem> </SlideItem>
<SlideItem class="slide-item"> <SlideItem class="">
<VInfinite <VInfinite
v-model:index="state.index" v-model:index="state.index"
:render="render" :render="render"
@ -40,7 +40,7 @@
</div> </div>
<Footer v-bind:init-tab="1"/> <Footer v-bind:init-tab="1"/>
</SlideItem> </SlideItem>
<SlideItem class="slide-item gray"> <SlideItem class=" gray">
<div class="big" v-for="i in 100">主页</div> <div class="big" v-for="i in 100">主页</div>
</SlideItem> </SlideItem>
</H> </H>
@ -63,10 +63,10 @@ const state = reactive({
navIndex: 5, navIndex: 5,
index: 0, index: 0,
recommendVideos: [ recommendVideos: [
{ // {
type: 'img', // type: 'img',
src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` // src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
}, // },
{ {
type: 'imgs', type: 'imgs',
src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}` src: `http://douyin.ttentau.top/0.mp4?vframe/jpg/offset/0/w/${document.body.clientWidth}`
@ -85,7 +85,7 @@ function render(item, itemIndex, play) {
node = <SlideImgs/> node = <SlideImgs/>
} }
return node return node
// return <SlideItem class="slide-item gray">{node}</SlideItem> // return <SlideItem class=" gray">{node}</SlideItem>
} }
// function render1(item, itemIndex, play) { // function render1(item, itemIndex, play) {

14
src/pages/test/Test.vue

@ -1,9 +1,9 @@
<template> <template>
<!-- <TestSlide></TestSlide>--> <!-- <TestSlide></TestSlide>-->
<!-- <SlideUser></SlideUser>--> <!-- <SlideUser></SlideUser>-->
<SlideImgs></SlideImgs> <!-- <SlideImgs></SlideImgs>-->
<!-- <TestImg/>--> <!-- <TestImg/>-->
<!-- <slideHooks></slideHooks>--> <slideHooks></slideHooks>
<!-- <div class="body">--> <!-- <div class="body">-->
<!-- <div class="wrapper">--> <!-- <div class="wrapper">-->
@ -46,7 +46,7 @@ export default {
} }
} }
</script> </script>
<style lang="less"> <style scoped lang="less">
.body { .body {
display: flex; display: flex;
align-items: center; align-items: center;
@ -63,10 +63,4 @@ export default {
background: black; background: black;
overflow: hidden; overflow: hidden;
} }
img {
transform-origin: 0 0;
max-width: 1040px;
max-height: 600px;
}
</style> </style>

11
src/utils/index.jsx

@ -353,7 +353,7 @@ export default {
} }
return str return str
}, },
$randomNum(minNum, maxNum) { randomNum(minNum, maxNum) {
switch (arguments.length) { switch (arguments.length) {
case 1: case 1:
return parseInt(Math.random() * minNum + 1, 10); return parseInt(Math.random() * minNum + 1, 10);
@ -363,4 +363,13 @@ export default {
return 0; return 0;
} }
}, },
getCenter(a, b) {
const x = (a.x + b.x) / 2;
const y = (a.y + b.y) / 2;
return {x, y}
},
//
getDistance(start, stop) {
return Math.hypot(stop.x - start.x, stop.y - start.y);
},
} }

Loading…
Cancel
Save