|
|
@@ -1,33 +1,177 @@
|
|
|
<template>
|
|
|
- <div class="layout" style="width: 80%; height: 80%">
|
|
|
- <slide :items="items">
|
|
|
- <div slot="item" slot-scope="{data}" class="item" @click="clickHandle(data)">
|
|
|
- {{1}}
|
|
|
+ <div class="coll-layout" ref="layout">
|
|
|
+ <div class="coll-content" ref="content"
|
|
|
+ :style="{transform: 'translateX(' + contentLeft + 'px)', width: maxWidth + 'px'}"
|
|
|
+ :class="{animation: !pauseAnimation}"
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ v-for="(item, i) in items"
|
|
|
+ :key="i"
|
|
|
+ @click="clickHandle($event, item)"
|
|
|
+ :style="{width: itemWidth + 'px', marginRight: itemRight + 'px'}">
|
|
|
+ <img :src="item.abbr">
|
|
|
</div>
|
|
|
- </slide>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <img class="definition">
|
|
|
+ <img class="definition">
|
|
|
+
|
|
|
+ <h3 class="title">{{active.title}}</h3>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
import slide from '@/components/slide'
|
|
|
|
|
|
+function loadTouch (start, move, end) {
|
|
|
+ let startHandle = (ev) => {
|
|
|
+ start()
|
|
|
+ let startX = ev.touches[0].pageX
|
|
|
+ let moveHandle = (ev) => {
|
|
|
+ ev.stopPropagation()
|
|
|
+ ev.preventDefault()
|
|
|
+
|
|
|
+ move(ev.touches[0].pageX - startX)
|
|
|
+ }
|
|
|
+
|
|
|
+ let endHandle = () => {
|
|
|
+ ev.stopPropagation()
|
|
|
+ ev.preventDefault()
|
|
|
+
|
|
|
+ end()
|
|
|
+ document.documentElement.removeEventListener('touchmove', moveHandle, {passive: false})
|
|
|
+ document.documentElement.removeEventListener('touchend', endHandle, {passive: false})
|
|
|
+ }
|
|
|
+
|
|
|
+ document.documentElement.addEventListener('touchmove', moveHandle, {passive: false})
|
|
|
+ document.documentElement.addEventListener('touchend', endHandle, {passive: false})
|
|
|
+ }
|
|
|
+
|
|
|
+ return startHandle
|
|
|
+}
|
|
|
+
|
|
|
+function getPoint (dom, targetDom) {
|
|
|
+ let x = 0
|
|
|
+ let y = 0
|
|
|
+
|
|
|
+ while (dom !== targetDom && dom !== document.documentElement) {
|
|
|
+ x += dom.offsetLeft
|
|
|
+ y += dom.offsetTop
|
|
|
+ dom = dom.offsetParent
|
|
|
+ }
|
|
|
+ return { x, y }
|
|
|
+}
|
|
|
+
|
|
|
export default {
|
|
|
name: 'collection',
|
|
|
data () {
|
|
|
+ let items = [
|
|
|
+ {
|
|
|
+ title: '牧童归家1',
|
|
|
+ abbr: require('@/assets/images/coll_abbr_1.png'),
|
|
|
+ image: require('@/assets/images/coll_relic_1.png')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '牧童归家2',
|
|
|
+ abbr: require('@/assets/images/coll_abbr_2.png'),
|
|
|
+ image: require('@/assets/images/coll_relic_2.png')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '牧童归家3',
|
|
|
+ abbr: require('@/assets/images/coll_abbr_3.png'),
|
|
|
+ image: require('@/assets/images/coll_relic_3.png')
|
|
|
+ },
|
|
|
+ {
|
|
|
+ title: '牧童归家4',
|
|
|
+ abbr: require('@/assets/images/coll_abbr_4.png'),
|
|
|
+ image: require('@/assets/images/coll_relic_4.png')
|
|
|
+ }
|
|
|
+ ]
|
|
|
+
|
|
|
return {
|
|
|
- items: [1, 2, 3]
|
|
|
+ screenW: window.outerWidth,
|
|
|
+ contentLeft: 0,
|
|
|
+ items,
|
|
|
+ active: items[0],
|
|
|
+ pauseAnimation: false
|
|
|
}
|
|
|
},
|
|
|
methods: {
|
|
|
- clickHandle () {
|
|
|
+ async clickHandle (ev, item) {
|
|
|
+ this.active = item
|
|
|
+
|
|
|
+ let result = getPoint(ev.target, this.$refs.layout)
|
|
|
+ let $old = document.querySelector('.definition:not(.active)')
|
|
|
+ let $active = document.querySelector('.definition.active')
|
|
|
+
|
|
|
+ if ($active) {
|
|
|
+ $active.classList.remove('active')
|
|
|
+ setTimeout(() => {
|
|
|
+ $active.classList.remove('animation')
|
|
|
+ }, 300)
|
|
|
+ }
|
|
|
+
|
|
|
+ $old.style.left = result.x + this.contentLeft + 'px'
|
|
|
+ $old.style.top = result.y + 'px'
|
|
|
+ $old.style.width = this.itemWidth + 'px'
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ $old.classList.add('animation')
|
|
|
+ $old.classList.add('active')
|
|
|
+ $old.setAttribute('src', this.active.image)
|
|
|
+ }, 10)
|
|
|
}
|
|
|
},
|
|
|
+ computed: {
|
|
|
+ itemWidth () {
|
|
|
+ return this.screenW * 0.266
|
|
|
+ },
|
|
|
+ itemRight () {
|
|
|
+ return this.screenW * 0.058
|
|
|
+ },
|
|
|
+ maxWidth () {
|
|
|
+ return (this.itemWidth + this.itemRight) * this.items.length
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted () {
|
|
|
+ let $content = this.$refs.content
|
|
|
+ let screenW = window.outerWidth
|
|
|
+
|
|
|
+ this.startHandle = loadTouch(
|
|
|
+ () => {
|
|
|
+ this.pauseAnimation = true
|
|
|
+ this.startX = this.contentLeft
|
|
|
+ },
|
|
|
+ (x) => {
|
|
|
+ this.contentLeft = this.startX + x
|
|
|
+ },
|
|
|
+ () => {
|
|
|
+ this.pauseAnimation = false
|
|
|
+
|
|
|
+ let mxWidth = $content.offsetWidth
|
|
|
+ let left = -this.contentLeft
|
|
|
+
|
|
|
+ let syncLeft = left > mxWidth - screenW
|
|
|
+ ? mxWidth - screenW : left < 0
|
|
|
+ ? 0 : null
|
|
|
+
|
|
|
+ if (syncLeft !== null) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.contentLeft = -syncLeft
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ $content.addEventListener('touchstart', this.startHandle, false)
|
|
|
+ },
|
|
|
+ beforeDestroy () {
|
|
|
+ this.$refs.content.removeEventListener('touchstart', this.startHandle, false)
|
|
|
+ },
|
|
|
components: {slide}
|
|
|
}
|
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
|
-.item {
|
|
|
- background-color: #fff;
|
|
|
-}
|
|
|
+@import url('./style.css');
|
|
|
</style>
|