|
@@ -11,23 +11,8 @@
|
|
@click="doTest"
|
|
@click="doTest"
|
|
>
|
|
>
|
|
<img
|
|
<img
|
|
- v-show="gearStatus==='idle'"
|
|
|
|
- class="gear gear-static-1"
|
|
|
|
- src="@/assets/images/gear-idle.png"
|
|
|
|
- alt=""
|
|
|
|
- draggable="false"
|
|
|
|
- >
|
|
|
|
- <img
|
|
|
|
- v-show="gearStatus==='clockwise'"
|
|
|
|
- class="gear gear-clockwise"
|
|
|
|
- src="@/assets/images/gear-clockwise.png"
|
|
|
|
- alt=""
|
|
|
|
- draggable="false"
|
|
|
|
- >
|
|
|
|
- <img
|
|
|
|
- v-show="gearStatus==='countercockwise'"
|
|
|
|
- class="gear gear-counterclockwise"
|
|
|
|
- src="@/assets/images/gear-counterclockwise.png"
|
|
|
|
|
|
+ class="gear"
|
|
|
|
+ :src="require(`@/assets/images/gear/表盘1_${gearFrameIdx.toString().padStart(5, '0')}.png`)"
|
|
alt=""
|
|
alt=""
|
|
draggable="false"
|
|
draggable="false"
|
|
>
|
|
>
|
|
@@ -35,28 +20,30 @@
|
|
<div
|
|
<div
|
|
class="time-axis-wrap"
|
|
class="time-axis-wrap"
|
|
:style="{
|
|
:style="{
|
|
- left: timeAxisLeft,
|
|
|
|
|
|
+ left: `${timeAxisLeft}px`,
|
|
}"
|
|
}"
|
|
>
|
|
>
|
|
- <img
|
|
|
|
- class="time-axis one"
|
|
|
|
- src="@/assets/images/time-axis.png"
|
|
|
|
- alt=""
|
|
|
|
- draggable="false"
|
|
|
|
- >
|
|
|
|
- <img
|
|
|
|
- class="time-axis two"
|
|
|
|
- src="@/assets/images/time-axis.png"
|
|
|
|
- alt=""
|
|
|
|
- draggable="false"
|
|
|
|
- >
|
|
|
|
|
|
+ <div
|
|
|
|
+ v-for="index in timeAxisScaleRepeat"
|
|
|
|
+ :key="index"
|
|
|
|
+ class="scale-line"
|
|
|
|
+ :style="{
|
|
|
|
+ width: `${timeAxisScaleWidth}px`,
|
|
|
|
+ marginRight: `${timeAxisScaleMargin}px`,
|
|
|
|
+ opacity: computeTimeAxisScaleOpacity(index),
|
|
|
|
+ }"
|
|
|
|
+ />
|
|
|
|
+ <div
|
|
|
|
+ v-for="index in timeAxisScaleRepeat"
|
|
|
|
+ :key="index"
|
|
|
|
+ class="scale-line"
|
|
|
|
+ :style="{
|
|
|
|
+ width: `${timeAxisScaleWidth}px`,
|
|
|
|
+ marginRight: `${timeAxisScaleMargin}px`,
|
|
|
|
+ opacity: computeTimeAxisScaleOpacity(index + timeAxisScaleRepeat),
|
|
|
|
+ }"
|
|
|
|
+ />
|
|
</div>
|
|
</div>
|
|
- <div
|
|
|
|
- class="test"
|
|
|
|
- :style="{
|
|
|
|
- left: testLeft,
|
|
|
|
- }"
|
|
|
|
- />
|
|
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -151,23 +138,19 @@ export default {
|
|
lastMoveEventTimeStamp.value = 0
|
|
lastMoveEventTimeStamp.value = 0
|
|
lastAnimationTimeStamp = Date.now()
|
|
lastAnimationTimeStamp = Date.now()
|
|
lastTouchPos.value = e.changedTouches[0].clientX
|
|
lastTouchPos.value = e.changedTouches[0].clientX
|
|
- console.log('start!')
|
|
|
|
}
|
|
}
|
|
function onTouchEnd(e) {
|
|
function onTouchEnd(e) {
|
|
isMouseDown.value = false
|
|
isMouseDown.value = false
|
|
- console.log('end!')
|
|
|
|
}
|
|
}
|
|
function onTouchCancel() {
|
|
function onTouchCancel() {
|
|
isMouseDown.value = false
|
|
isMouseDown.value = false
|
|
}
|
|
}
|
|
function onTouchMove(e) {
|
|
function onTouchMove(e) {
|
|
- console.log('move!')
|
|
|
|
if (isMouseDown.value && e.changedTouches.length === 1) {
|
|
if (isMouseDown.value && e.changedTouches.length === 1) {
|
|
// 疯狂操作的极端情况下两个时间戳之间的时差会不合理,甚至为0
|
|
// 疯狂操作的极端情况下两个时间戳之间的时差会不合理,甚至为0
|
|
if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
|
|
if (lastMoveEventTimeStamp.value && (e.timeStamp - lastMoveEventTimeStamp.value > 1)) {
|
|
// 更新speed
|
|
// 更新speed
|
|
- console.log('shabi')
|
|
|
|
- const currentMoveSpeed = - (e.changedTouches[0].clientX - lastTouchPos.value) / (e.timeStamp - lastMoveEventTimeStamp.value) * 0.5
|
|
|
|
|
|
+ const currentMoveSpeed = - (e.changedTouches[0].clientX - lastTouchPos.value) / (e.timeStamp - lastMoveEventTimeStamp.value) * 1
|
|
moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
|
|
moveSpeed.value = moveSpeed.value * 0.9 + currentMoveSpeed * 0.1
|
|
lastTouchPos.value = e.changedTouches[0].clientX
|
|
lastTouchPos.value = e.changedTouches[0].clientX
|
|
}
|
|
}
|
|
@@ -207,7 +190,6 @@ export default {
|
|
translateLength.value = maxTranslateLength.value
|
|
translateLength.value = maxTranslateLength.value
|
|
moveSpeed.value = 0
|
|
moveSpeed.value = 0
|
|
}
|
|
}
|
|
- console.log(translateLength.value)
|
|
|
|
lastAnimationTimeStamp = timeStamp
|
|
lastAnimationTimeStamp = timeStamp
|
|
animationFrameId = requestAnimationFrame(animationFrameTask)
|
|
animationFrameId = requestAnimationFrame(animationFrameTask)
|
|
}
|
|
}
|
|
@@ -232,38 +214,41 @@ export default {
|
|
immediate: true,
|
|
immediate: true,
|
|
})
|
|
})
|
|
|
|
|
|
- const testSpeedRate = 1
|
|
|
|
- const initialTestLeft = `1000px`
|
|
|
|
- const testLeft = ref(initialTestLeft)
|
|
|
|
|
|
+ // 时间轴
|
|
|
|
+ const timeAxisLeft = ref(0)
|
|
|
|
+ const timeAxisScaleWidth = 2
|
|
|
|
+ const timeAxisScaleMargin = 120
|
|
|
|
+ const timeAxisScaleRepeat = 20
|
|
watch(translateLength, (vNew) => {
|
|
watch(translateLength, (vNew) => {
|
|
- console.log('sdjgflksklfg', vNew)
|
|
|
|
- testLeft.value = `calc(${initialTestLeft} - ${vNew * testSpeedRate}px)`
|
|
|
|
|
|
+ timeAxisLeft.value = -(vNew % ((timeAxisScaleWidth + timeAxisScaleMargin) * timeAxisScaleRepeat))
|
|
})
|
|
})
|
|
|
|
+ const windowCenterX = window.innerWidth / 2
|
|
|
|
+ function computeTimeAxisScaleOpacity(index) { // 注意index是从1开始的
|
|
|
|
+ const scaleCenterXInWindow = (timeAxisScaleWidth + timeAxisScaleMargin) * (index - 1) + timeAxisScaleWidth / 2 + timeAxisLeft.value
|
|
|
|
+ return String(Math.max(1 - Math.abs(windowCenterX - scaleCenterXInWindow) / (windowCenterX), 0))
|
|
|
|
+ }
|
|
|
|
|
|
- // 时间轴位移
|
|
|
|
- const timeAxisLeft = ref('0px')
|
|
|
|
|
|
+ // 齿轮
|
|
|
|
+ const gearFrameNumberTotal = 24
|
|
|
|
+ const gearFrameIdx = ref(0)
|
|
|
|
+ const gearFrameNumberPerScale = 3
|
|
|
|
+ const translateLengthPerGrearFrame = (timeAxisScaleWidth + timeAxisScaleMargin) / gearFrameNumberPerScale
|
|
watch(translateLength, (vNew) => {
|
|
watch(translateLength, (vNew) => {
|
|
- timeAxisLeft.value = `${-(vNew % 1920)}px`
|
|
|
|
|
|
+ const framePassed = Math.round(translateLength.value / translateLengthPerGrearFrame)
|
|
|
|
+ gearFrameIdx.value = framePassed % gearFrameNumberTotal
|
|
})
|
|
})
|
|
|
|
|
|
- // 齿轮
|
|
|
|
- const gearStatus = ref('idle')
|
|
|
|
- function doTest() {
|
|
|
|
- gearStatus.value = 'clockwise'
|
|
|
|
- setTimeout(() => {
|
|
|
|
- gearStatus.value = 'idle'
|
|
|
|
- }, 2000)
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
return {
|
|
return {
|
|
onTouchStart,
|
|
onTouchStart,
|
|
onTouchEnd,
|
|
onTouchEnd,
|
|
onTouchCancel,
|
|
onTouchCancel,
|
|
onTouchMove,
|
|
onTouchMove,
|
|
- testLeft,
|
|
|
|
timeAxisLeft,
|
|
timeAxisLeft,
|
|
- gearStatus,
|
|
|
|
- doTest,
|
|
|
|
|
|
+ timeAxisScaleWidth,
|
|
|
|
+ timeAxisScaleMargin,
|
|
|
|
+ timeAxisScaleRepeat,
|
|
|
|
+ computeTimeAxisScaleOpacity,
|
|
|
|
+ gearFrameIdx,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -287,18 +272,13 @@ export default {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
>.time-axis-wrap{
|
|
>.time-axis-wrap{
|
|
- top: 54%;
|
|
|
|
|
|
+ bottom: 32.4%;
|
|
position: absolute;
|
|
position: absolute;
|
|
display: flex;
|
|
display: flex;
|
|
- >.time-axis{
|
|
|
|
- width: 1920px;
|
|
|
|
|
|
+ >.scale-line{
|
|
|
|
+ height: 30px;
|
|
|
|
+ background-color: #91886b;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- >.test{
|
|
|
|
- position: absolute;
|
|
|
|
- width: 100px;
|
|
|
|
- height: 100px;
|
|
|
|
- background-color: red;
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
</style>
|
|
</style>
|