fixed several animation & transition problems plaguing the inventory tray

This commit is contained in:
Disco DeDisco
2026-04-04 14:51:49 -04:00
parent b74f8e1bb1
commit 4e07fcf38b
5 changed files with 54 additions and 15 deletions

View File

@@ -205,7 +205,12 @@ var RoleSelect = (function () {
var _reload = function () { window.location.reload(); };
function handleRolesRevealed() {
function handleAllRolesFilled() {
var wrap = document.getElementById('id_pick_sigs_wrap');
if (wrap) wrap.style.display = '';
}
function handleSigSelectStarted() {
_reload();
}
@@ -291,7 +296,8 @@ var RoleSelect = (function () {
window.addEventListener("room:role_select_start", init);
window.addEventListener("room:turn_changed", handleTurnChanged);
window.addEventListener("room:roles_revealed", handleRolesRevealed);
window.addEventListener("room:all_roles_filled", handleAllRolesFilled);
window.addEventListener("room:sig_select_started", handleSigSelectStarted);
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", init);

View File

@@ -1,5 +1,8 @@
var Tray = (function () {
var _open = false;
// Fallback timeout (ms) after close() in placeCard in case transitionend
// never fires (e.g. CSS transitions disabled). Zeroed by reset() for tests.
var _closeTransitionMs = 600;
var _dragStartX = null;
var _dragStartY = null;
var _dragStartLeft = null;
@@ -235,7 +238,9 @@ var Tray = (function () {
}
// placeCard(roleCode, onComplete) — mark the first tray cell with the role,
// open the tray, arc-in the cell, then force-close. Calls onComplete after.
// open the tray, arc-in the cell, then animated-close. Calls onComplete after
// the close slide finishes (transitionend), with a fallback timeout in case
// CSS transitions are disabled (e.g. test environments).
// The grid always contains exactly 8 .tray-cell elements (from the template);
// the first one receives .tray-role-card and data-role instead of a new element
// being inserted, so the cell count never changes.
@@ -250,8 +255,22 @@ var Tray = (function () {
open();
_arcIn(firstCell, function () {
forceClose();
if (onComplete) onComplete();
close();
if (!onComplete) return;
if (!_wrap) { onComplete(); return; }
var propName = _isLandscape() ? 'top' : 'left';
var done = false;
function finish() {
if (done) return;
done = true;
if (_wrap) _wrap.removeEventListener('transitionend', onCloseEnd);
onComplete();
}
function onCloseEnd(e) {
if (e.propertyName === propName) finish();
}
_wrap.addEventListener('transitionend', onCloseEnd);
setTimeout(finish, _closeTransitionMs);
});
}
@@ -425,6 +444,7 @@ var Tray = (function () {
// reset() — restores module state; used by Jasmine afterEach
function reset() {
_open = false;
_closeTransitionMs = 0;
_dragStartX = null;
_dragStartY = null;
_dragStartLeft = null;

View File

@@ -473,6 +473,16 @@ html:has(.gate-backdrop) .position-strip .gate-slot button { pointer-events: aut
justify-content: center;
}
// Outside .room-table-scene so it isn't scaled by scaleTable().
// Positioned absolute so it floats over the hex without affecting flex layout.
#id_pick_sigs_wrap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 10;
}
.table-center {
display: flex;
align-items: center;

View File

@@ -41,11 +41,11 @@ $handle-r: 1rem;
display: flex;
flex-direction: row;
align-items: stretch;
transition: left 1.0s cubic-bezier(0.4, 0, 0.2, 1);
transition: left 0.35s cubic-bezier(0.4, 0, 0.2, 1);
&.tray-dragging { transition: none; }
&.wobble { animation: tray-wobble .45s ease; }
&.snap { animation: tray-snap 1.0s ease; }
&.snap { animation: tray-snap 0.30s ease; }
}
#id_tray_handle {
@@ -222,11 +222,11 @@ $handle-r: 1rem;
right: $sidebar-w;
top: auto; // JS controls style.top for the Y-axis slide
bottom: auto;
transition: top 1.0s cubic-bezier(0.4, 0, 0.2, 1);
transition: top 0.35s cubic-bezier(0.4, 0, 0.2, 1);
&.tray-dragging { transition: none; }
&.wobble { animation: tray-wobble-landscape 0.45s ease; }
&.snap { animation: tray-snap-landscape 1.0s ease; }
&.snap { animation: tray-snap-landscape 0.30s ease; }
}

View File

@@ -9,17 +9,20 @@
{% if room.table_status %}data-select-role-url="{% url 'epic:select_role' room.id %}"{% endif %}>
<div class="room-shell">
<div id="id_game_table" class="room-table">
{% if room.table_status == "ROLE_SELECT" %}
<div id="id_pick_sigs_wrap"{% if starter_roles|length < 6 %} style="display:none"{% endif %}>
<form method="POST" action="{% url 'epic:pick_sigs' room.id %}">
{% csrf_token %}
<button type="submit" class="btn btn-primary btn-xl">PICK<br>SIGS</button>
</form>
</div>
{% endif %}
<div class="room-table-scene">
<div class="table-hex-border">
<div class="table-hex">
<div class="table-center">
{% if room.table_status == "ROLE_SELECT" %}
{% if starter_roles|length == 6 %}
<form method="POST" action="{% url 'epic:pick_sigs' room.id %}">
{% csrf_token %}
<button type="submit" class="pick-sigs-btn btn btn-primary btn-xl">PICK SIGS</button>
</form>
{% elif card_stack_state %}
{% if card_stack_state %}
<div class="card-stack" data-state="{{ card_stack_state }}"
data-starter-roles="{{ starter_roles|join:',' }}"
data-user-slots="{{ user_slots|join:',' }}"