Clock: hand outlines drawn once, bubbles beside the watch
The hands' drop-shadow outline sat on their own compositor layers, so the GPU recomputed it every frame a bubble moved. It is now on an inner box, painted once into the hand's layer. The bubbles rise beside the watch, never behind it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,13 +19,16 @@ import { SKIN } from "../lib/skins";
|
||||
import { SHOW_DECORATIVE_ANIMATIONS } from "../lib/theme";
|
||||
import { Drift, type DriftField } from "./Drift";
|
||||
|
||||
/** Beside the watch only, never behind it: on a 1080p kiosk the watch covers roughly
|
||||
* 28-72% of the width, and a bubble rising behind it would drag the watch into every
|
||||
* frame the Pi redraws. */
|
||||
const BUBBLES: DriftField = [
|
||||
[5, 14, 0.5, 9, 0],
|
||||
[12, 22, 0.5, 12, -3],
|
||||
[17, 16, 0.5, 11, -2],
|
||||
[22, 10, 0.5, 8, -6],
|
||||
[48, 16, 0.5, 11, -2],
|
||||
[63, 12, 0.5, 10, -7],
|
||||
[78, 24, 0.5, 14, -5],
|
||||
[83, 12, 0.5, 10, -7],
|
||||
[88, 12, 0.5, 9, -1],
|
||||
[95, 18, 0.5, 13, -9],
|
||||
];
|
||||
@@ -69,11 +72,15 @@ export function ClockOverlay({ visible, clock, onClose }: Props) {
|
||||
<div className="clock-face">
|
||||
<Dial />
|
||||
<div className="clock-hand clock-hand-hour" style={{ transform: `rotate(${angles.hour}deg)` }}>
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
<div className="clock-hand clock-hand-minute" style={{ transform: `rotate(${angles.minute}deg)` }}>
|
||||
<div>
|
||||
<div />
|
||||
</div>
|
||||
</div>
|
||||
<div className="clock-hand clock-hand-second" style={{ transform: `rotate(${angles.second}deg)` }}>
|
||||
<div />
|
||||
</div>
|
||||
|
||||
@@ -362,8 +362,12 @@
|
||||
will-change: transform;
|
||||
}
|
||||
|
||||
.clock-hand-hour,
|
||||
.clock-hand-minute {
|
||||
/* The outline and shadow, on the hand's inner box rather than the hand: a filter on the
|
||||
layer itself would be recomputed on the GPU every frame anything on screen moves (the
|
||||
bubbles), while one inside it is drawn once into the layer's picture. The shape is
|
||||
one level further in, so the outline goes round the clipped arrow, not its box. */
|
||||
.clock-hand-hour > div,
|
||||
.clock-hand-minute > div {
|
||||
filter: drop-shadow(0.35vmin 0 0 var(--clock-ink)) drop-shadow(-0.35vmin 0 0 var(--clock-ink))
|
||||
drop-shadow(0 0.35vmin 0 var(--clock-ink)) drop-shadow(0 -0.35vmin 0 var(--clock-ink))
|
||||
drop-shadow(0 1vmin 1vmin oklch(15% 0.05 210 / 0.3));
|
||||
@@ -382,8 +386,18 @@
|
||||
margin-left: -2.7vmin;
|
||||
}
|
||||
|
||||
.clock-hand-hour > div {
|
||||
.clock-hand-hour > div,
|
||||
.clock-hand-minute > div {
|
||||
bottom: -3.5vmin;
|
||||
}
|
||||
|
||||
.clock-hand-hour > div > div,
|
||||
.clock-hand-minute > div > div {
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
}
|
||||
|
||||
.clock-hand-hour > div > div {
|
||||
background: oklch(92% 0.06 345);
|
||||
clip-path: polygon(50% 0%, 100% 22%, 66% 22%, 66% 100%, 34% 100%, 34% 22%, 0% 22%);
|
||||
}
|
||||
@@ -394,8 +408,7 @@
|
||||
margin-left: -2.5vmin;
|
||||
}
|
||||
|
||||
.clock-hand-minute > div {
|
||||
bottom: -3.5vmin;
|
||||
.clock-hand-minute > div > div {
|
||||
background: oklch(92% 0.05 200);
|
||||
clip-path: polygon(50% 0%, 100% 14%, 64% 14%, 64% 100%, 36% 100%, 36% 14%, 0% 14%);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user