Skip to content

Commit ba6c138

Browse files
author
Tom Notch
committed
Refine interaction hints
1 parent 702b60a commit ba6c138

3 files changed

Lines changed: 191 additions & 117 deletions

File tree

public/spherical-viewer/index.html

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,9 +92,11 @@
9292
}
9393
.usf-interaction-hint {
9494
position: absolute;
95-
bottom: 10%;
95+
top: 50%;
9696
left: 50%;
97-
transform: translateX(-50%);
97+
transform: translate(-50%, -50%);
98+
width: 64px;
99+
height: 88px;
98100
pointer-events: none;
99101
opacity: 0;
100102
transition: opacity 0.4s;
@@ -103,21 +105,41 @@
103105
.usf-interaction-hint.visible {
104106
opacity: 1;
105107
}
106-
.usf-hint-hand {
108+
.usf-hint-hand-wrap {
109+
position: absolute;
110+
inset: 0;
111+
display: flex;
112+
align-items: center;
113+
justify-content: center;
114+
opacity: 0;
115+
transition: opacity 0.35s ease;
116+
}
117+
.usf-interaction-hint.visible .usf-hint-hand-wrap {
118+
opacity: 1;
119+
}
120+
.usf-hint-hand--pan {
107121
width: 50px;
108122
height: 72px;
109-
animation: usf-swipe 2.4s ease-in-out;
123+
transform: translateX(0) scale(1.16);
124+
transform-origin: center center;
125+
/* forwards: avoid snap to scale(1) when non-infinite animation ends */
126+
animation: usf-swipe 2.4s ease-in-out forwards;
110127
}
111128
@keyframes usf-swipe {
112129
0%,
113130
100% {
114-
transform: translateX(0);
131+
transform: translateX(0) scale(1.16);
115132
}
116133
30% {
117-
transform: translateX(24px);
134+
transform: translateX(26px) scale(1.16);
118135
}
119136
60% {
120-
transform: translateX(-24px);
137+
transform: translateX(-26px) scale(1.16);
138+
}
139+
}
140+
@media (prefers-reduced-motion: reduce) {
141+
.usf-hint-hand--pan {
142+
animation: none !important;
121143
}
122144
}
123145
</style>

public/spherical-viewer/viewer.js

Lines changed: 43 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,10 @@ function showInteractionHint(container, theme) {
200200
const dark = theme === "dark";
201201
const wrap = document.createElement("div");
202202
wrap.className = "usf-interaction-hint";
203-
wrap.innerHTML = `<div class="usf-hint-hand">${handSVG(dark)}</div>`;
203+
wrap.innerHTML =
204+
`<div class="usf-hint-hand-wrap">` +
205+
`<div class="usf-hint-hand usf-hint-hand--pan">${handSVG(dark)}</div>` +
206+
`</div>`;
204207
container.appendChild(wrap);
205208
return wrap;
206209
}
@@ -644,30 +647,52 @@ async function main() {
644647
let hintDismissed = hintAlreadyDismissed;
645648
let hintTimers = [];
646649

647-
const hintHand = hint.querySelector(".usf-hint-hand");
650+
const hintPanInner = hint.querySelector(".usf-hint-hand--pan");
651+
652+
const restartPanAnim = () => {
653+
hintPanInner.style.animation = "none";
654+
void hintPanInner.offsetWidth;
655+
hintPanInner.style.animation = "";
656+
};
648657

649658
if (hintAlreadyDismissed) {
650659
hint.remove();
651660
} else {
652-
const scheduleHintPulse = () => {
661+
const PAN_MS = 2800;
662+
const FADE_MS = 450;
663+
const GAP_MS = 2800;
664+
const INITIAL_DELAY_MS = 800;
665+
666+
const scheduleHintCycle = (isFirstCycle) => {
653667
if (hintDismissed) return;
654-
const t1 = setTimeout(() => {
655-
if (hintDismissed) return;
656-
hintHand.style.animation = "none";
657-
void hintHand.offsetWidth;
658-
hintHand.style.animation = "";
659-
hint.classList.add("visible");
660-
}, 800);
661-
const t2 = setTimeout(() => {
662-
if (hintDismissed) return;
663-
hint.classList.remove("visible");
664-
const t3 = setTimeout(() => scheduleHintPulse(), 3000);
665-
hintTimers.push(t3);
666-
}, 3600);
667-
hintTimers.push(t1, t2);
668+
let acc = isFirstCycle ? INITIAL_DELAY_MS : GAP_MS;
669+
670+
hintTimers.push(
671+
setTimeout(() => {
672+
if (hintDismissed) return;
673+
restartPanAnim();
674+
hint.classList.add("visible");
675+
}, acc),
676+
);
677+
678+
acc += PAN_MS;
679+
hintTimers.push(
680+
setTimeout(() => {
681+
if (hintDismissed) return;
682+
hint.classList.remove("visible");
683+
}, acc),
684+
);
685+
686+
acc += FADE_MS;
687+
hintTimers.push(
688+
setTimeout(() => {
689+
if (hintDismissed) return;
690+
scheduleHintCycle(false);
691+
}, acc),
692+
);
668693
};
669694

670-
scheduleHintPulse();
695+
scheduleHintCycle(true);
671696

672697
const dismissHint = (broadcast = true) => {
673698
hintDismissed = true;

0 commit comments

Comments
 (0)