Ajuste le maintien de demarrage du cube
This commit is contained in:
55
app.js
55
app.js
@@ -7,7 +7,7 @@ const DEFAULT_BLOCK_DURATION_MS = 180000;
|
|||||||
const DEFAULT_MOVE_LIMIT_MS = 20000;
|
const DEFAULT_MOVE_LIMIT_MS = 20000;
|
||||||
const TIME_MODE_INITIAL_CLOCK_MS = 600000;
|
const TIME_MODE_INITIAL_CLOCK_MS = 600000;
|
||||||
const CUBE_TIME_CAP_MS = 120000;
|
const CUBE_TIME_CAP_MS = 120000;
|
||||||
const CUBE_START_HOLD_MS = 300;
|
const CUBE_START_HOLD_MS = 2000;
|
||||||
|
|
||||||
const PRESETS = {
|
const PRESETS = {
|
||||||
fast: {
|
fast: {
|
||||||
@@ -584,6 +584,7 @@ function initCubePage() {
|
|||||||
white: createCubeHoldIntent(),
|
white: createCubeHoldIntent(),
|
||||||
black: createCubeHoldIntent(),
|
black: createCubeHoldIntent(),
|
||||||
};
|
};
|
||||||
|
let cubeHoldAnimationFrameId = null;
|
||||||
|
|
||||||
const openModal = () => toggleModal(refs.helpModal, true);
|
const openModal = () => toggleModal(refs.helpModal, true);
|
||||||
const closeModal = () => toggleModal(refs.helpModal, false);
|
const closeModal = () => toggleModal(refs.helpModal, false);
|
||||||
@@ -693,6 +694,7 @@ function initCubePage() {
|
|||||||
clearCubeHoldTimeout(holdIntent);
|
clearCubeHoldTimeout(holdIntent);
|
||||||
holdIntent.armed = true;
|
holdIntent.armed = true;
|
||||||
holdIntent.ready = false;
|
holdIntent.ready = false;
|
||||||
|
holdIntent.startedAt = Date.now();
|
||||||
holdIntent.pointerId = event.pointerId;
|
holdIntent.pointerId = event.pointerId;
|
||||||
holdIntent.timeoutId = window.setTimeout(() => {
|
holdIntent.timeoutId = window.setTimeout(() => {
|
||||||
holdIntent.timeoutId = null;
|
holdIntent.timeoutId = null;
|
||||||
@@ -711,6 +713,7 @@ function initCubePage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render();
|
render();
|
||||||
|
ensureCubeHoldAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCubePressEnd(color, button, event) {
|
function handleCubePressEnd(color, button, event) {
|
||||||
@@ -771,7 +774,44 @@ function initCubePage() {
|
|||||||
clearCubeHoldTimeout(holdIntent);
|
clearCubeHoldTimeout(holdIntent);
|
||||||
holdIntent.armed = false;
|
holdIntent.armed = false;
|
||||||
holdIntent.ready = false;
|
holdIntent.ready = false;
|
||||||
|
holdIntent.startedAt = 0;
|
||||||
holdIntent.pointerId = null;
|
holdIntent.pointerId = null;
|
||||||
|
stopCubeHoldAnimationIfIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureCubeHoldAnimation() {
|
||||||
|
if (cubeHoldAnimationFrameId !== null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const tick = () => {
|
||||||
|
cubeHoldAnimationFrameId = null;
|
||||||
|
if (!isCubeHoldAnimating()) {
|
||||||
|
render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
render();
|
||||||
|
cubeHoldAnimationFrameId = window.requestAnimationFrame(tick);
|
||||||
|
};
|
||||||
|
|
||||||
|
cubeHoldAnimationFrameId = window.requestAnimationFrame(tick);
|
||||||
|
}
|
||||||
|
|
||||||
|
function stopCubeHoldAnimationIfIdle() {
|
||||||
|
if (cubeHoldAnimationFrameId === null || isCubeHoldAnimating()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.cancelAnimationFrame(cubeHoldAnimationFrameId);
|
||||||
|
cubeHoldAnimationFrameId = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isCubeHoldAnimating() {
|
||||||
|
return Object.entries(cubeHoldState).some(([color, holdIntent]) => {
|
||||||
|
const playerState = match.cube.playerState[color];
|
||||||
|
return holdIntent.armed && !holdIntent.ready && !playerState.running && match.cube.times[color] === null;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function clearCubeHoldTimeout(holdIntent) {
|
function clearCubeHoldTimeout(holdIntent) {
|
||||||
@@ -793,12 +833,16 @@ function initCubePage() {
|
|||||||
const time = match.cube.times[color];
|
const time = match.cube.times[color];
|
||||||
const holdArmed = holdIntent.armed && !playerState.running && time === null && match.phase === "cube" && !match.result;
|
const holdArmed = holdIntent.armed && !playerState.running && time === null && match.phase === "cube" && !match.result;
|
||||||
const holdReady = holdIntent.ready && holdArmed;
|
const holdReady = holdIntent.ready && holdArmed;
|
||||||
|
const holdProgress = holdArmed
|
||||||
|
? Math.min((Date.now() - holdIntent.startedAt) / CUBE_START_HOLD_MS, 1)
|
||||||
|
: 0;
|
||||||
|
|
||||||
name.textContent = playerName(match, color);
|
name.textContent = playerName(match, color);
|
||||||
result.textContent = formatCubePlayerTime(match, color);
|
result.textContent = formatCubePlayerTime(match, color);
|
||||||
cap.textContent = renderCubeCap(match, time);
|
cap.textContent = renderCubeCap(match, time);
|
||||||
button.classList.toggle("cube-hold-arming", holdArmed && !holdReady);
|
button.classList.toggle("cube-hold-arming", holdArmed && !holdReady);
|
||||||
button.classList.toggle("cube-hold-ready", holdReady);
|
button.classList.toggle("cube-hold-ready", holdReady);
|
||||||
|
button.style.setProperty("--cube-hold-progress", `${holdProgress}`);
|
||||||
|
|
||||||
if (match.result) {
|
if (match.result) {
|
||||||
button.textContent = resultText(match);
|
button.textContent = resultText(match);
|
||||||
@@ -836,15 +880,15 @@ function initCubePage() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (holdArmed) {
|
if (holdArmed) {
|
||||||
button.textContent = "Maintenez...";
|
button.textContent = "Maintenez 2 s...";
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
hint.textContent = "Gardez le doigt pose un court instant pour armer le depart.";
|
hint.textContent = "Gardez le doigt pose 2 secondes, jusqu'a la fin de la barre.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
button.textContent = "Maintenir pour demarrer";
|
button.textContent = "Maintenir 2 s pour demarrer";
|
||||||
button.disabled = false;
|
button.disabled = false;
|
||||||
hint.textContent = "Maintenez la grande zone, puis relachez pour lancer votre chrono.";
|
hint.textContent = "Maintenez la grande zone 2 secondes, puis relachez pour lancer votre chrono.";
|
||||||
}
|
}
|
||||||
|
|
||||||
function render() {
|
function render() {
|
||||||
@@ -1787,6 +1831,7 @@ function createCubeHoldIntent() {
|
|||||||
return {
|
return {
|
||||||
armed: false,
|
armed: false,
|
||||||
ready: false,
|
ready: false,
|
||||||
|
startedAt: 0,
|
||||||
pointerId: null,
|
pointerId: null,
|
||||||
timeoutId: null,
|
timeoutId: null,
|
||||||
};
|
};
|
||||||
|
|||||||
40
styles.css
40
styles.css
@@ -711,9 +711,38 @@ textarea:focus {
|
|||||||
}
|
}
|
||||||
|
|
||||||
body[data-page="cube"] .zone-button {
|
body[data-page="cube"] .zone-button {
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
touch-action: none;
|
touch-action: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
--cube-hold-progress: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-page="cube"] .zone-button::before,
|
||||||
|
body[data-page="cube"] .zone-button::after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
left: 1rem;
|
||||||
|
right: 1rem;
|
||||||
|
bottom: 0.9rem;
|
||||||
|
height: 0.38rem;
|
||||||
|
border-radius: 999px;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-page="cube"] .zone-button::before {
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 120ms ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
body[data-page="cube"] .zone-button::after {
|
||||||
|
background: linear-gradient(90deg, rgba(255, 255, 255, 0.4), currentColor);
|
||||||
|
transform: scaleX(var(--cube-hold-progress));
|
||||||
|
transform-origin: left center;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 120ms ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
body[data-page="cube"] .zone-button.cube-hold-arming {
|
body[data-page="cube"] .zone-button.cube-hold-arming {
|
||||||
@@ -722,6 +751,13 @@ body[data-page="cube"] .zone-button.cube-hold-arming {
|
|||||||
box-shadow: inset 0 0 0 1px currentColor;
|
box-shadow: inset 0 0 0 1px currentColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body[data-page="cube"] .zone-button.cube-hold-arming::before,
|
||||||
|
body[data-page="cube"] .zone-button.cube-hold-arming::after,
|
||||||
|
body[data-page="cube"] .zone-button.cube-hold-ready::before,
|
||||||
|
body[data-page="cube"] .zone-button.cube-hold-ready::after {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
body[data-page="cube"] .zone-button.cube-hold-ready {
|
body[data-page="cube"] .zone-button.cube-hold-ready {
|
||||||
transform: none;
|
transform: none;
|
||||||
filter: brightness(1.08);
|
filter: brightness(1.08);
|
||||||
@@ -730,6 +766,10 @@ body[data-page="cube"] .zone-button.cube-hold-ready {
|
|||||||
0 0 24px rgba(255, 255, 255, 0.08);
|
0 0 24px rgba(255, 255, 255, 0.08);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body[data-page="cube"] .zone-button.cube-hold-ready::after {
|
||||||
|
transform: scaleX(1);
|
||||||
|
}
|
||||||
|
|
||||||
.zone-button:hover {
|
.zone-button:hover {
|
||||||
transform: translateY(-2px);
|
transform: translateY(-2px);
|
||||||
filter: brightness(1.04);
|
filter: brightness(1.04);
|
||||||
|
|||||||
Reference in New Issue
Block a user