pull/18889/merge
okxint 2 days ago committed by GitHub
commit cd9eb3b6be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
'svelte': patch
---
fix: correct draw and crossfade transition rendering bugs

@ -93,19 +93,21 @@ let b = $derived(await two());
(Note that if the values of `await one()` and `await two()` subsequently change, they can do so concurrently — the waterfall only occurs when the deriveds are first created.)
You can solve this by creating the promises first and _then_ awaiting them:
You can solve this by starting the promises _before_ awaiting them. Because `$derived` is lazy — the expression only runs when the value is first read — using `$derived(one())` does not help: `one()` still isn't called until `aPromise` is read for the first time, which happens on the `$derived(await aPromise)` line. Use plain `const` or `let` declarations so both functions are called eagerly, before either await runs:
```js
async function one() { return 1 }
async function two() { return 2 }
// ---cut---
let aPromise = $derived(one());
let bPromise = $derived(two());
const aPromise = one();
const bPromise = two();
let a = $derived(await aPromise);
let b = $derived(await bPromise);
```
> [!NOTE] This approach only eliminates the waterfall when `one()` and `two()` do not themselves depend on reactive state. If the promise-creating expressions read `$state` or `$derived` values, there is currently no way to avoid the waterfall.
## binding_property_non_reactive
> `%binding%` is binding to a non-reactive property

@ -197,6 +197,15 @@ export function scale(
export function draw(node, { delay = 0, speed, duration, easing = cubic_in_out } = {}) {
let len = node.getTotalLength();
const style = getComputedStyle(node);
// When vector-effect: non-scaling-stroke is set, the stroke lives in screen
// pixels but getTotalLength() returns SVG user units. Scale len by the CTM
// x-basis magnitude so dasharray/dashoffset match the rendered stroke length.
if (style.vectorEffect === 'non-scaling-stroke') {
const ctm = /** @type {SVGGraphicsElement} */ (node).getCTM?.();
if (ctm) {
len = len * Math.sqrt(ctm.a * ctm.a + ctm.b * ctm.b);
}
}
if (style.strokeLinecap !== 'butt') {
len += parseInt(style.strokeWidth);
}
@ -275,6 +284,7 @@ export function crossfade({ fallback, ...defaults }) {
easing,
css: (t, u) => `
opacity: ${t * opacity};
mix-blend-mode: plus-lighter;
transform-origin: top left;
transform: ${transform} translate(${u * dx}px,${u * dy}px) scale(${t + (1 - t) * dw}, ${
t + (1 - t) * dh

Loading…
Cancel
Save