Skip to content

Commit 3de5495

Browse files
author
Mathieu Legault
committed
Resize and sizing cleanup
1 parent 1fdfee8 commit 3de5495

File tree

1 file changed

+29
-60
lines changed

1 file changed

+29
-60
lines changed

fern/rive-animation.js

Lines changed: 29 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
aspectRatio, // e.g., 369/93 or 16/9
1212
stateMachine = "State Machine 1",
1313
fallbackImages = [], // Array of {src, className, alt}
14-
fit = 'Contain', // Rive fit mode
14+
fit = 'Contain', // Rive fit mode (Contain, Cover, FitWidth, FitHeight, None)
1515
eventHandlers = {} // Custom event handlers: {'Event Name': (eventData) => {...}}
1616
} = config;
1717

@@ -44,40 +44,25 @@
4444
}
4545

4646
try {
47-
// Calculate correct dimensions with high-DPI support
48-
const rect = riveContainer.getBoundingClientRect();
49-
50-
// Use available width, fallback to a reasonable default if container has no width yet
51-
const width = rect.width > 0 ? rect.width : 800;
52-
const height = width / aspectRatio; // Force correct aspect ratio
53-
54-
// Set container dimensions to prevent layout shift
55-
riveContainer.style.width = width + 'px';
56-
riveContainer.style.height = height + 'px';
57-
58-
// Also ensure the parent container accommodates the content
59-
if (sdkRiveContainer) {
60-
sdkRiveContainer.style.minHeight = height + 'px';
47+
// Set container aspect ratio while respecting existing layout
48+
const currentWidth = riveContainer.offsetWidth || riveContainer.clientWidth;
49+
if (currentWidth > 0) {
50+
// Use existing width, set height based on aspect ratio
51+
riveContainer.style.height = (currentWidth / aspectRatio) + 'px';
52+
} else {
53+
// Fallback: use CSS aspect-ratio if container has no initial width
54+
riveContainer.style.aspectRatio = aspectRatio.toString();
55+
riveContainer.style.width = '100%';
6156
}
6257

63-
// Force minimum 2x resolution for crispness (even on non-retina displays)
64-
const dpr = Math.max(window.devicePixelRatio || 1, 2);
65-
canvas.width = width * dpr;
66-
canvas.height = height * dpr;
67-
68-
// Set explicit CSS size to prevent stretching
69-
canvas.style.width = width + 'px';
70-
canvas.style.height = height + 'px';
71-
canvas.style.display = 'block';
72-
73-
// Create Rive instance
58+
// Let Rive handle canvas sizing internally - much simpler!
7459
const r = new rive.Rive({
7560
src: riveUrl,
7661
canvas: canvas,
7762
autoplay: true,
7863
stateMachines: stateMachine,
7964
layout: new rive.Layout({
80-
fit: rive.Fit[fit],
65+
fit: rive.Fit[fit], // Configurable fit mode
8166
alignment: rive.Alignment.Center
8267
}),
8368
shouldDisableRiveListeners: false, // Enable native Rive interactions (hover, click, etc.)
@@ -86,6 +71,9 @@
8671
canvas.style.pointerEvents = 'auto';
8772
canvas.style.userSelect = 'none';
8873

74+
// Critical: Resize drawing surface to canvas after load
75+
r.resizeDrawingSurfaceToCanvas();
76+
8977
// Set up dynamic cursor changes based on Rive's interactive areas
9078
setupDynamicCursor(canvas, r, stateMachine);
9179

@@ -110,38 +98,19 @@
11098
// Store instance for cleanup
11199
canvas._riveInstance = r;
112100

113-
// Add resize observer for responsive behavior
114-
const resizeObserver = new ResizeObserver(entries => {
115-
for (let entry of entries) {
116-
if (entry.target === riveContainer) {
117-
const newWidth = entry.contentRect.width;
118-
if (newWidth > 0) {
119-
const newHeight = newWidth / aspectRatio;
120-
121-
// Update container size
122-
riveContainer.style.height = newHeight + 'px';
123-
if (sdkRiveContainer) {
124-
sdkRiveContainer.style.minHeight = newHeight + 'px';
125-
}
126-
127-
// Update canvas size
128-
const dpr = Math.max(window.devicePixelRatio || 1, 2);
129-
canvas.width = newWidth * dpr;
130-
canvas.height = newHeight * dpr;
131-
canvas.style.width = newWidth + 'px';
132-
canvas.style.height = newHeight + 'px';
133-
134-
// Resize Rive animation
135-
if (r && r.resizeDrawingSurfaceToCanvas) {
136-
r.resizeDrawingSurfaceToCanvas();
137-
}
138-
}
139-
}
101+
// Simple resize handling (following Rive best practices)
102+
const windowResizeHandler = () => {
103+
// Let Rive handle the canvas sizing internally
104+
if (r && r.resizeDrawingSurfaceToCanvas) {
105+
r.resizeDrawingSurfaceToCanvas();
140106
}
141-
});
107+
};
108+
109+
// Add window resize listener (as per Rive documentation)
110+
window.addEventListener('resize', windowResizeHandler, false);
142111

143-
resizeObserver.observe(riveContainer);
144-
canvas._resizeObserver = resizeObserver;
112+
// Store cleanup function
113+
canvas._windowResizeHandler = windowResizeHandler;
145114

146115
} catch (error) {
147116
console.error('Rive creation error:', error);
@@ -329,9 +298,9 @@
329298
canvas._riveInstance.cleanup();
330299
canvas._riveInstance = null;
331300
}
332-
if (canvas._resizeObserver) {
333-
canvas._resizeObserver.disconnect();
334-
canvas._resizeObserver = null;
301+
if (canvas._windowResizeHandler) {
302+
window.removeEventListener('resize', canvas._windowResizeHandler, false);
303+
canvas._windowResizeHandler = null;
335304
}
336305
});
337306
}

0 commit comments

Comments
 (0)