2017-10-26 20:28:17 -04:00
|
|
|
import paper from '@scratch/paper';
|
|
|
|
import {getSelectedRootItems} from './selection';
|
|
|
|
|
2018-05-01 16:18:24 -04:00
|
|
|
// 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;
|
2018-04-16 18:08:17 -04:00
|
|
|
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));
|
|
|
|
}
|
2018-04-16 18:08:17 -04:00
|
|
|
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
|
|
|
}
|
2018-04-16 18:08:17 -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
|
|
|
};
|
|
|
|
|
2017-10-26 20:28:17 -04:00
|
|
|
// Zoom keeping the selection center (if any) fixed.
|
2017-10-27 09:33:06 -04:00
|
|
|
const zoomOnSelection = deltaZoom => {
|
2017-10-26 20:28:17 -04:00
|
|
|
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 = () => {
|
2018-04-16 18:08:17 -04:00
|
|
|
paper.project.view.zoom = .5;
|
2018-08-16 16:49:43 -04:00
|
|
|
clampViewBounds();
|
2017-10-26 20:28:17 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
const pan = (dx, dy) => {
|
|
|
|
paper.project.view.scrollBy(new paper.Point(dx, dy));
|
2018-08-16 16:49:43 -04:00
|
|
|
clampViewBounds();
|
2017-10-26 20:28:17 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
export {
|
2018-04-16 18:08:17 -04:00
|
|
|
ART_BOARD_HEIGHT,
|
|
|
|
ART_BOARD_WIDTH,
|
2018-05-01 16:18:24 -04:00
|
|
|
SVG_ART_BOARD_WIDTH,
|
|
|
|
SVG_ART_BOARD_HEIGHT,
|
2018-08-16 16:49:43 -04:00
|
|
|
clampViewBounds,
|
2017-10-26 20:28:17 -04:00
|
|
|
pan,
|
|
|
|
resetZoom,
|
|
|
|
zoomOnSelection,
|
|
|
|
zoomOnFixedPoint
|
2017-10-27 09:33:06 -04:00
|
|
|
};
|