scratch-paint/src/helper/view.js

76 lines
2.2 KiB
JavaScript

import paper from '@scratch/paper';
import {getSelectedRootItems} from './selection';
const ART_BOARD_WIDTH = 480 * 2;
const ART_BOARD_HEIGHT = 360 * 2;
const clampViewBounds = () => {
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));
}
if (right > ART_BOARD_WIDTH) {
paper.project.view.scrollBy(new paper.Point(ART_BOARD_WIDTH - right, 0));
}
};
// 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;
const newZoom = Math.max(1, view.zoom + deltaZoom);
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));
clampViewBounds();
};
// Zoom keeping the selection center (if any) fixed.
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;
clampViewBounds();
};
const pan = (dx, dy) => {
paper.project.view.scrollBy(new paper.Point(dx, dy));
clampViewBounds();
};
export {
ART_BOARD_HEIGHT,
ART_BOARD_WIDTH,
clampViewBounds,
pan,
resetZoom,
zoomOnSelection,
zoomOnFixedPoint
};