UNPKG

@daign/2d-graphics

Version:

Two dimensional graphics library that implements the daign-2d-pipeline.

119 lines (118 loc) 5.52 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.Viewport = void 0; var math_1 = require("@daign/math"); var _2d_pipeline_1 = require("@daign/2d-pipeline"); var group_1 = require("../basic-elements/group"); /** * Group that acts as an viewport by applying a transformation to bring objects into the visible * area. * So this is just the top most node of the drawing layer. But the transformation it has is used * for zooming and panning the content around. */ var Viewport = /** @class */ (function (_super) { __extends(Viewport, _super); /** * Constructor. * @param context - The target drawing context. * @param application - The corresponding application. */ function Viewport(context, application) { var _this = _super.call(this) || this; _this.context = context; _this.application = application; // The transformations applied to the view's content. _this.decenteringTransform = new _2d_pipeline_1.NativeTranslateTransform(); _this.scaleTransform = new _2d_pipeline_1.NativeScaleTransform(); _this.translateTransform = new _2d_pipeline_1.NativeTranslateTransform(); // Content coordinates at the center of the viewport. _this.viewCenter = new math_1.Vector2(); // Scaling of the viewport content. _this.viewScale = new math_1.Value(1); // Minimum scale. _this.scaleMin = 0.001; // Maximum scale. _this.scaleMax = 1000; // Area limiting view center movements. _this.viewCenterLimit = new math_1.Box2(); _this.context = context; _this.application = application; // Initialize with unlimited view center limit. _this.viewCenterLimit.makeUnlimited(); // Add the transformations that transform the viewport. _this.scaleTransform.scaling.set(1, 1); _this.transformation.push(_this.translateTransform); _this.transformation.push(_this.scaleTransform); _this.transformation.push(_this.decenteringTransform); // Automatically update viewport when center or scale changes. _this.viewCenter.subscribeToChanges(function () { _this.updateViewport(); }); _this.viewScale.subscribeToChanges(function () { _this.updateViewport(); }); return _this; } /** * Set view center and scale so that the content is fully zoomed in the center of the viewport. * @param margin - The margin to leave around the content. Optional. */ Viewport.prototype.fitToContent = function (margin) { var contentBox = this.getBox(); // Expand area of interest by margin. if (margin) { contentBox.expandByScalar(margin); } var scaling = this.context.size.clone().divide(contentBox.size); // Scaling is the same in both directions. // Set silent so that updateViewport can be called once at the end. this.viewScale.setSilent(Math.min(scaling.x, scaling.y)); var newCenter = contentBox.min.clone().add(contentBox.size.clone().multiplyScalar(0.5)); this.viewCenter.copySilent(newCenter); this.updateViewport(); }; /** * Set view center and scale so that the coordinates translate one-to-one to context coordinates. */ Viewport.prototype.fitToContextSize = function () { // Set center of target's drawing space as center. var newCenter = this.context.size.clone().multiplyScalar(0.5); this.viewCenter.copySilent(newCenter); this.viewScale.setSilent(1); this.updateViewport(); }; /** * Calculate and apply the transformations that result from the view center and scale properties. */ Viewport.prototype.updateViewport = function () { // Apply limits to center and scale. var limitedCenter = this.viewCenter.clone().clampInBox(this.viewCenterLimit); this.viewCenter.copySilent(limitedCenter); var limitedScale = this.viewScale.clone().clamp(this.scaleMin, this.scaleMax); this.viewScale.setSilent(limitedScale.x); // Move the center of the view to (0,0) to keep it unaffected from the scaling. var decentering = new math_1.Vector2(-this.viewCenter.x, -this.viewCenter.y); var scaling = new math_1.Vector2(this.viewScale.x, this.viewScale.x); var translation = this.context.size.clone().multiplyScalar(0.5); this.decenteringTransform.translation.copy(decentering); this.scaleTransform.scaling.copy(scaling); this.translateTransform.translation.copy(translation); }; return Viewport; }(group_1.Group)); exports.Viewport = Viewport;