feat(工具箱): 完善“原神时钟”的交互逻辑
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
'clock-rotation': clockState.isRotation,
|
||||
}"
|
||||
:style="elStyle"
|
||||
@touchmove.prevent
|
||||
>
|
||||
|
||||
<!-- 外部 -->
|
||||
@@ -43,7 +44,7 @@
|
||||
<div class="pointer-wrapper pointer-upper bg-contain">
|
||||
<div
|
||||
class="pointer-content"
|
||||
@mousedown="handleDragPointer('upper')"
|
||||
@pointerdown="handleDragPointer('upper')"
|
||||
></div>
|
||||
</div>
|
||||
|
||||
@@ -71,6 +72,9 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 遮罩层,用于阻止操作 -->
|
||||
<div v-show="isAutoRotating" class="clock-mask"></div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -79,6 +83,7 @@ import {
|
||||
computed,
|
||||
onBeforeUnmount, onMounted,
|
||||
reactive, ref,
|
||||
watch,
|
||||
} from 'vue';
|
||||
|
||||
import {
|
||||
@@ -96,6 +101,10 @@ import {
|
||||
IMAGE_TIME_ICON_MORNING,
|
||||
IMAGE_TIME_ICON_NIGHT,
|
||||
IMAGE_TIME_ICON_NOON,
|
||||
isAutoRotating, isTimeExceeded, isTimeTooEarly,
|
||||
timeCurrHour, timeCurrMinute,
|
||||
timeDiffLabel, timeDiffLabelStill,
|
||||
timeNewHour, timeNewMinute,
|
||||
} from './common-data';
|
||||
|
||||
import ClockColor from './ClockColor.vue';
|
||||
@@ -138,6 +147,8 @@ const upperPointer = reactive({
|
||||
|
||||
});
|
||||
|
||||
window.upperPointer = upperPointer;
|
||||
|
||||
/** 元素 CSS */
|
||||
const elStyle = computed(() => {
|
||||
return {
|
||||
@@ -217,7 +228,11 @@ function handleDragPointer() {
|
||||
// 节流
|
||||
let last = 0;
|
||||
|
||||
document.onmousemove = function (ev) {
|
||||
/**
|
||||
* @description 处理光标移动
|
||||
* @param {PointerEvent} ev
|
||||
*/
|
||||
let handleMove = function (ev) {
|
||||
|
||||
let curr = Date.now();
|
||||
|
||||
@@ -283,10 +298,10 @@ function handleDragPointer() {
|
||||
|
||||
};
|
||||
|
||||
document.onmouseup = function () {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
window.addEventListener('pointermove', handleMove);
|
||||
window.addEventListener('pointerup', function () {
|
||||
window.removeEventListener('pointermove', handleMove);
|
||||
}, { once: true });
|
||||
|
||||
}
|
||||
|
||||
@@ -304,6 +319,8 @@ function handleSubmitTime() {
|
||||
// 结束
|
||||
if (upperAngleCurr === 0) {
|
||||
clearInterval(timer);
|
||||
isAutoRotating.value = false;
|
||||
timeDiffLabelStill.value = '';
|
||||
}
|
||||
|
||||
let upperAngleDiff = upperAngleStart - upperAngleCurr;
|
||||
@@ -315,12 +332,87 @@ function handleSubmitTime() {
|
||||
|
||||
}, 50);
|
||||
|
||||
/** 更新状态 */
|
||||
isAutoRotating.value = true;
|
||||
|
||||
// 固定时间差文本
|
||||
timeDiffLabelStill.value = timeDiffLabel.value;
|
||||
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
handleSubmitTime,
|
||||
});
|
||||
|
||||
// 检测角度变化,计算时间信息(自动旋转时)
|
||||
watch(() => {
|
||||
return lowerPointer.viewAngle;
|
||||
}, (viewAngle) => {
|
||||
|
||||
// 转换为对应 24 小时的角度
|
||||
let timeAngle = viewAngle + (viewAngle < 180 ? 180 : -180);
|
||||
let timeValue = timeAngle / 15;
|
||||
let currHour = Math.floor(timeValue);
|
||||
let currMinute = Math.round((timeValue - currHour) * 60);
|
||||
|
||||
// 计算时间值
|
||||
timeCurrHour.value = String(currHour).padStart(2, '0');
|
||||
timeCurrMinute.value = String(currMinute).padStart(2, '0');
|
||||
|
||||
}, { immediate: true });
|
||||
|
||||
// 检测角度变化,计算时间信息(用户操作时)
|
||||
watch(() => {
|
||||
return upperPointer.dataAngle;
|
||||
}, (dataAngle) => {
|
||||
|
||||
// 注:15° / 小时
|
||||
|
||||
let isSecond = upperPointer.isSecond;
|
||||
let currAngle = lowerPointer.viewAngle;
|
||||
let viewAngle = upperPointer.viewAngle;
|
||||
|
||||
let diffAngle = dataAngle + (isSecond ? 360 : 0);
|
||||
let diffAngle1 = 0; // +1 日角度差
|
||||
let diffAngle2 = 0; // +2 日角度差
|
||||
let diffLabel = '';
|
||||
|
||||
// 转换为对应 24 小时的角度
|
||||
let timeAngle = viewAngle + (viewAngle < 180 ? 180 : -180);
|
||||
let timeValue = timeAngle / 15;
|
||||
let newHour = Math.floor(timeValue);
|
||||
let newMinute = Math.round((timeValue - newHour) * 60);
|
||||
|
||||
if (currAngle < 180) {
|
||||
diffAngle1 = 180 - currAngle;
|
||||
diffAngle2 = diffAngle1 + 360;
|
||||
} else {
|
||||
diffAngle1 = 540 - currAngle; // 360 + 180
|
||||
diffAngle2 = diffAngle1 + 360;
|
||||
}
|
||||
|
||||
// 处理时间差信息
|
||||
if (diffAngle < diffAngle1) {
|
||||
diffLabel = '今日';
|
||||
} else if (diffAngle < diffAngle2) {
|
||||
diffLabel = '次日';
|
||||
} else {
|
||||
diffLabel = '+2日';
|
||||
}
|
||||
|
||||
// 处理提示信息显示
|
||||
isTimeTooEarly.value = diffAngle < 7.5;
|
||||
isTimeExceeded.value = diffAngle === 720;
|
||||
|
||||
// 更新时间差信息
|
||||
timeDiffLabel.value = diffLabel;
|
||||
|
||||
// 计算时间值
|
||||
timeNewHour.value = String(newHour).padStart(2, '0');
|
||||
timeNewMinute.value = String(newMinute).padStart(2, '0');
|
||||
|
||||
}, { immediate: true });
|
||||
|
||||
onMounted(() => {
|
||||
timerInit();
|
||||
});
|
||||
@@ -610,6 +702,16 @@ onBeforeUnmount(() => {
|
||||
}
|
||||
}
|
||||
|
||||
.clock-mask {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 100;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
cursor: wait;
|
||||
}
|
||||
|
||||
// 顺时针旋转
|
||||
@keyframes rotation-forward {
|
||||
0% {
|
||||
|
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="tool-detail-page">
|
||||
<div class="tool-detail-page has-radius">
|
||||
|
||||
<!-- 左 -->
|
||||
<div class="page-column">
|
||||
@@ -13,17 +13,27 @@
|
||||
<clock-element ref="clockRef" />
|
||||
|
||||
<!-- 上限提示 -->
|
||||
<div class="time-notice">
|
||||
<div
|
||||
:class="{
|
||||
'is-hide': isAutoRotating,
|
||||
'time-notice': true,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-show="true"
|
||||
v-show="isTimeExceeded"
|
||||
class="time-notice-text"
|
||||
>时间到达上限</span>
|
||||
</div>
|
||||
|
||||
<!-- 确认时间 -->
|
||||
<div class="time-submit">
|
||||
<div
|
||||
:class="{
|
||||
'is-hide': isAutoRotating,
|
||||
'time-submit': true,
|
||||
}"
|
||||
>
|
||||
<span
|
||||
v-if="false"
|
||||
v-if="isTimeTooEarly"
|
||||
class="time-notice-text"
|
||||
>时间少于30分钟</span>
|
||||
<genshin-button
|
||||
@@ -44,6 +54,10 @@ import {
|
||||
ref,
|
||||
} from 'vue';
|
||||
|
||||
import {
|
||||
isAutoRotating, isTimeTooEarly, isTimeExceeded,
|
||||
} from './common-data';
|
||||
|
||||
import ClockElement from './ClockElement.vue';
|
||||
import GenshinButton from './GenshinButton.vue';
|
||||
import TimeInfo from './TimeInfo.vue';
|
||||
@@ -68,7 +82,6 @@ function handleConfirm() {
|
||||
|
||||
<style lang="less" scoped>
|
||||
.tool-detail-page {
|
||||
border-radius: 8px;
|
||||
background-color: #000;
|
||||
font-size: 16px;
|
||||
text-align: center;
|
||||
@@ -89,9 +102,23 @@ function handleConfirm() {
|
||||
}
|
||||
}
|
||||
|
||||
.time-notice {
|
||||
.time-notice, .time-submit {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
opacity: 1;
|
||||
visibility: visible;
|
||||
transition: opacity 0.25s, visibility 0s 0s;
|
||||
|
||||
// 注:
|
||||
// visibility 动画时长用于等待 opacity 动画过渡完毕
|
||||
&.is-hide {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
transition: opacity 0.25s, visibility 0.25s 0s;
|
||||
}
|
||||
}
|
||||
|
||||
.time-notice {
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
@@ -102,9 +129,4 @@ function handleConfirm() {
|
||||
opacity: 0.5;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.time-submit {
|
||||
display: flex;
|
||||
height: 40px;
|
||||
}
|
||||
</style>
|
||||
|
@@ -11,7 +11,11 @@
|
||||
<div class="time-title time-title-current">当前时间</div>
|
||||
|
||||
<!-- 当前时间值 -->
|
||||
<div class="time-value time-value-current">12:00</div>
|
||||
<div class="time-value time-value-current">
|
||||
<span>{{ timeCurrHour }}</span>
|
||||
<span>:</span>
|
||||
<span>{{ timeCurrMinute }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 三角形图标 -->
|
||||
<div class="triangle-icon">
|
||||
@@ -27,10 +31,16 @@
|
||||
</div>
|
||||
|
||||
<!-- 目标时间值 -->
|
||||
<div class="time-value time-value-target">12:00</div>
|
||||
<div class="time-value time-value-target">
|
||||
<span>{{ timeNewHour }}</span>
|
||||
<span>:</span>
|
||||
<span>{{ timeNewMinute }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 时间差 -->
|
||||
<div class="time-diff">+2日</div>
|
||||
<div class="time-diff">
|
||||
<span>{{ timeDiffLabelStill || timeDiffLabel }}</span>
|
||||
</div>
|
||||
|
||||
<!-- 装饰元素 -->
|
||||
<div class="arrow-element"></div>
|
||||
@@ -41,6 +51,9 @@
|
||||
<script setup>
|
||||
import {
|
||||
IMAGE_TIME_INFO_ARROW,
|
||||
timeCurrHour, timeCurrMinute,
|
||||
timeDiffLabel, timeDiffLabelStill,
|
||||
timeNewHour, timeNewMinute,
|
||||
} from './common-data';
|
||||
</script>
|
||||
|
||||
@@ -66,8 +79,17 @@ import {
|
||||
}
|
||||
|
||||
.time-diff {
|
||||
color: #ECE3D6;
|
||||
display: flex;
|
||||
width: 3.5em;
|
||||
height: 1.75em;
|
||||
border-radius: 1.75em;
|
||||
background-color: #282C33;
|
||||
color: rgba(255, 255, 255, 0.75);
|
||||
font-size: 0.75em;
|
||||
|
||||
span {
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.time-title {
|
||||
|
@@ -1,3 +1,5 @@
|
||||
import { ref } from "vue";
|
||||
|
||||
export const IMAGE_BASE = `https://c.frost-zx.top/data/static/image/genshin-impact-clock`;
|
||||
export const IMAGE_CLOCK_BG_INNER = `url("${IMAGE_BASE}/clock_bg_inner.png")`;
|
||||
export const IMAGE_CLOCK_BG_OUTER = `url("${IMAGE_BASE}/clock_bg_outer.png")`;
|
||||
@@ -15,3 +17,30 @@ export const IMAGE_TIME_ICON_NIGHT = `url("${IMAGE_BASE}/time_icon_night.png")`;
|
||||
export const IMAGE_TIME_ICON_NOON = `url("${IMAGE_BASE}/time_icon_noon.png")`;
|
||||
export const IMAGE_TIME_INFO_ARROW = `url("${IMAGE_BASE}/time_info_arrow.png")`;
|
||||
export const IMAGE_TIME_ZONE_COLOR = `${IMAGE_BASE}/time_zone_color.png`;
|
||||
|
||||
/** 是否正在自动旋转 */
|
||||
export const isAutoRotating = ref(false);
|
||||
|
||||
/** 是否时间少于 30 分钟 */
|
||||
export const isTimeTooEarly = ref(false);
|
||||
|
||||
/** 是否时间到达上限 */
|
||||
export const isTimeExceeded = ref(false);
|
||||
|
||||
/** 当前时 */
|
||||
export const timeCurrHour = ref('00');
|
||||
|
||||
/** 当前分 */
|
||||
export const timeCurrMinute = ref('00');
|
||||
|
||||
/** 时间差(动态)*/
|
||||
export const timeDiffLabel = ref('');
|
||||
|
||||
/** 时间差(固定)*/
|
||||
export const timeDiffLabelStill = ref('');
|
||||
|
||||
/** 新的时 */
|
||||
export const timeNewHour = ref('00');
|
||||
|
||||
/** 新的分 */
|
||||
export const timeNewMinute = ref('00');
|
||||
|
Reference in New Issue
Block a user