scratch-paint/src/helper/view.js

84 lines
2.4 KiB
JavaScript
Raw Normal View History

import paper from '@scratch/paper';
import {getSelectedRootItems} from './selection';
// Vectors are imported and exported at SVG_ART_BOARD size.
// Once they are imported however, both SVGs and bitmaps are on
// canvases of ART_BOARD size.
const SVG_ART_BOARD_WIDTH = 480;
const SVG_ART_BOARD_HEIGHT = 360;
const ART_BOARD_WIDTH = 480 * 2;
const ART_BOARD_HEIGHT = 360 * 2;
2018-08-16 16:49:43 -04:00
const clampViewBounds = () => {
2017-10-27 09:33:06 -04:00
const {left, right, top, bottom} = paper.project.view.bounds;
if (left < 0) {
paper.project.view.scrollBy(new paper.Point(-left, 0));
}
if (top < 0) {
paper.project.view.scrollBy(new paper.Point(0, -top));
}
if (bottom > ART_BOARD_HEIGHT) {
paper.project.view.scrollBy(new paper.Point(0, ART_BOARD_HEIGHT - bottom));
2017-10-27 09:33:06 -04:00
}
if (right > ART_BOARD_WIDTH) {
paper.project.view.scrollBy(new paper.Point(ART_BOARD_WIDTH - right, 0));
2017-10-27 09:33:06 -04:00
}
};
2017-10-27 10:06:01 -04:00
// Zoom keeping a project-space point fixed.
// This article was helpful http://matthiasberth.com/tech/stable-zoom-and-pan-in-paperjs
const zoomOnFixedPoint = (deltaZoom, fixedPoint) => {
const {view} = paper.project;
const preZoomCenter = view.center;
2018-04-20 11:20:38 -04:00
const newZoom = Math.max(0.5, view.zoom + deltaZoom);
2017-10-27 10:06:01 -04:00
const scaling = view.zoom / newZoom;
const preZoomOffset = fixedPoint.subtract(preZoomCenter);
const postZoomOffset = fixedPoint.subtract(preZoomOffset.multiply(scaling))
.subtract(preZoomCenter);
view.zoom = newZoom;
view.translate(postZoomOffset.multiply(-1));
2018-08-16 16:49:43 -04:00
clampViewBounds();
2017-10-27 10:06:01 -04:00
};
// Zoom keeping the selection center (if any) fixed.
2017-10-27 09:33:06 -04:00
const zoomOnSelection = deltaZoom => {
let fixedPoint;
const items = getSelectedRootItems();
if (items.length > 0) {
let rect = null;
for (const item of items) {
if (rect) {
rect = rect.unite(item.bounds);
} else {
rect = item.bounds;
}
}
fixedPoint = rect.center;
} else {
fixedPoint = paper.project.view.center;
}
zoomOnFixedPoint(deltaZoom, fixedPoint);
};
const resetZoom = () => {
paper.project.view.zoom = .5;
2018-08-16 16:49:43 -04:00
clampViewBounds();
};
const pan = (dx, dy) => {
paper.project.view.scrollBy(new paper.Point(dx, dy));
2018-08-16 16:49:43 -04:00
clampViewBounds();
};
export {
ART_BOARD_HEIGHT,
ART_BOARD_WIDTH,
SVG_ART_BOARD_WIDTH,
SVG_ART_BOARD_HEIGHT,
2018-08-16 16:49:43 -04:00
clampViewBounds,
pan,
resetZoom,
zoomOnSelection,
zoomOnFixedPoint
2017-10-27 09:33:06 -04:00
};