quickshell: fling the worm when a panel pops out on top of him
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
25819bd901
commit
bdb3ab0c75
1 changed files with 43 additions and 26 deletions
|
|
@ -1029,7 +1029,7 @@ in
|
||||||
// Snapshot last, so a rect is always compared against
|
// Snapshot last, so a rect is always compared against
|
||||||
// where it was exactly one tick ago. vector4d is a
|
// where it was exactly one tick ago. vector4d is a
|
||||||
// value type, so this copies numbers, not handles.
|
// value type, so this copies numbers, not handles.
|
||||||
prevRects = pushers.slice();
|
prevRects = pushers.map(p => p.rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1060,12 +1060,18 @@ in
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── Shoved by the panels ────────────────────────────────
|
// ── Shoved by the panels ────────────────────────────────
|
||||||
// Bound to the very rects the frame shader melts into the
|
// Each pusher is { rect, push }: `rect` is the very vector4d
|
||||||
// chrome (cx, cy, hw, hh; hw <= 0 means "not on screen"), so
|
// the frame shader melts into the chrome (cx, cy, hw, hh;
|
||||||
// what sweeps him aside is the panel outline you can actually
|
// hw <= 0 means "not on screen"), so what sweeps him aside is
|
||||||
// see growing, not the cards riding inside it.
|
// the panel outline you can actually see. `push` is the unit
|
||||||
|
// direction that panel slides out in — a constant of the
|
||||||
|
// design, and not something worth deriving: the morph is
|
||||||
|
// 280ms of OutExpo, nearly all of it landing inside a single
|
||||||
|
// 33ms tick, so there is rarely a partly-grown rect to read a
|
||||||
|
// direction off of.
|
||||||
property var pushers: []
|
property var pushers: []
|
||||||
property var prevRects: []
|
property var prevRects: []
|
||||||
|
readonly property real shoveSpeed: 18
|
||||||
|
|
||||||
function inRect(p, r) {
|
function inRect(p, r) {
|
||||||
return Math.abs(p.x - r.x) <= r.z + 6 && Math.abs(p.y - r.y) <= r.w + 6;
|
return Math.abs(p.x - r.x) <= r.z + 6 && Math.abs(p.y - r.y) <= r.w + 6;
|
||||||
|
|
@ -1074,16 +1080,28 @@ in
|
||||||
function checkShove() {
|
function checkShove() {
|
||||||
let head = body[0], tail = body[segments - 1];
|
let head = body[0], tail = body[segments - 1];
|
||||||
for (let i = 0; i < pushers.length; i++) {
|
for (let i = 0; i < pushers.length; i++) {
|
||||||
let r = pushers[i], q = prevRects[i];
|
let r = pushers[i].rect, q = prevRects[i];
|
||||||
if (!r || r.z < 0.5) continue;
|
if (!r || r.z < 0.5) continue;
|
||||||
if (!inRect(head, r)) continue;
|
// Any part of him in the way is enough to be swept;
|
||||||
if (!q || q.z < 0.5) { q = r; } // appeared already overlapping him
|
// only the head decides a turn-around.
|
||||||
// Only an edge that is travelling outward carries him,
|
let touched = false;
|
||||||
// and it carries him the way it is going: the dropdown
|
for (let s = 0; s < body.length && !touched; s++)
|
||||||
// grows rightward out of the bar, the launcher grows
|
touched = inRect(body[s], r);
|
||||||
// up out of the floor. A panel closing just lets go.
|
if (!touched) continue;
|
||||||
let dx = Math.max(0, (r.x + r.z) - (q.x + q.z)) + Math.min(0, (r.x - r.z) - (q.x - q.z));
|
// Either it was not there a tick ago — the pop-out,
|
||||||
let dy = Math.max(0, (r.y + r.w) - (q.y + q.w)) + Math.min(0, (r.y - r.w) - (q.y - q.w));
|
// and the usual case given how fast the morph is — or
|
||||||
|
// an edge has swept outward over him since. Both mean
|
||||||
|
// the panel arrived where he was standing.
|
||||||
|
let appeared = !q || q.z < 0.5;
|
||||||
|
let grew = !appeared && (
|
||||||
|
(r.x + r.z) - (q.x + q.z) > 1 || (q.x - q.z) - (r.x - r.z) > 1
|
||||||
|
|| (r.y + r.w) - (q.y + q.w) > 1 || (q.y - q.w) - (r.y - r.w) > 1);
|
||||||
|
if (appeared || grew) {
|
||||||
|
worm.loose = true;
|
||||||
|
worm.vx = pushers[i].push.x * shoveSpeed;
|
||||||
|
worm.vy = pushers[i].push.y * shoveSpeed - 3; // -3: a little air
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Sitting still, it is simply solid: he walks into the
|
// Sitting still, it is simply solid: he walks into the
|
||||||
// panel and turns around rather than crawling through
|
// panel and turns around rather than crawling through
|
||||||
// it, which is what made an open dropdown feel like it
|
// it, which is what made an open dropdown feel like it
|
||||||
|
|
@ -1092,15 +1110,7 @@ in
|
||||||
// inside (he landed there) means walking on is the way
|
// inside (he landed there) means walking on is the way
|
||||||
// out, and reversing on that would just buzz him in
|
// out, and reversing on that would just buzz him in
|
||||||
// place against both edges.
|
// place against both edges.
|
||||||
if (Math.abs(dx) < 1 && Math.abs(dy) < 1) {
|
if (inRect(head, r) && !inRect(tail, r)) reverse();
|
||||||
if (!inRect(tail, r)) reverse();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
worm.loose = true;
|
|
||||||
// Clamped: the panel's first frame of OutExpo covers
|
|
||||||
// most of its width, which would fire him off screen.
|
|
||||||
worm.vx = Math.max(-22, Math.min(22, dx * 1.4));
|
|
||||||
worm.vy = Math.max(-22, Math.min(22, dy * 1.4)) - 3; // -3: a little air
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -6752,9 +6762,16 @@ in
|
||||||
|
|
||||||
// Last child, so he crawls over the panels rather than under
|
// Last child, so he crawls over the panels rather than under
|
||||||
// them. Purely decorative, see Weird.qml. The pushers are the
|
// them. Purely decorative, see Weird.qml. The pushers are the
|
||||||
// same rects the frame shader draws, so what shoves him is the
|
// same rects the frame shader draws, paired with the way each
|
||||||
// panel outline itself as it grows.
|
// one slides out: dropdowns and toasts rightward out of the
|
||||||
Weird { pushers: [chromeSdf.panel, chromeSdf.launcher] }
|
// bar column, the launcher up out of the bottom frame band.
|
||||||
|
Weird {
|
||||||
|
pushers: [
|
||||||
|
{ rect: chromeSdf.panel, push: Qt.point(1, 0) },
|
||||||
|
{ rect: chromeSdf.toast, push: Qt.point(1, 0) },
|
||||||
|
{ rect: chromeSdf.launcher, push: Qt.point(0, -1) }
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue