@ -1,12 +1,12 @@
@@ -1,12 +1,12 @@
< template >
< div id = "SlideImgs" >
< div class = "img-slide-wrapper" ref = "wap" >
< div class = "img-slide-wrapper" >
< div class = "img-slide-list"
ref = "list "
@ touchstart = "touchs tart"
@ touchmove = "touchm ove"
@ touchend = "touche nd" >
< div class = "img-slide-item" v-for ="img in modelValue.imgs" >
ref = "wrapperE l"
@ touchstart = "touchS tart"
@ touchmove = "touchM ove"
@ touchend = "touchE nd" >
< div class = "img-slide-item" v-for ="img in props. modelValue.imgs" >
< img :ref ="setItemRef" :src ="img" >
< / div >
< / div >
@ -20,11 +20,20 @@
@@ -20,11 +20,20 @@
< / div >
< / template >
< script >
< script setup lang = "jsx" >
import enums from "../../utils/enums" ;
import globalMethod s from '../../utils'
import Util s from '../../utils'
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 ( [
0 , 0 , 0 , 0 ,
@ -38,426 +47,291 @@ let ov = new Float32Array([
@@ -38,426 +47,291 @@ let ov = new Float32Array([
0 , 0 , 1 , 0 ,
0 , 0 , 0 , 1 ,
] ) ;
let original = cloneDeep ( ov )
const rectMap = new Map ( )
export default {
name : "SlideImgs" ,
components : { } ,
props : {
modelValue : {
type : Object ,
default ( ) {
return {
type : 'imgs' ,
imgs : [
new URL ( '../../assets/img/poster/0.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/1.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/2.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/3.jpg' , import . meta . url ) . href ,
] ,
"id" : "034ae83b-ca0a-401a-b7c6-cf78361bae7b" ,
video : 'http://douyin.ttentau.top/0.mp4' ,
"video_data_size" : 26829508 ,
"duration" : 427780 ,
"desc" : "我不管我们宿舍第一好看" ,
"allow_download" : 0 ,
"allow_duet" : 0 ,
"allow_react" : 0 ,
"allow_music" : 1 ,
"allow_douplus" : 1 ,
"allow_share" : 1 ,
"digg_count" : 10480000 ,
"comment_count" : 79000 ,
"download_count" : 6 ,
"play_count" : 0 ,
"share_count" : 119000 ,
"forward_count" : 0 ,
"collect_count" : 3 ,
"sort" : 195 ,
"is_top" : 0 ,
"city" : "北京" ,
address : '中央戏剧学院' ,
"musicId" : "2ee213c6-3e3f-4758-ba5a-7f1c955604a4" ,
"create_time" : "1630423555" ,
"creator_id" : "93864497380" ,
"status" : 1 ,
"topics" : [
{
"id" : "85ceda30-898f-4b57-b891-0e58b3ab99a9" ,
"name" : "敬礼变装" ,
"creator_id" : "93864497380" ,
"create_time" : "1630423555" ,
"status" : 1
} ,
{
"id" : "85ceda30-898f-4b57-b891-0e58b3ab99a9" ,
"name" : "宿舍" ,
"creator_id" : "93864497380" ,
"create_time" : "1630423555" ,
"status" : 1
}
] ,
"music" : {
"id" : "cde50af2-628c-4d28-b9c6-67237a62518e" ,
"cover" : "https://p29.douyinpic.com/img/tos-cn-avt-0015/f4de202ff2e41b523838a4a767aebd16~c5_100x100.jpeg?from=116350172" ,
"mp3" : "https://sf3-cdn-tos.douyinstatic.com/obj/ies-music/1658584661080088.mp3" ,
"title" : "@穷电影创作的原声-小高快起来跳舞" ,
const props = defineProps ( {
modelValue : {
type : Object ,
default ( ) {
return {
type : 'imgs' ,
imgs : [
new URL ( '../../assets/img/poster/0.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/1.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/2.jpg' , import . meta . url ) . href ,
new URL ( '../../assets/img/poster/3.jpg' , import . meta . url ) . href ,
] ,
"id" : "034ae83b-ca0a-401a-b7c6-cf78361bae7b" ,
video : 'http://douyin.ttentau.top/0.mp4' ,
"video_data_size" : 26829508 ,
"duration" : 427780 ,
"desc" : "我不管我们宿舍第一好看" ,
"allow_download" : 0 ,
"allow_duet" : 0 ,
"allow_react" : 0 ,
"allow_music" : 1 ,
"allow_douplus" : 1 ,
"allow_share" : 1 ,
"digg_count" : 10480000 ,
"comment_count" : 79000 ,
"download_count" : 6 ,
"play_count" : 0 ,
"share_count" : 119000 ,
"forward_count" : 0 ,
"collect_count" : 3 ,
"sort" : 195 ,
"is_top" : 0 ,
"city" : "北京" ,
address : '中央戏剧学院' ,
"musicId" : "2ee213c6-3e3f-4758-ba5a-7f1c955604a4" ,
"create_time" : "1630423555" ,
"creator_id" : "93864497380" ,
"status" : 1 ,
"topics" : [
{
"id" : "85ceda30-898f-4b57-b891-0e58b3ab99a9" ,
"name" : "敬礼变装" ,
"creator_id" : "93864497380" ,
"create_time" : "1630423555" ,
"status" : 1
} ,
"author" : {
"id" : "1" ,
"unique_id_modify_time" : "1630393144" ,
"unique_id" : "10040050" ,
"favoriting_count" : 143 ,
"avatar" : new URL ( '../../assets/img/icon/avatar/3.png' , import . meta . url ) . href ,
school : {
name : '中央戏剧学院' ,
department : null ,
joinTime : null ,
education : null ,
displayType : enums . DISPLAY _TYPE . ALL ,
} ,
"city" : "" ,
"province" : '北京' ,
"country" : "" ,
"location" : "" ,
"birthday" : "2002-01-01" ,
"cover" : "https://p3.douyinpic.com/obj/c8510002be9a3a61aad2?from=116350172" ,
"following_count" : 66 ,
"follower_count" : 235000 ,
"aweme_count" : 1796000 ,
"nickname" : "我是小睿耶" ,
certification : '' ,
"phone" : "" ,
"sex" : "" ,
"last_login_time" : "1630423555" ,
{
"id" : "85ceda30-898f-4b57-b891-0e58b3ab99a9" ,
"name" : "宿舍" ,
"creator_id" : "93864497380" ,
"create_time" : "1630423555" ,
"status" : 1 ,
"desc" : ` 一个普普通通学表演的 \ n看到的人都能开开心心 ` ,
"is_private" : 0
"status" : 1
}
] ,
"music" : {
"id" : "cde50af2-628c-4d28-b9c6-67237a62518e" ,
"cover" : "https://p29.douyinpic.com/img/tos-cn-avt-0015/f4de202ff2e41b523838a4a767aebd16~c5_100x100.jpeg?from=116350172" ,
"mp3" : "https://sf3-cdn-tos.douyinstatic.com/obj/ies-music/1658584661080088.mp3" ,
"title" : "@穷电影创作的原声-小高快起来跳舞" ,
"creator_id" : "93864497380" ,
"create_time" : "1630423555" ,
"status" : 1
} ,
"author" : {
"id" : "1" ,
"unique_id_modify_time" : "1630393144" ,
"unique_id" : "10040050" ,
"favoriting_count" : 143 ,
"avatar" : new URL ( '../../assets/img/icon/avatar/3.png' , import . meta . url ) . href ,
school : {
name : '中央戏剧学院' ,
department : null ,
joinTime : null ,
education : null ,
displayType : enums . DISPLAY _TYPE . ALL ,
} ,
"city" : "" ,
"province" : '北京' ,
"country" : "" ,
"location" : "" ,
"birthday" : "2002-01-01" ,
"cover" : "https://p3.douyinpic.com/obj/c8510002be9a3a61aad2?from=116350172" ,
"following_count" : 66 ,
"follower_count" : 235000 ,
"aweme_count" : 1796000 ,
"nickname" : "我是小睿耶" ,
certification : '' ,
"phone" : "" ,
"sex" : "" ,
"last_login_time" : "1630423555" ,
"create_time" : "1630423555" ,
"status" : 1 ,
"desc" : ` 一个普普通通学表演的 \ n看到的人都能开开心心 ` ,
"is_private" : 0
}
}
}
}
} )
const judgeValue = 20
const wrapperEl = ref ( null )
const state = reactive ( {
name : 'SlideHorizontal' ,
localIndex : 0 ,
needCheck : true ,
isTwo : true ,
next : false ,
wrapper : { width : 0 , height : 0 , childrenLength : 0 } ,
last : {
point1 : { x : 0 , y : 0 } ,
point2 : { x : 0 , y : 0 } ,
} ,
data ( ) {
return {
itemRefs : [ ] ,
baseActiveIndex : 0 ,
progress : 0 ,
cycleFn : null ,
state : 'play' , / / s t o p , c u s t o m
startX : 0 ,
startY : 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 : {
ratio : 1 ,
point1 : { x : 0 , y : 0 } ,
point2 : { x : 0 , y : 0 } ,
} ,
start : {
point1 : { x : 0 , y : 0 } ,
point2 : { x : 0 , y : 0 } ,
}
}
} ,
created ( ) {
this . width = document . body . clientWidth
} ,
watch : {
state ( newVal , oldVal ) {
return
console . log ( 'newVal' , newVal )
if ( newVal === 'play' ) requestAnimationFrame ( this . cycleFn )
if ( newVal === 'stop' ) cancelAnimationFrame ( this . cycleFn )
if ( newVal === 'custom' ) cancelAnimationFrame ( this . cycleFn )
}
start : {
x : 0 , y : 0 ,
point1 : { x : 0 , y : 0 } ,
point2 : { x : 0 , y : 0 } ,
center : { x : 0 , y : 0 } ,
time : 0
} ,
mounted ( ) {
this . cycleFn = ( ) => {
if ( this . state !== 'play' ) return cancelAnimationFrame ( this . cycleFn )
if ( this . progress < this . modelValue . imgs . length * 100 ) {
this . progress += .4
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 {
this . progress = 0
/ / c a n c e l A n i m a t i o n F r a m e ( t h i s . c y c l e F n )
move : { x : 0 , y : 0 } ,
itemRefs : [ ] ,
status : 'play' , / / s t o p , c u s t o m
progress : 0 ,
cycleFn : null ,
} )
onMounted ( ( ) => {
slideInit ( wrapperEl . value , state , SlideType . HORIZONTAL )
state . cycleFn = ( ) => {
if ( state . status !== 'play' ) return cancelAnimationFrame ( state . cycleFn )
if ( state . progress < props . modelValue . imgs . length * 100 ) {
state . progress += .4
state . localIndex = parseInt ( state . progress / 100 )
if ( wrapperEl . value ) {
Utils . $setCss ( wrapperEl . value , 'transition-duration' , ` 300ms ` )
Utils . $setCss ( wrapperEl . value , 'transform' , ` translate3d( ${ getSlideDistance ( state ) } px, 0px, 0px) ` )
}
requestAnimationFrame ( this . cycleFn )
} else {
state . progress = 0
/ / c a n c e l A n i m a t i o n F r a m e ( t h i s . c y c l e F n )
}
return
/ / r e q u e s t A n i m a t i o n F r a m e ( t h i s . c y c l e F n )
let x = 0
let y = 0
let scale = 1
requestAnimationFrame ( state . cycleFn )
}
requestAnimationFrame ( state . cycleFn )
} )
function touchStart ( e ) {
console . log ( 'start' , e . touches . length )
/ / i f ( s . s t a t e ! = = ' c u s t o m ' ) {
/ / t h i s . s t a t e = ' s t o p '
/ / }
if ( e . touches . length === 1 ) {
state . isTwo = false
slideTouchStart ( e , wrapperEl . value , state )
} else {
if ( state . isTwo ) return
state . isTwo = true
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 . point2 = state . start . point2 = { x : e . touches [ 1 ] . pageX , y : e . touches [ 1 ] . pageY } ;
state . start . center = Utils . getCenter ( state . start . point1 , state . start . point2 )
}
}
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' ;
function touchMove ( e ) {
/ / c o n s o l e . l o g ( ' m o v e ' , e . t o u c h e s . l e n g t h )
if ( state . isTwo && e . touches . length === 1 ) {
state . status = 'pause'
Utils . $stopPropagation ( e )
/ / c o n s o l e . l o g ( ' 单 手 移 动 ' , )
let current = { x : e . touches [ 0 ] . pageX , y : e . touches [ 0 ] . pageY }
let movementX = current . x - state . last . point1 . x
let movementY = current . y - state . last . point1 . y
/ / c o n s o l e . l o g ( m o v e m e n t X , m o v e m e n t Y )
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 ) ;
state . itemRefs [ state . localIndex ] . style . transform = ` matrix3d( ${ ov . toString ( ) } ) ` ;
state . last . point1 = current
} else {
if ( e . touches . length === 1 ) {
state . isTwo = false
slideTouchMove ( e , wrapperEl . value , state , judgeValue , canNext , ( ) => {
state . status = 'pause'
} , SlideType . HORIZONTAL )
} else {
state . isTwo = true
Utils . $stopPropagation ( e )
state . status = 'pause'
let { clientX , clientY , deltaY } = e ;
let rect = { x : 0 , y : 0 }
if ( tt . has ( this . index ) ) {
rect = tt . get ( this . index )
if ( rectMap . has ( state . localI ndex) ) {
rect = rectMap . get ( state . localI ndex)
} 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 ( ) } ) ` ;
/ / i m a g e . s e t A t t r i b u t e ( " s t y l e " , ` t r a n s f o r m : m a t r i x 3 d ( $ { o v . t o S t r i n g ( ) } ) ; ` ) ;
} )
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 )
if ( this . state !== 'custom' ) {
this . state = 'stop'
/ / g e t B o u n d i n g C l i e n t R e c t 在 手 机 上 获 取 不 到 值
let offset = $ ( state . itemRefs [ state . localIndex ] ) . offset ( )
rect = { x : offset . left , y : offset . top }
rectMap . set ( state . localIndex , rect )
}
if ( e . touches . length === 1 ) {
this . isTwo = false
globalMethods . $setCss ( this . $refs . list , 'transition-duration' , ` 0ms ` )
this . startX = e . touches [ 0 ] . pageX
this . startY = e . touches [ 0 ] . pageY
this . startTime = Date . now ( )
} else {
if ( this . isTwo ) return
this . isTwo = true
this . itemRefs [ this . index ] . style [ 'transition-duration' ] = '0ms' ;
if ( e . cancelable ) {
e . preventDefault ( ) ;
}
let current1 = { x : e . touches [ 0 ] . pageX , y : e . touches [ 0 ] . pageY }
let current2 = { x : e . touches [ 1 ] . pageX , y : e . touches [ 1 ] . pageY }
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 ) {
/ / c o n s o l e . l o g ( ' 单 手 移 动 ' , )
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 , ] ) ;
let ov1 = mat4 . multiply ( out , t , ov ) ;
this . itemRefs [ this . index ] . style . transform = ` matrix3d( ${ ov1 . toString ( ) } ) ` ;
/ / t h i s . l a s t . p o i n t 1 = c u r r e n t
} else {
if ( e . touches . length === 1 ) {
this . isTwo = false
/ / 双 指 缩 放 比 例 , 就 是 对 应 的 放 大 倍 数
let currentRatio = Utils . getDistance ( current1 , current2 ) / Utils . getDistance ( state . start . point1 , state . start . point2 ) ;
this . moveX = e . touches [ 0 ] . pageX - this . startX
this . moveY = e . touches [ 0 ] . pageY - this . startY
let center = Utils . getCenter ( current1 , current2 )
this . isDrawRight = this . moveX < 0
this . isDrawDown = this . moveY < 0
center . x -= rect . x
center . y -= rect . y
/ / 用 最 新 的 放 大 倍 数 r a t i o 除 以 之 前 的 放 大 o v [ 0 ] 倍 数 , 算 出 本 次 要 累 加 放 大 的 倍 数
let zoom = currentRatio / ov [ 0 ]
const x = center . x * ( 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 , ] ) ;
/ / 如 果 z o o m 是 每 次 都 是 最 后 放 大 倍 数 , 第 三 个 参 数 用 原 值 ( 即 , 矩 阵 x 乘 时 , 都 是 乘 以 单 位 矩 阵 )
/ / 如 果 z o o m 是 累 加 放 大 ( 比 如 每 次 都 是 0 . 1 5 ) , 第 三 个 参 数 用 o v 。 这 里 还 是 采 用 累 加 计 算
ov = mat4 . multiply ( out , t , ov ) ;
if ( this . index === 0 && ! this . isDrawRight ) return
if ( this . index === this . modelValue . imgs . length - 1 && this . isDrawRight ) return
let movementRatio = currentRatio - ov [ 0 ]
/ / 如 果 本 次 比 例 和 上 次 的 不 超 过 0 . 0 2 。 那 么 判 定 为 平 移
if ( Math . abs ( movementRatio ) <= 0.02 ) {
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 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 ) ;
}
globalMethods . $setCss ( this . $refs . list , 'transform' ,
` translate3d( ${ - this . getWidth ( this . index ) +
this . moveX } px , 0 px , 0 px ) ` )
} else {
this . isTwo = true
if ( e . cancelable ) {
e . preventDefault ( ) ;
}
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 ratio = this . getDistance ( current1 , current2 ) / this . getDistance ( this . point1 , this . point2 ) ;
let rect = { x : 0 , y : 0 }
if ( rectMap . has ( this . index ) ) {
rect = rectMap . get ( this . index )
} else {
/ / g e t B o u n d i n g C l i e n t R e c t 在 手 机 上 获 取 不 到 值
let offset = $ ( this . itemRefs [ this . index ] ) . offset ( )
rect . x = offset . left
rect . y = offset . top
rectMap . set ( this . index , rect )
}
state . itemRefs [ state . localIndex ] . style . transform = ` matrix3d( ${ ov . toString ( ) } ) ` ;
state . last . point1 = current1
state . last . point2 = current2
}
}
}
let center = cloneDeep ( this . startCenter )
center . x -= rect . x
center . y -= rect . y
let zoom = ratio
const x = center . x * ( 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 , ] ) ;
/ / 如 果 z o o m 是 累 加 放 大 ( 比 如 每 次 都 是 0 . 1 5 ) , 第 三 个 参 数 用 o v
/ / 但 这 里 z o o m 是 每 次 都 是 最 后 放 大 倍 数 , 第 三 个 参 数 用 原 值 ( 即 , 矩 阵 x 乘 时 , 都 是 乘 以 单 位 矩 阵 )
ov = mat4 . multiply ( out , t , original ) ;
let movementX = current1 . x - this . last . point1 . x
let movementY = current1 . y - this . last . point1 . y
let movement2X = current2 . x - this . last . point2 . x
let movement2Y = current2 . y - this . last . point2 . y
let minX = Math . min ( movementX , movement2X )
let minY = Math . min ( movementY , movement2Y )
console . log ( 'minX' , minX , 'minY' , minY )
this . itemRefs [ this . index ] . style . transform = ` matrix3d( ${ ov . toString ( ) } ) ` ;
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 ( ) } ) ` ;
/ / i f ( t h i s . s t a t e ! = = ' c u s t o m ' ) {
/ / t h i s . s t a t e = ' p l a y '
/ / }
/ / i f ( e . t o u c h e s . l e n g t h ) {
/ / t h i s . p o i n t 1 = { x : e . t o u c h e s [ 0 ] . p a g e X , y : e . t o u c h e s [ 0 ] . p a g e Y }
/ / }
} else {
if ( this . index === 0 && ! this . isDrawRight ) return
if ( this . index === this . modelValue . imgs . length - 1 && this . isDrawRight ) return
let canSlide = this . width / 5 < Math . abs ( this . moveX ) ;
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 {
if ( this . state !== 'custom' ) {
this . state = 'play'
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 {
if ( state . isTwo ) {
Utils . $stopPropagation ( e )
state . itemRefs [ state . localIndex ] . style [ 'transition-duration' ] = '300ms' ;
state . itemRefs [ state . localIndex ] . style . transform = ` matrix3d( ${ ov . toString ( ) } ) ` ;
} else {
slideTouchEnd ( e , state , canNext ,
( ) => {
state . status = 'custom'
state . progress = ( state . localIndex + 1 ) * 100
} ,
( ) => {
if ( state . status !== 'custom' ) {
state . status = 'play'
requestAnimationFrame ( state . cycleFn )
}
}
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 ) {
this . itemRefs . push ( el )
}
} ,
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 ) {
if ( this . progress >= ( index + 1 ) * 100 ) return { width : '100%' }
return { width : ` ${ this . progress - index * 100 < 0 ? 0 : this . progress - index * 100 } % ` }
)
slideReset ( wrapperEl . value , state , SlideType . HORIZONTAL , null )
}
}
}
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 >
< style scoped lang = "less" >
@ -469,14 +343,10 @@ html {
@@ -469,14 +343,10 @@ html {
position : relative ;
background : black ;
width : 100 % ;
/ / h e i g h t : 1 0 0 % ;
height : calc ( 100 vh - 50 rem ) ;
height : 100 % ;
overflow : hidden ;
color : white ;
font - size : 14 rem ;
display : flex ;
align - items : center ;
justify - content : center ;
. img - slide - wrapper {
height : 100 % ;
@ -498,30 +368,15 @@ html {
@@ -498,30 +368,15 @@ html {
img {
transform - origin : 0 0 ;
width : 100 vw ;
width : 100 % ;
}
}
}
}
. content {
width : 100 vw ;
. base - slide - item {
display : flex ;
align - items : center ;
justify - content : center ;
}
img {
width : 100 vw ;
}
}
. progress - bar {
position : absolute ;
width : 100 vw ;
width : 100 % ;
bottom : 0 ;
display : flex ;
box - sizing : border - box ;