Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
import { Gesture } from 'app/pages/editor/scripts/paper/gesture';
import { PaperLayer } from 'app/pages/editor/scripts/paper/item';
import { PaperService } from 'app/pages/editor/services';
import * as paper from 'paper';
/**
* A gesture that selects one or more items using a selection box.
*
* Preconditions:
* - The user is in default mode.
*/
export class BatchSelectItemsGesture extends Gesture {
private readonly pl = paper.project.activeLayer as PaperLayer;
// private initialSelectedLayers: ReadonlySet;
constructor(private readonly ps: PaperService) {
super();
}
// @Override
onMouseDown(event: paper.ToolEvent) {
if (!event.modifiers.shift) {
// A selection box implies that the gesture began with a failed hit test,
// so deselect everything on mouse down (unless the user is holding shift).
this.ps.setSelectedLayerIds(new Set());
}
// TODO: make use of this information (i.e. toggle the layers when shift is pressed)
// this.initialSelectedLayers = this.ps.getSelectedLayerIds();
}
guideLayer.bringToFront();
guideLayer.name = "guide";
const scaleGuide = (item, zoom) => {
if (item.data.isMarker) {
item.scaling = 1 / zoom;
}
if (item.children) {
item.children.forEach(child => scaleGuide(child, zoom));
}
};
paper.project.view.applyMatrix = false;
paper.project.view.on("zoom", zoom => {
guideLayer.children.forEach(child => {
scaleGuide(child, zoom);
});
});
activeLayer.activate();
// canvas navigation
{
let px,
py,
isDragging = false;
const mousedown = ({ x, y, target }) => {
isDragging = true;
px = x;
export function getProjectScaling() {
// Given unit vectors u0 = (0, 1) and v0 = (1, 0).
//
// After matrix mapping, we get u1 and v1. Let Θ be the angle between u1 and v1.
// Then the final scale we want is:
//
// Math.min(|u1|sin(Θ),|v1|sin(Θ)) = |u1||v1|sin(Θ) / Math.max(|u1|,|v1|)
//
// If Math.max(|u1|,|v1|) = 0, that means either x or y has a scale of 0.
//
// For the non-skew case, which is most of the cases, matrix scale is
// computing exactly the scale on x and y axis, and take the minimal of these two.
//
// For the skew case, an unit square will mapped to a parallelogram,
// and this function will return the minimal height of the 2 bases.
const { matrix } = paper.project.activeLayer;
const m = new paper.Matrix(matrix.a, matrix.b, matrix.c, matrix.d, 0, 0);
const u0 = new paper.Point(0, 1);
const v0 = new paper.Point(1, 0);
const u1 = u0.transform(m);
const v1 = v0.transform(m);
const sx = Math.hypot(u1.x, u1.y);
const sy = Math.hypot(v1.x, v1.y);
const dotProduct = u1.y * v1.x - u1.x * v1.y;
const maxScale = Math.max(sx, sy);
return maxScale > 0 ? Math.abs(dotProduct) / maxScale : 0;
}
import { PaperLayer } from 'app/modules/editor/scripts/paper/item';
import { PaperUtil } from 'app/modules/editor/scripts/paper/util';
import { PaperService } from 'app/modules/editor/services';
import * as paper from 'paper';
/**
* A gesture that allows the user to mould a curve by dragging a point on its path.
*
* Based on math from here: https://pomax.github.io/bezierinfo/#moulding
*
* Preconditions:
* - The user is in edit path mode.
* - The user hit one of the edit path's curves.
*/
export class MouldCurveGesture extends Gesture {
private readonly pl = paper.project.activeLayer as PaperLayer;
private points: CubicPoints;
private B: paper.Point;
private C: paper.Point;
private ratio: number;
private t: number;
// TODO: update HoverSegmentsCurvesGesture to *not* display a split path dot when command is held down
// TODO: handle cases where t === 0 and t === 1?
constructor(
private readonly ps: PaperService,
private readonly editPathId: string,
private readonly hitCurveInfo: Readonly<{ curveIndex: number; time: number }>,
) {
super();
}
import { MathUtil } from 'app/scripts/common';
import { PaperLayer } from 'app/scripts/paper/item';
import { PaperUtil } from 'app/scripts/paper/util';
import { PaperService } from 'app/services';
import * as _ from 'lodash';
import * as paper from 'paper';
/**
* A helper class that processes mouse events before they are dispatched and
* determines if currently selected items should be snapped to other items
* in the project as a result.
*/
export class MouseSnapper {
private readonly paperLayer = paper.project.activeLayer as PaperLayer;
constructor(private readonly ps: PaperService) {}
// TODO: return immediately in onMouseEvent() if the command key is pressed?
// TODO: listen for and react to command key down/up events
// TODO: figure out how to snap cloned items that were created mid-drag
// TODO: also add the entire artwork's bounds as a guide as well?
getSnapInfo(event: paper.ToolEvent): SnapInfo {
if (event.type !== 'mousedrag') {
return undefined;
}
const dragItems = Array.from(this.ps.getSelectedLayers()).map(id =>
this.paperLayer.findItemByLayerId(id),
);
if (!dragItems.length) {
return undefined;
destroy() {
$(Paper.project.view.element).off("wheel");
}
this.down = function (event) {
Registry.viewManager.killParamsWindow();
paper.project.deselectAll();
ref.createNewFeature(MouseTool.getEventPosition(event));
}
}
import { Line } from 'app/modules/editor/store/paper/actions';
import * as _ from 'lodash';
import * as paper from 'paper';
/**
* A gesture that performs scaling operations.
*
* Preconditions:
* - The user is in default mode.
* - One or more layers are selected.
* - A mouse down event occurred on a selection bounds handle.
*
* TODO: should we also scale the stroke width?
*/
export class ScaleItemsGesture extends Gesture {
private readonly pl = paper.project.activeLayer as PaperLayer;
private selectedItems: ReadonlyArray;
private localToVpItemMatrices: ReadonlyArray;
private vpInitialPivot: paper.Point;
private vpInitialSize: paper.Point;
private vpInitialCenteredSize: paper.Point;
private vpInitialCenter: paper.Point;
private vpInitialDraggedSegment: paper.Point;
private vpDownPoint: paper.Point;
private vpPoint: paper.Point;
private initialVectorLayer: VectorLayer;
constructor(
private readonly ps: PaperService,
private readonly selectionBoundsRaster: SelectionBoundsRaster,
) {
super();
if((event.ctrlKey || event.metaKey) && key == 83){
event.preventDefault();
reference.exportPanel.saveJSON();
}
if(key === 70){
//Reset the view
reference.view.initializeView();
reference.updateGrid();
reference.view.updateAlignmentMarks();
}
//Escape key
if(key === 27){
//Deselect all
paper.project.deselectAll();
//Change active tool to select tool
reference.resetToDefaultTool();
}
});
export function handleHoveredItem(hitOptions: paper.HitOptions, event: paper.ToolEvent) {
const hitResult = paper.project.hitTest(event.point, hitOptions);
if (!hitResult) {
clearHoveredItem();
return;
}
if (hitResult.item.data && hitResult.item.data.noHover) {
return;
}
clearHoveredItem();
const { item } = hitResult;
if (!item.selected) {
if (item instanceof paper.Shape) {
hoveredItem = GuideUtil.hoverBounds(item);
} else if (PaperUtil.isGroup(PaperUtil.findParentLayer(item))) {
hoveredItem = GuideUtil.hoverBounds(PaperUtil.findParentLayer(item));
} else {
hoveredItem = GuideUtil.hoverItem(hitResult);