UNPKG

vue-poster-editor

Version:

A poster editor based on Vue.js

275 lines (214 loc) 9.55 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _debounce2 = require('lodash/debounce'); var _debounce3 = _interopRequireDefault(_debounce2); var _bluebird = require('bluebird'); var _bluebird2 = _interopRequireDefault(_bluebird); var _utils = require('../utils/utils'); var _utils2 = _interopRequireDefault(_utils); var _vueInherit = require('../utils/vue-inherit'); var _vueInherit2 = _interopRequireDefault(_vueInherit); var _canvas = require('../utils/canvas'); var _editorElement = require('./editor-element'); var _editorElement2 = _interopRequireDefault(_editorElement); var _editorElementMask = require('./editor-element-mask.html'); var _editorElementMask2 = _interopRequireDefault(_editorElementMask); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var max = Math.max, round = Math.round; exports.default = (0, _vueInherit2.default)(_editorElement2.default, { template: _editorElementMask2.default, computed: { zoom: function zoom() { return this.global.zoom; }, imageUrl: function imageUrl() { var model = this.model, options = this.options; return _utils2.default.getComputedUrl(model.imageUrl, options.fitCrossOrigin); }, 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 }; }, 'urlAndMask': function urlAndMask() { return this.model.url + this.model.mask; }, 'imageWidthAndImageHeight': function imageWidthAndImageHeight() { return this.model.imageWidth + this.model.imageHeight; }, 'modelWidthAndModelHeight': function modelWidthAndModelHeight() { return this.model.width + this.model.height; }, 'imageTransformPosition': function imageTransformPosition() { return this.model.imageTransform.position.x + this.model.imageTransform.position.y; }, 'imageTransformRotation': function imageTransformRotation() { return this.model.imageTransform.rotation; } }, methods: { load: function load() { var model = this.model, options = this.options; var fitCrossOrigin = options.fitCrossOrigin; var loadImage = _utils2.default.loadImage; var promise = model.imageUrl ? loadImage(model.imageUrl, fitCrossOrigin) : this.updateMask(); if (!model.imageUrl || options.mode !== 'mirror') { promise = promise.then(function () { return loadImage(model.url, fitCrossOrigin); }).then(function (originalImg) { model.$naturalHeight = originalImg.naturalHeight; model.$naturalWidth = originalImg.naturalWidth; }); } return promise; }, getCanvas: function getCanvas() { var canvas = this.$canvas; if (!canvas) { canvas = this.$canvas = (0, _canvas.createCanvas)(100, 100); } return _bluebird2.default.resolve(canvas); }, getContext: function getContext() { var _this = this; var model = this.model, options = this.options; return _bluebird2.default.all([_utils2.default.loadImage(model.url, options.fitCrossOrigin), _utils2.default.loadImage(model.mask, options.fitCrossOrigin)]).spread(function (img, mask) { _this.$img = img; _this.$mask = mask; return _this.updateStage(); }); }, updateStage: function updateStage() { var _this2 = this; return this.getCanvas().then(function (canvas) { var model = _this2.model; var context = canvas.getContext('2d'); var _options = _this2.options, maskResizeOptions = _options.maskResizeOptions, maskPixelRatio = _options.maskPixelRatio; var mask = _this2.$mask; var img = _this2.$img; if (!mask) { return; } var imageTransform = model.imageTransform; var imageWidth = model.imageWidth, imageHeight = model.imageHeight, width = model.width, height = model.height; var _imageTransform$posit = imageTransform.position, translateX = _imageTransform$posit.x, translateY = _imageTransform$posit.y; var pixelRatio = max(1, +maskPixelRatio || 1); var canvasWidth = round(width * pixelRatio); var canvasHeight = round(height * pixelRatio); canvas.width = canvasWidth; canvas.height = canvasHeight; context.scale(pixelRatio, pixelRatio); context.clearRect(0, 0, canvasWidth, canvasHeight); context.drawImage(mask, 0, 0, canvasWidth, canvasHeight); context.globalCompositeOperation = 'source-over'; var imageSize = { width: imageWidth, height: imageHeight }; var imageCenter = { x: translateX + imageSize.width / 2, y: translateY + imageSize.height / 2 }; return _bluebird2.default.try(function () { return (0, _canvas.resizeImageByCanvas)(img, imageWidth, imageHeight, maskResizeOptions); }).then(function (imgCanvas) { (0, _canvas.drawImageToCanvas)(canvas, imgCanvas, imageCenter, imageSize, imageTransform.rotation); return context; }); }); }, renderToImage: function renderToImage() { var _this3 = this; return this.getContext().then(function (context) { return _this3.rendererToBase64(context) || null; }); }, rendererToBase64: function rendererToBase64(context) { var hasOpacity = false; var pixels = null; pixels = context.getImageData(0, 0, context.canvas.width, context.canvas.height); pixels = pixels.data; var index = pixels.length - 1; while (index > 0) { if (pixels[index] !== 255) { hasOpacity = true; break; } index -= 4; } hasOpacity = true; var imageType = 'image/' + (hasOpacity ? 'png' : 'jpeg'); return context.canvas.toDataURL(imageType, 1) || null; }, updateMask: function updateMask() { var _this4 = this; var fitCrossOrigin = this.options.fitCrossOrigin; return this.renderToImage().tap(function (url) { return _utils2.default.loadImage(url, fitCrossOrigin); }).then(function (url) { _this4.model.imageUrl = url; return url; }); }, destoryRenderer: function destoryRenderer() {} }, events: { 'editor.transform.inactive': function editorTransformInactive(model, drag, datas) { if (this.model === model && datas.action === 'resize') { var widthRatio = model.width / drag.width; var heightRatio = model.height / drag.height; var position = model.imageTransform.position; model.imageWidth *= widthRatio; model.imageHeight *= heightRatio; position.x *= widthRatio; position.y *= heightRatio; } } }, mounted: function mounted() { var _this5 = this; this.model.$resizeLimit = true; this.model.$getResizeLimit = function () { return { maxWidth: Infinity, minWidth: 2, maxHeight: Infinity, minHeight: 2 }; }; var updateMaskImmediately = (0, _debounce3.default)(this.updateMask, 350, { 'leading': true, 'trailing': false }); var updateMaskFinished = (0, _debounce3.default)(this.updateMask, 350, { 'leading': false, 'trailing': true }); this.$watch('urlAndMask', function () { updateMaskImmediately(); _utils2.default.loadImage(_this5.model.url).then(function (img) { _this5.model.$naturalWidth = img.naturalWidth; _this5.model.$naturalHeight = img.naturalHeight; }); }); this.$watch('imageWidthAndImageHeight', updateMaskFinished); this.$watch('modelWidthAndModelHeight', updateMaskImmediately); this.$watch('imageTransformPosition', updateMaskImmediately); this.$watch('imageTransformRotation', updateMaskImmediately); } }); module.exports = exports['default'];