FIT TO CANVAS #105
-
I'm loading an SVG using editor.loadFromSvg() but the loaded SVG doesn't fit the canvas/viewport. How can I automatically scale and/or position the loaded SVG to fit the canvas, either entirely within the canvas or to fill the canvas completely |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
One option might be to move the visible part of the canvas with Option 1import { Viewport } from 'js-draw';
import { Mat33, Vec2 } from '@js-draw/math';
// Enable autoresize (if not already enabled).
editor.dispatch(editor.image.setAutoresizeEnabled(true));
// Zooms the editor content such that its width matches the editor width
// (or height matches the editor height).
const zoomToContent = () => {
const svgRect = editor.getImportExportRect();
const currentVisibleRect = editor.viewport.visibleRect;
// Calculate how much we need to zoom in or out
const xScale = svgRect.width / currentVisibleRect.width;
const yScale = svgRect.height / currentVisibleRect.height;
const scaleAmount = Math.max(xScale, yScale);
// Zoom in by scaleAmount.
const viewportScale = Mat33.scaling2D(scaleAmount);
// Move such that svgRect.topLeft matches the canvas's top left
const moveAmount = svgRect.topLeft.minus(currentVisibleRect.topLeft);
const viewportTranslate = Mat33.translation(moveAmount);
// Combine the two transformations into one that scales, then updates
const viewportUpdate = viewportTranslate.rightMul(viewportScale);
// Invert, since we're moving the **canvas**, not the screen:
Viewport.transformBy(viewportUpdate.inverse()).apply(editor);
};
zoomToContent(); Option 2// Centers content, preserving the zoom
const centerContent = () => {
const svgRect = editor.getImportExportRect();
const currentVisibleRect = editor.viewport.visibleRect;
// Move the loaded SVG (by moving the canvas).
// moveAmount = Final - Initial
const moveAmount = currentVisibleRect.center.minus(svgRect.center);
// Important: moveAmount moves the **canvas**, not the screen.
// Apply the amount to move:
const viewportTranslate = Mat33.translation(moveAmount);
Viewport.transformBy(viewportTranslate).apply(editor);
};
const zoomToAndCenterContent = () => {
const svgRect = editor.getImportExportRect();
// Calculate how much we need to zoom the canvas in or out
// xScale = finalScale / initialScale
const xScale = editor.display.width / svgRect.width;
// yScale = finalScale / initialScale
const yScale = editor.display.height / svgRect.height;
const scaleAmount = Math.min(xScale, yScale);
// Zoom in by scaleAmount.
// Note: This discards the previous translation/rotation/scale
// of the viewport.
const viewportScale = Mat33.scaling2D(scaleAmount);
editor.viewport.resetTransform(viewportScale);
centerContent();
};
zoomToAndCenterContent(); There's may be a simpler way to do this. (For example, Please let me know if you have any follow-up questions! Edited: Added a second example, expanded explanation. |
Beta Was this translation helpful? Give feedback.
One option might be to move the visible part of the canvas with
Viewport.transformBy
:Option 1