@daign/2d-graphics
Version:
Two dimensional graphics library that implements the daign-2d-pipeline.
119 lines (118 loc) • 5.52 kB
JavaScript
;
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;