Refactor/reacrhitecture to fsd+ #49
@@ -61,14 +61,6 @@ const SLIDER_SPRING_CONFIG = { stiffness: 0.2, damping: 0.7 } as const;
|
||||
*/
|
||||
const SLIDER_PERSIST_DEBOUNCE_MS = 100;
|
||||
|
||||
/**
|
||||
* Horizontal layout padding subtracted from container width before laying
|
||||
* out the comparison text. Different per breakpoint to match the gutters
|
||||
* around the slider track.
|
||||
*/
|
||||
const SLIDER_PADDING_MOBILE_PX = 48;
|
||||
const SLIDER_PADDING_DESKTOP_PX = 96;
|
||||
|
||||
/**
|
||||
* Position bounds (percent of container width).
|
||||
*/
|
||||
@@ -94,7 +86,18 @@ const isMobile = $derived(responsive?.isMobile ?? false);
|
||||
|
||||
let isDragging = $state(false);
|
||||
let isTypographyMenuOpen = $state(false);
|
||||
/**
|
||||
* Border-box width of the slider track. Drives the slider→position mapping and
|
||||
* the per-char split math (pointer events are measured against this same box).
|
||||
*/
|
||||
let containerWidth = $state(0);
|
||||
/**
|
||||
* Content-box width of the slider track (border box minus the responsive CSS
|
||||
* gutters). The width the text lays out into, and what the line-breaker fits
|
||||
* within. Measured rather than derived from a padding constant so it tracks the
|
||||
* breakpoint gutters.
|
||||
*/
|
||||
let contentWidth = $state(0);
|
||||
|
||||
const layout = new DualFontLayout();
|
||||
|
||||
@@ -114,10 +117,14 @@ $effect(() => {
|
||||
|
||||
const observer = new ResizeObserver(entries => {
|
||||
for (const entry of entries) {
|
||||
// Use borderBoxSize if available, fallback to contentRect
|
||||
const width = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
|
||||
if (width > 0) {
|
||||
containerWidth = width;
|
||||
// Border box for slider/pointer math, content box for text width.
|
||||
const border = entry.borderBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
|
||||
const content = entry.contentBoxSize?.[0]?.inlineSize ?? entry.contentRect.width;
|
||||
if (border > 0) {
|
||||
containerWidth = border;
|
||||
}
|
||||
if (content > 0) {
|
||||
contentWidth = content;
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -226,7 +233,7 @@ $effect(() => {
|
||||
}
|
||||
});
|
||||
|
||||
// Layout effect — depends on content, settings AND containerWidth.
|
||||
// Layout effect — depends on content, settings, and contentWidth.
|
||||
// Awaits font loading into the canvas measurement context before invoking
|
||||
// the engine; otherwise pretext caches fallback-font widths globally per
|
||||
// font string, and the morph boundary drifts from the thumb visually.
|
||||
@@ -236,18 +243,15 @@ $effect(() => {
|
||||
const _size = typography.renderedSize;
|
||||
const _height = typography.height;
|
||||
const _spacing = typography.spacing;
|
||||
const _width = containerWidth;
|
||||
const _isMobile = isMobile;
|
||||
const availableWidth = contentWidth;
|
||||
|
||||
if (!container || !fontA || !fontB || _width <= 0) {
|
||||
if (!container || !fontA || !fontB || availableWidth <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fontAStr = getPretextFontString(_weight, _size, fontA.name);
|
||||
const fontBStr = getPretextFontString(_weight, _size, fontB.name);
|
||||
|
||||
const padding = _isMobile ? SLIDER_PADDING_MOBILE_PX : SLIDER_PADDING_DESKTOP_PX;
|
||||
const availableWidth = Math.max(0, _width - padding);
|
||||
const lineHeight = _size * _height;
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
Reference in New Issue
Block a user