vue-poster-editor
Version:
A poster editor based on Vue.js
334 lines (264 loc) • 11.3 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _throttle2 = require('lodash/throttle');
var _throttle3 = _interopRequireDefault(_throttle2);
var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
var _bluebird = require('bluebird');
var _bluebird2 = _interopRequireDefault(_bluebird);
var _canvasFilters = require('canvas-filters');
var _canvasFilters2 = _interopRequireDefault(_canvasFilters);
var _utils = require('../utils/utils');
var _utils2 = _interopRequireDefault(_utils);
var _vueInherit = require('../utils/vue-inherit');
var _vueInherit2 = _interopRequireDefault(_vueInherit);
var _editorElement = require('./editor-element');
var _editorElement2 = _interopRequireDefault(_editorElement);
var _editorElementImage = require('./editor-element-image.html');
var _editorElementImage2 = _interopRequireDefault(_editorElementImage);
var _imageEffect = require('../utils/image-effect');
var _imageEffect2 = _interopRequireDefault(_imageEffect);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
exports.default = (0, _vueInherit2.default)(_editorElement2.default, {
template: _editorElementImage2.default,
data: function data() {
return {
usePlaceholder: false,
isImageEffectReady: true
};
},
computed: {
showOriginImage: function showOriginImage() {
return !this.effectedImageUrl || this.model.$editing || !this.isImageEffectReady;
},
imageUrl: function imageUrl() {
var model = this.model,
options = this.options;
return _utils2.default.getComputedUrl(model.url, options.fitCrossOrigin);
},
effectedImageUrl: function effectedImageUrl() {
return this.model.effectedImage;
},
clip: function clip() {
return this.rect.clip;
},
outerHeight: function outerHeight() {
var rect = this.rect;
var clip = rect.clip;
return rect.height + clip.top + clip.bottom;
},
outerWidth: function outerWidth() {
var rect = this.rect;
var clip = rect.clip;
return rect.width + clip.left + clip.right;
},
cssStyle: function cssStyle() {
var rect = this.rect;
var padding = rect.padding;
return {
height: rect.height + padding[0] + padding[2] + 'px',
width: rect.width + padding[1] + padding[3] + 'px',
transform: this.transform.toString(),
left: rect.left + 'px',
top: rect.top + 'px',
opacity: this.opacity
};
},
canvas: function canvas() {
return this.$refs.canvas;
},
canvasStyle: function canvasStyle() {
return {
position: 'absolute',
width: this.outerWidth + 'px',
height: this.outerHeight + 'px',
left: -this.clip.left + 'px',
top: -this.clip.top + 'px'
};
},
effectedCanvasStyle: function effectedCanvasStyle() {
var model = this.model;
var zoom = this.global.zoom;
var scaleX = zoom * model.width / model.originWidth;
var scaleY = zoom * model.height / model.originHeight;
var style = {
position: 'absolute',
width: model.effectedImageWidth * scaleX + 'px',
height: model.effectedImageHeight * scaleY + 'px',
left: model.effectedImageOffsetLeft * scaleX + 'px',
top: model.effectedImageOffsetTop * scaleY + 'px',
pointerEvents: 'none'
};
return style;
},
imageScale: function imageScale() {
var model = this.model;
var $naturalWidth = model.$naturalWidth,
$naturalHeight = model.$naturalHeight,
width = model.width,
height = model.height;
if (!model.clip) {
model.clip = {
bottom: 0,
right: 0,
left: 0,
top: 0
};
}
var currentWidth = width + model.clip.left + model.clip.right;
var currentHeight = height + model.clip.top + model.clip.bottom;
return Math.max(currentWidth / $naturalWidth, currentHeight / $naturalHeight);
}
},
methods: {
load: function load() {
var _this = this;
var _model = this.model,
url = _model.url,
effectedImage = _model.effectedImage;
if (!url) {
return _bluebird2.default.resolve();
}
if (this.isFilters) {
return this.applyFilter();
}
return _bluebird2.default.all([_utils2.default.loadImage(url, this.options.fitCrossOrigin), effectedImage ? _utils2.default.loadImage(effectedImage, this.options.fitCrossOrigin) : _bluebird2.default.resolve()]).then(function (_ref) {
var _ref2 = _slicedToArray(_ref, 1),
img = _ref2[0];
_this.model.$naturalWidth = img.naturalWidth;
_this.model.$naturalHeight = img.naturalHeight;
return img;
});
},
applyFilter: function applyFilter() {
var _this2 = this;
var model = this.model,
options = this.options;
return _utils2.default.loadImage(model.url, options.fitCrossOrigin).then(function (img) {
var canvas = _this2.canvas;
var ctx = canvas ? canvas.getContext('2d') : null;
if (!ctx) {
throw new Error('Canvas init error');
}
var outerWidth = _this2.outerWidth,
outerHeight = _this2.outerHeight;
var _model$filter = model.filter,
hueRotate = _model$filter.hueRotate,
saturate = _model$filter.saturate,
brightness = _model$filter.brightness;
canvas.width = outerWidth;
canvas.height = outerHeight;
ctx.drawImage(img, 0, 0, outerWidth, outerHeight);
var imgData = ctx.getImageData(0, 0, outerWidth, outerHeight, 0, 0, img.width, img.height);
var filterdImgData = _canvasFilters2.default.HSLAdjustment(imgData, hueRotate, saturate, brightness);
ctx.putImageData(filterdImgData, 0, 0);
});
},
updateFilter: function updateFilter() {
clearTimeout(this.updateFilterTimer);
if (!this.isFilters) {
return;
}
this.updateFilterTimer = setTimeout(this.applyFilter, 172);
},
applyImageEffectLazy: function applyImageEffectLazy() {
var delay = 80;
if (!this._applyImageEffectLazy) {
this._applyImageEffectLazy = (0, _throttle3.default)(this.applyImageEffect, delay, {
trailing: true,
leading: true
});
}
return this._applyImageEffectLazy();
},
applyImageEffect: function applyImageEffect() {
var _this3 = this;
var model = this.model,
options = this.options;
if (!this.imageEffectApp) {
this.imageEffectApp = new _imageEffect2.default();
}
var app = this.imageEffectApp;
return _utils2.default.loadImage(model.url, options.fitCrossOrigin).then(function (img) {
return app.applyEffects(img, {
effects: model.imageEffects,
width: model.width,
height: model.height,
clip: model.clipModel || model.clip,
lastHash: model.imageEffectsHash,
scale: _this3.imageScale
});
}).then(function (data) {
return Object.assign(model, data);
});
}
},
watch: {
'model.url': function modelUrl() {
this.checkLoad().then(this.applyImageEffectLazy);
},
'model.filter': {
deep: true,
handler: function handler() {
this.updateFilter();
}
},
'model.imageEffects': {
deep: true,
handler: function handler() {
this.applyImageEffectLazy();
}
}
},
events: {
'image.cancal.expand': function imageCancalExpand() {
if (this.model.imageEffects.length && this.model.imageEffects[0].expand.enable) {
this.model.imageEffects = [];
this.model.effectedImage = null;
}
},
'editor.edit.apply': function editorEditApply(model) {
var _this4 = this;
if (model.$id !== this.model.$id || model.type !== '$croper' || !model.effectedImage) {
return;
}
var clippedHeight = 0;
var clippedWidth = 0;
if (model.clipModel) {
clippedWidth = model.clipModel.left + model.clipModel.right;
clippedHeight = model.clipModel.top + model.clipModel.bottom;
}
this.model.originWidth -= clippedWidth;
this.model.originHeight -= clippedHeight;
this.isImageEffectReady = false;
this.applyImageEffectLazy().then(function () {
_this4.isImageEffectReady = true;
});
},
'editor.transform.inactive': function editorTransformInactive(model) {
if (model !== this.model || !model.effectedImage) {
return;
}
this.applyImageEffectLazy();
},
'editor.element.error.load': function editorElementErrorLoad(e, model) {
if (model === this.model) {
this.usePlaceholder = true;
}
}
},
mounted: function mounted() {
this.model.$resizeLimit = true;
this.model.$getResizeLimit = function () {
return {
maxWidth: Infinity,
minWidth: 2,
maxHeight: Infinity,
minHeight: 2
};
};
this.updateFilter();
}
});
module.exports = exports['default'];