198 lines
5.6 KiB
JavaScript
198 lines
5.6 KiB
JavaScript
'use strict';
|
|
|
|
var FrameHandler = require('./FrameHandler');
|
|
var GoreHandler = require('./GoreHandler');
|
|
var RulerHandler = require('./RulerHandler');
|
|
var util = require('./util');
|
|
|
|
function Viewport(canvas) {
|
|
var _beams = [];
|
|
var _borderWidth = 2;
|
|
var _data = null;
|
|
var _rect;
|
|
var self = this;
|
|
|
|
/**
|
|
* Applies viewport to page
|
|
*/
|
|
function apply() {
|
|
var cropData = canvas.getImageData().getCropData();
|
|
canvas.remove(_rect);
|
|
|
|
_rect = new fabric.Rect({
|
|
evented: false,
|
|
fill: 'transparent',
|
|
width: _data.width,
|
|
height: _data.height,
|
|
stroke: '#fff',
|
|
strokeWidth: canvas.__type === 'canvas' ? 0 : _borderWidth
|
|
});
|
|
|
|
_rect.width += _borderWidth;
|
|
_rect.height += _borderWidth;
|
|
_rect.addTo(canvas).center().setCoords();
|
|
|
|
if (cropData) {
|
|
// Calculate the new position after screenresize and when the
|
|
// image already has been cropped to a certain position.
|
|
var left = _rect.left + _rect.strokeWidth - (canvas.getImage().width * canvas.getImage().scaleX * cropData.x);
|
|
var top = _rect.top + _rect.strokeWidth - (canvas.getImage().height * canvas.getImage().scaleY * cropData.y);
|
|
|
|
canvas.getImage().set({ left: left, top: top }).setCoords();
|
|
} else {
|
|
canvas.getImage().center().setCoords();
|
|
}
|
|
|
|
canvas.getImage().drag.enable(calcMinMaxBoundsForRect(_rect.getInsideBoundingRect(), canvas.getImage()));
|
|
canvas.getApertures().apply(_data.axis, _rect.getBoundingRect());
|
|
|
|
if (canvas.__type !== 'canvas') {
|
|
drawBeams();
|
|
} else {
|
|
self.setFrame(self.getFrameHandler().getFrameType());
|
|
}
|
|
|
|
canvas.getDragbars().apply();
|
|
// Apertures sometimes overlaps the viewports bounding rect.
|
|
// Solve this by bringing it to the front after apertures are applied.
|
|
_rect.bringToFront();
|
|
}
|
|
|
|
/**
|
|
* Render the diagonal lines from viewport to edge of the canvas
|
|
*/
|
|
function drawBeams() {
|
|
_beams.forEach(function (beam) {
|
|
canvas.remove(beam);
|
|
});
|
|
|
|
_beams = [];
|
|
|
|
// TOP LEFT
|
|
_beams.push(new fabric.Line(
|
|
[_rect.left, _rect.top, _rect.left - _rect.top, -1], {
|
|
stroke: '#fff',
|
|
strokeWidth: 2,
|
|
}
|
|
));
|
|
|
|
// TOP RIGHT
|
|
_beams.push(_beams[0].clone().set({ flipX: true, left: _rect.left + _rect.width }));
|
|
// BOTTOM RIGHT
|
|
_beams.push(_beams[1].clone().set({ flipY: true, top: _rect.top + _rect.height }));
|
|
// BOTTOM LEFT
|
|
_beams.push(_beams[0].clone().set({ flipY: true, top: _rect.top + _rect.height }));
|
|
|
|
_beams.forEach(function (o) {
|
|
canvas.add(o);
|
|
o.bringToFront();
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Gets an object with min / max values for each axis, based on the bounds
|
|
* of passed fabric.Rect
|
|
* @param {fabric.Rect} rect
|
|
* @return {Object}
|
|
*/
|
|
function calcMinMaxBoundsForRect(rect, img) {
|
|
return {
|
|
left: {
|
|
min: rect.left + rect.width - (img.width * img.scaleX),
|
|
max: rect.left
|
|
},
|
|
top: {
|
|
min: rect.top + rect.height - (img.height * img.scaleY),
|
|
max: rect.top
|
|
}
|
|
};
|
|
}
|
|
|
|
this.canvas = canvas;
|
|
|
|
this.getBounds = function () {
|
|
return _rect.getInsideBoundingRect();
|
|
};
|
|
|
|
/**
|
|
* @return {Viewport}
|
|
*/
|
|
this.reset = function () {
|
|
if (_data) {
|
|
return this.set(_data.dim.width, _data.dim.height, _data.dim.units);
|
|
}
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* @param {Number} width
|
|
* @param {Number} height
|
|
* @param {string} units
|
|
* @return {Viewport}
|
|
*/
|
|
this.set = function (width, height, units) {
|
|
var oldData = _data;
|
|
|
|
_data = util.calcCrop(canvas.getImage(), width, height, units);
|
|
|
|
var keepCropping = (oldData && !util.isAspectChanged(oldData.dim.width, oldData.dim.height, width, height));
|
|
if (keepCropping) {
|
|
canvas.getImageData().setCropData();
|
|
}
|
|
|
|
apply();
|
|
this.getGores().reset();
|
|
this.getRulers().reset();
|
|
|
|
if (canvas.getImage().__cropped && !keepCropping) {
|
|
canvas.getApertures().setTransparent(true);
|
|
|
|
// Trigger event to tell the image needs to be dragged.
|
|
$(document).trigger('PIE:needs-dragging', { axis: _data.axis });
|
|
}
|
|
|
|
canvas.getButtonMenu().bringToFront();
|
|
|
|
};
|
|
|
|
/**
|
|
* @param {string} frameType white|black|image|none
|
|
* @return {Viewport}
|
|
*/
|
|
this.setFrame = function (frameType) {
|
|
this.getFrameHandler().setFrames(frameType);
|
|
|
|
var buttons = canvas.getButtonMenu().getItems();
|
|
if (frameType === 'none') {
|
|
buttons[0].setDisabled(true);
|
|
}
|
|
else {
|
|
buttons[0].setDisabled(false);
|
|
}
|
|
canvas.getButtonMenu().bringToFront();
|
|
|
|
canvas.refresh3dView();
|
|
};
|
|
|
|
this.getData = function () {
|
|
return _data;
|
|
};
|
|
|
|
var _frameHandler = null;
|
|
|
|
this.getFrameHandler = function () {
|
|
return _frameHandler || (_frameHandler = new FrameHandler(this));
|
|
};
|
|
|
|
this.getGores = function () {
|
|
return this.__goreHandler || (this.__goreHandler = new GoreHandler(this));
|
|
};
|
|
|
|
this.getRulers = function () {
|
|
return this.__rulerHandler || (this.__rulerHandler = new RulerHandler(this));
|
|
};
|
|
|
|
}
|
|
|
|
module.exports = Viewport;
|