どちらも押した位置に円形インジケータを、少し離して選択先のリストを出す。 間隔は600msで始まり1000msごとに進む(500ms/450msは早いという所感への対応)。 リスト方式は、ポインタがリストに入ると巡回を止め、離したときに指している行で確定する。 リストへ向かう動きをドラッグと取り違えないよう、リスト方式では長押し後のドラッグをしない。 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ShoEXYqi8PWTjB9E86Ltot
104 lines
1.9 KiB
Vue
104 lines
1.9 KiB
Vue
<script setup lang="ts">
|
|
import { HOLD_INTERVAL, type HoldMode } from "./usePhyLongPress";
|
|
defineProps<{
|
|
mode: HoldMode;
|
|
pos: { x: number; y: number };
|
|
names: string[];
|
|
index: number;
|
|
step: number;
|
|
pointing: boolean;
|
|
}>();
|
|
// 円の周長。インジケータは次の切り替えまでに一周する
|
|
const ring = 2 * Math.PI * 14;
|
|
</script>
|
|
|
|
<template>
|
|
<svg
|
|
v-if="!pointing"
|
|
:key="step"
|
|
class="hold-ring"
|
|
width="36"
|
|
height="36"
|
|
:style="{ left: pos.x - 18 + 'px', top: pos.y - 18 + 'px' }"
|
|
>
|
|
<circle cx="18" cy="18" r="14" class="track" />
|
|
<circle
|
|
cx="18"
|
|
cy="18"
|
|
r="14"
|
|
class="progress"
|
|
:stroke-dasharray="ring"
|
|
:style="{ '--ring': ring, animationDuration: HOLD_INTERVAL + 'ms' }"
|
|
/>
|
|
</svg>
|
|
<ol
|
|
class="hold-list"
|
|
:class="mode"
|
|
:data-hold-mode="mode"
|
|
:style="{ left: pos.x + 22 + 'px', top: pos.y + 10 + 'px' }"
|
|
>
|
|
<li
|
|
v-for="(name, i) in names"
|
|
:key="i"
|
|
class="hold-row"
|
|
:class="{ active: i === index }"
|
|
:data-hold-index="i"
|
|
>
|
|
{{ name }}
|
|
</li>
|
|
</ol>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.hold-ring {
|
|
position: fixed;
|
|
z-index: 3;
|
|
pointer-events: none;
|
|
}
|
|
.track,
|
|
.progress {
|
|
fill: none;
|
|
stroke-width: 3;
|
|
}
|
|
.track {
|
|
stroke: rgb(200 125 19 / 25%);
|
|
}
|
|
.progress {
|
|
stroke: #c87d13;
|
|
transform: rotate(-90deg);
|
|
transform-origin: 18px 18px;
|
|
animation: hold-ring linear forwards;
|
|
}
|
|
@keyframes hold-ring {
|
|
from {
|
|
stroke-dashoffset: var(--ring);
|
|
}
|
|
to {
|
|
stroke-dashoffset: 0;
|
|
}
|
|
}
|
|
.hold-list {
|
|
position: fixed;
|
|
z-index: 3;
|
|
margin: 0;
|
|
padding: 3px 0;
|
|
list-style: none;
|
|
background: #fff3d8;
|
|
border: 1px solid #c87d13;
|
|
border-radius: 4px;
|
|
font-size: 13px;
|
|
user-select: none;
|
|
}
|
|
.hold-list.loop {
|
|
pointer-events: none;
|
|
}
|
|
.hold-row {
|
|
padding: 3px 10px;
|
|
white-space: nowrap;
|
|
}
|
|
.hold-row.active {
|
|
background: #c87d13;
|
|
color: #fff;
|
|
}
|
|
</style>
|