UNPKG

matting-editor

Version:

matting-editor

1,127 lines (890 loc) 37.3 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _lodash = require('lodash'); var _lodash2 = _interopRequireDefault(_lodash); var _bluebird = require('bluebird'); var _bluebird2 = _interopRequireDefault(_bluebird); var _md = require('crypto-js/md5'); var _md2 = _interopRequireDefault(_md); var _snapshot = require('./utils/snapshot'); var _snapshot2 = _interopRequireDefault(_snapshot); var _loadImageByPixi = require('./utils/load-image-by-pixi'); var _loadImageByPixi2 = _interopRequireDefault(_loadImageByPixi); var _onecolor = require('./utils/onecolor.shim'); var _onecolor2 = _interopRequireDefault(_onecolor); var _mattingImage = require('./utils/matting-image'); var _mattingImage2 = _interopRequireDefault(_mattingImage); var _mattingDefault = require('./base/matting-default'); var _mattingDefault2 = _interopRequireDefault(_mattingDefault); var _pixi = require('./utils/pixi.shim'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var TilingSprite = _pixi.extras.TilingSprite; var defaultMattingData = _mattingDefault2.default.defaultMattingData; exports.default = { props: { options: { type: Object, default: function _default() {} } }, data: function data() { return { version: _mattingDefault2.default.version, matting: {}, mattingData: {}, ready: false, resultUpdating: false, draging: false, innerOptions: _lodash2.default.cloneDeep(_mattingDefault2.default.options), currentTool: _mattingDefault2.default.options.defaultTool, resolution: window.devicePixelRatio || 1, canvasSize: { width: 0, height: 0 }, canvasPosition: { x: 0, y: 0 }, zoom: 1, snapshot: new _snapshot2.default({ lines: [] }), backgroundTile: null, lastEdgePaths: [], lineCounts: { keep: 0, drop: 0 }, originImage: '', lastResultImageUrl: '', imagePosition: { x: 0, y: 0 }, isOverSprite: false }; }, watch: { options: function options(_options) { if (_options) { this.setOptions(this.options); } } }, methods: { setOptions: function setOptions(options) { var defaultOpionts = _lodash2.default.cloneDeep(_mattingDefault2.default.options); options = _lodash2.default.assign({}, defaultOpionts, this.innerOptions, options); this.innerOptions = options; }, createApp: function createApp(options) { var backgroundColor = this.hexToDecimal(this.innerOptions.canvasBackgroundColor); var app = new _pixi.Application(_extends({ resolution: this.resolution, forceCanvas: true, sharedLoader: true, sharedTicker: true, backgroundColor: backgroundColor, antialias: true }, this.canvasSize, options)); app.resize = function (width, height) { if ((typeof width === 'undefined' ? 'undefined' : _typeof(width)) === 'object') { height = width.height; width = width.width; } return app.renderer.resize(width, height); }; return app; }, initApp: function initApp() { this.sourceApp = this.createApp({ view: this.$refs.sourceCanvas }); this.resultApp = this.createApp({ view: this.$refs.resultCanvas }); }, activeTool: function activeTool(name) { if (name !== this.currentTool) { this.currentTool = name; this.$events.$emit('canvas.changetool', name); } }, resetLines: function resetLines() { this.lineCounts.keep = 0; this.lineCounts.drop = 0; this.currentLine = null; this.setMattingData({ lines: [] }); }, addLine: function addLine() { var _ref = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref$position = _ref.position, position = _ref$position === undefined ? { x: 0, y: 0 } : _ref$position, _ref$action = _ref.action, action = _ref$action === undefined ? 'keep' : _ref$action; var x = Math.round(position.x); var y = Math.round(position.y); var line = { action: action, points: [x, y], color: this.hexToDecimal(this.innerOptions.brushColorsMap[action]), size: this.mattingData.brushSize / this.zoom, alpha: 0.8 }; this.currentLine = line; this.mattingData.lines.push(line); return line; }, addPoint: function addPoint(x, y) { var line = this.currentLine; var points = line ? line.points : null; x = Math.round(x); y = Math.round(y); if (!points) { return; } var len = points.length; if (len >= 2) { var minOffset = 2; var lastX = points[len - 2]; var lastY = points[len - 1]; var xOffset = Math.abs(x - lastX); var yOffset = Math.abs(y - lastY); if (xOffset < minOffset && yOffset < minOffset) { return; } } points.push(x, y); }, loadImage: function loadImage(url) { var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return (0, _loadImageByPixi2.default)(url, options); }, showImage: function showImage(texture) { var _this = this; var img = new _pixi.Sprite(texture); var panel = this.getSourcePanel(); img.name = 'sourceImage'; img.interactive = true; img.on('pointerover', function (e) { _this.isOverSprite = true; _this.$events.$emit('canvas.mouseenter.source', e.data.originalEvent); }); img.on('pointerdown', function (e) { _this.$events.$emit('canvas.mousedown.source', e.data.originalEvent); }); img.on('pointerout', function (e) { _this.isOverSprite = false; _this.$events.$emit('canvas.mouseleave.source', e.data.originalEvent); }); img.on('pointermove', function (e) { _this.$events.$emit('canvas.mousemove', e.data.originalEvent); }); img.on('pointerup', function (e) { _this.$events.$emit('canvas.mouseup', e.data.originalEvent); _this.$events.$emit('canvas.mouseup.source', e.data.originalEvent); }); img.on('mouseupoutside', function (e) { _this.$events.$emit('canvas.mouseup', e.data.originalEvent); }); panel.pivot.set(img.width / 2, img.height / 2); panel.addChild(img); return img; }, fitZoom: function fitZoom() { var fullscreen = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; if (!this.ready) { return; } var canvasSize = this.canvasSize; var _mattingData = this.mattingData, imageHeight = _mattingData.imageHeight, imageWidth = _mattingData.imageWidth; var panelSize = { height: imageHeight, width: imageWidth }; var canvasRatio = canvasSize.width / canvasSize.height; var panelRatio = panelSize.width / panelSize.height; var fitWidth = fullscreen ? canvasRatio >= panelRatio : canvasRatio < panelRatio; var zoom = fitWidth ? Math.min(1, canvasSize.width / panelSize.width) : Math.min(1, canvasSize.height / panelSize.height); this.setZoom(zoom); this.resetPosition(); }, showResult: function showResult(data) { var _this2 = this; if (!data || !data.resultImage) { var retImgUrl = this.lastResultImageUrl; if (!retImgUrl) { retImgUrl = this.mattingData.sourceImage; } data = { edge_paths: this.lastEdgePaths, resultImage: retImgUrl }; } var panel = this.getResultPanel(); var res = _pixi.loader.resources[data.resultImage]; if (!res) { return; } var img = new _pixi.Sprite(res.texture); img.name = 'resultImage'; img.interactive = true; img.on('pointerover', function () { _this2.isOverSprite = true; }); img.on('pointerout', function () { _this2.isOverSprite = false; }); img.on('pointerdown', function (e) { _this2.$events.$emit('canvas.mousedown.result', e.data.originalEvent); }); img.on('pointermove', function (e) { _this2.$events.$emit('canvas.mousemove', e.data.originalEvent); }); img.on('pointerup', function (e) { _this2.$events.$emit('canvas.mouseup', e.data.originalEvent); }); img.on('mouseupoutside', function (e) { _this2.$events.$emit('canvas.mouseup', e.data.originalEvent); }); if (this.checkImageLoaded(data.resultImage)) { var bg = this.getResultBackground(); panel.removeChildren(); panel.pivot.set(img.width / 2, img.height / 2); panel.addChild(bg.imageBackground, img); bg.update(); } panel.x = this.imagePosition.x; panel.y = this.imagePosition.y; panel.scale.set(this.zoom); this.updateEdgePaths(); }, updatePanel: function () { var actions = { zoom: function zoom(panel) { panel.scale.set(this.zoom); }, position: function position(panel) { panel.position = this.imagePosition; } }; return function (type, data) { var sourceApp = this.sourceApp || {}; var sourcePanel = sourceApp.panel; if (!sourcePanel || !actions[type]) { return; } actions[type].call(this, sourcePanel, data); this.showResult(); }; }(), setZoom: function setZoom() { var zoom = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 1; var origin = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : null; var _mattingData2 = this.mattingData, imageHeight = _mattingData2.imageHeight, imageWidth = _mattingData2.imageWidth; var panel = this.sourceApp.panel; var sSize = Math.max(20, Math.min(imageWidth, imageHeight)); var targetZoom = Math.max(20 / sSize, Math.min(4, +zoom || 0)); var currOriginPos = void 0; if (origin && panel) { currOriginPos = panel.toLocal(origin); } this.zoom = targetZoom; this.updatePanel('zoom'); if (currOriginPos) { var currPos = this.imagePosition; var newOriginPos = panel.toGlobal(currOriginPos); var xOffset = newOriginPos.x - origin.x; var yOffset = newOriginPos.y - origin.y; this.setPosition(currPos.x - xOffset, currPos.y - yOffset); } }, resetPosition: function resetPosition() { var canvasSize = this.canvasSize; this.setPosition(canvasSize.width / 2, canvasSize.height / 2); }, setPosition: function setPosition() { var x = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; this.imagePosition = { x: +x || 0, y: +y || 0 }; this.updatePanel('position'); }, checkImageLoaded: function checkImageLoaded(url) { var resources = _pixi.loader.resources; url = _pixi.loader._prepareUrl(url); return !!resources[url]; }, updateCanvasSize: function updateCanvasSize() { var rect = this.getCanvasRect(); this.canvasSize = { height: rect.height, width: rect.width }; this.canvasPosition = { x: rect.left, y: rect.top }; this.sourceApp.resize(this.canvasSize); this.resultApp.resize(this.canvasSize); var ctx = this.sourceApp.renderer.context; ctx.lineJoin = 'round'; ctx.lineCap = 'round'; }, getCanvasRect: function getCanvasRect() { var sourceCanvasPanel = this.$refs.sourceCanvasPanel; var ret = { height: 0, width: 0, left: 0, top: 0 }; if (sourceCanvasPanel) { var rect = sourceCanvasPanel.getBoundingClientRect(); ret.height = rect.height; ret.width = rect.width; ret.left = rect.left; ret.top = rect.top; } return ret; }, getSourcePanel: function getSourcePanel() { var sourceApp = this.sourceApp; if (!sourceApp.panel) { var stage = sourceApp.stage; var panel = sourceApp.panel = new _pixi.Container(); stage.addChild(panel); stage.setChildIndex(panel, 0); } return sourceApp.panel; }, getResultPanel: function getResultPanel() { var resultApp = this.resultApp; var stage = resultApp.stage; if (!resultApp.panel) { var panel = new _pixi.Container(); var bg = this.getResultBackground(); stage.addChild(bg.panel, bg.mask, panel); stage.setChildIndex(bg.panel, 0); stage.setChildIndex(bg.mask, 1); stage.setChildIndex(panel, 2); resultApp.panel = panel; } return resultApp.panel; }, getResultBackground: function getResultBackground() { var _this3 = this; var bg = this._resultBackground; if (bg) { return bg; } var imageBackground = new _pixi.Graphics(); var tile = this.getBackgroundTile(); var panel = new TilingSprite(tile, 0, 0); var mask = new _pixi.Graphics(); panel.mask = mask; bg = this._resultBackground = { imageBackground: imageBackground, panel: panel, mask: mask, _update: function _update(width, height, color) { var params = { hexa: color.hexa(), height: height, width: width }; if (_lodash2.default.isEqual(params, bg._updateCache)) { return; } bg._updateCache = params; imageBackground.clear(); if (color.alpha() > 0) { imageBackground.beginFill(color.int(), color.alpha()); var _offset = _this3.zoom < 0.25 ? 2 : 1; imageBackground.drawRect(_offset, _offset, -2 * _offset + width, -2 * _offset + height); imageBackground.endFill(); } mask.pivot.set(width / 2, height / 2); mask.clear(); mask.beginFill(0x000000); var offset = _this3.zoom < 0.25 ? 2 : 1; mask.drawRect(offset, offset, -2 * offset + width, -2 * offset + height); mask.endFill(); }, update: function update() { var canvasSize = _this3.canvasSize; var _mattingData3 = _this3.mattingData, width = _mattingData3.imageWidth, height = _mattingData3.imageHeight; var imagePosition = _this3.imagePosition; var cssColor = _this3.mattingData.backgroundColor || 'rgba(0,0,0,0)'; var color = (0, _onecolor2.default)(cssColor); bg._update(width, height, color); panel.height = canvasSize.height; panel.width = canvasSize.width; mask.position = imagePosition; mask.scale.set(_this3.zoom); } }; return bg; }, getBackgroundTile: function getBackgroundTile() { var tile = this._backgroundTile; if (tile) { return tile; } var tileSize = 32; var tilePanel = new _pixi.Graphics(); tilePanel.beginFill(0xcccccc); tilePanel.drawRect(0, 0, tileSize, tileSize); tilePanel.endFill(); var tileSizeHalf = tileSize / 2; tilePanel.beginFill(0xffffff); tilePanel.drawRect(0, 0, tileSizeHalf, tileSizeHalf); tilePanel.drawRect(tileSizeHalf, tileSizeHalf, tileSizeHalf, tileSizeHalf); tilePanel.endFill(); tile = _pixi.RenderTexture.create(tileSize, tileSize); this.resultApp.renderer.render(tilePanel, tile); this._backgroundTile = tile; return tile; }, updateEdgePaths: function updateEdgePaths() { var lastEdgePaths = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.lastEdgePaths; var size = 2; var color = '#005cf9'; var panel = this.getSourcePanel(); var div = document.createElement('div'); var pathBaseAttrs = 'stroke-width="' + size + '" stroke="' + color + '" fill="none"'; var pathsStr = lastEdgePaths.map(function (d) { return '<path ' + pathBaseAttrs + ' d="' + d + '" />'; }); if (panel.edgeSvg) { panel.removeChild(panel.edgeSvg); } div.innerHTML = '<svg>' + pathsStr + '</svg>'; var svgNode = div.firstChild; if (!svgNode.children) { var children = []; lastEdgePaths.forEach(function (d) { var newElement = document.createElementNS('http://www.w3.org/2000/svg', 'path'); newElement.setAttribute('d', d); newElement.style.stroke = color; newElement.style.strokeWidth = size; newElement.style.fill = 'none'; children.push(newElement); }); svgNode.children = children; } var svg = new _pixi.SVG(svgNode); panel.addChild(svg); panel.edgeSvg = svg; }, resetCanvas: function resetCanvas() { var sourceApp = this.sourceApp; var resultApp = this.resultApp; if (!sourceApp) { return; } if (sourceApp.panel) { var sourceStage = sourceApp.stage; sourceStage.removeChild(sourceApp.panel); sourceApp.panel = null; } if (resultApp.panel) { resultApp.panel.removeChildren(); } }, reset: function reset() { this.resetCanvas(); this.resetSnapshot(); this.resetLines(); this.lastEdgePaths = []; this.mattingData = Object.assign({}, defaultMattingData); this.matting = {}; this.lastResultImageUrl = ''; this.ready = false; }, drawLines: function drawLines() { var lines = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.mattingData.lines; var brush = this.getBrush(); brush.clear(); lines.forEach(function (line) { var size = line.size; var color = line.color; var alpha = line.alpha; var points = line.points; var len = points.length; if (len <= 2) { var rad = size / 2; var x = points[0]; var y = points[1]; brush.lineStyle(0); brush.beginFill(color, alpha); brush.drawCircle(x, y, rad); brush.endFill(); return; } brush.lineStyle(size, color, alpha); brush.moveTo(points[0], points[1]); var x1 = points[0]; var y1 = points[1]; var x2 = points[2]; var y2 = points[3]; for (var mx, my, i = 2; i < len; i += 2) { mx = x1 + (x2 - x1) / 2; my = y1 + (y2 - y1) / 2; brush.quadraticCurveTo(x1, y1, mx, my); x1 = points[i]; y1 = points[i + 1]; x2 = points[i + 2]; y2 = points[i + 3]; } brush.lineTo(x1, y1); }); this.lineCounts = lines.reduce(function (ret, line) { ret[line.action] += 1; return ret; }, { keep: 0, drop: 0 }); this.updateResultLazy(); }, previewResult: function previewResult(imageUrl) { var _this4 = this; return this.loadImage(imageUrl).then(function () { _this4.lastResultImageUrl = imageUrl; var ret = { edge_paths: [], resultImage: imageUrl }; return _this4.showResult(ret); }); }, updateResultLazy: function updateResultLazy() { var _this5 = this; var delay = 520; this.makeSnapshot('update'); clearTimeout(this.updateResultTimer); this.updateResultTimer = setTimeout(function () { var mattingData = _this5.getMattingData(); _this5.mattingChange(mattingData); _this5.updateResult(); }, delay); }, updateResult: function updateResult() { var _this6 = this; var dataHash = void 0; var matting = this.getMatting(); var lineCounts = this.lineCounts; var self = this; var isHashChanged = function isHashChanged() { return dataHash && dataHash !== _this6._lastMattingDataHash; }; var _showResult = function _showResult(ret) { return _bluebird2.default.try(function () { if (isHashChanged()) { var err = new Error('User canceled'); err.name = 'CancellationError'; err.canceled = true; throw err; } }).tap(function () { var imgUrl = ret.resultImage || ''; if (imgUrl && ret.edge_paths) { _this6.lastEdgePaths = ret.edge_paths || []; _this6.updateEdgePaths(); } if (imgUrl) { return _this6.loadImage(imgUrl); } }).tap(function () { if (isHashChanged()) { return; } return _this6.showResult(ret); }); }; return _bluebird2.default.try(function () { return _this6.saveMatting(matting); }).then(function (matting) { var ret = { edge_paths: [], resultImage: '' }; _this6.loadingTimer = setTimeout(_this6.showLoading, _this6.innerOptions.loadingDelay); if (!lineCounts.keep || !lineCounts.drop) { _this6.lastEdgePaths = []; return ret; } var mattingDataWithHash = _this6.getMattingDataWithHash(); dataHash = mattingDataWithHash.hash; _this6._lastMattingDataHash = dataHash; return (0, _mattingImage2.default)(matting, mattingDataWithHash.data, { onPreview: function onPreview(ret, mattingResult) { _showResult(ret); var mattingData = self.getMattingData(); self.hideLoading(); self.mattinged(mattingResult, mattingData); }, mattingImage: _this6.innerOptions.mattingImage, uploadImage: _this6.uploadImage }); }).then(function (ret) { _this6.lastResultImageUrl = _this6.matting.result_image = ret.resultImage; return _showResult(ret); }).then(function () { var matting = _this6.getMatting(); return _this6.saveMatting(matting); }).then(function () { var mattingData = _this6.getMattingData(); _this6.mattingUpdate(mattingData); }).catch(function (err) { _this6.mattingError(err); }).finally(function () { _this6.hideLoading(); }); }, getBrush: function getBrush() { var sourceApp = this.sourceApp; var panel = sourceApp.panel; if (!panel.brush) { var brush = panel.brush = new _pixi.Graphics(); panel.addChild(brush); } return panel.brush; }, resetSnapshot: function resetSnapshot() { this.snapshot.reset(); }, makeSnapshot: function makeSnapshot() { var _this7 = this; var tag = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; if (!tag) { throw new Error('No tag gived'); } this.snapshot.addLazy(tag, function () { return { lines: _this7.mattingData.lines }; }); }, applySnapshot: function applySnapshot() { var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0; var snapshot = this.snapshot; if (index === snapshot.currentIndex) { return; } snapshot.jumpTo(index); var data = snapshot.getData(); if (!data) { return; } this.setMattingData({ lines: data.lines }); this.drawLines(); }, saveMatting: function saveMatting(matting) { var _this8 = this; return this.innerOptions.saveMatting(matting).then(function (matting) { _this8.setMatting(matting); return matting; }); }, uploadImage: function uploadImage(blob, matting) { return this.innerOptions.uploadImage(blob, matting); }, createMattingData: function createMattingData() { var mattingData = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; return Object.assign({}, defaultMattingData, mattingData); }, setMatting: function setMatting(matting) { try { var contentData = JSON.parse(matting.content); this.mattingData = contentData; this.originImage = contentData.sourceImage; this.matting = Object.assign(this.matting, matting); } catch (ex) { throw new Error('不正确的 matting 对象'); } }, getMatting: function getMatting() { Object.assign(this.matting, { content: JSON.stringify(this.mattingData), result_image: this.lastResultImageUrl || this.matting.result_image }); return this.matting; }, getMattingData: function getMattingData() { return this.mattingData; }, setMattingData: function setMattingData(mattingData) { this.mattingData = Object.assign({ version: this.version }, defaultMattingData, this.mattingData, mattingData); return this.mattingData; }, getMattingDataWithHash: function getMattingDataWithHash() { var data = this.getMattingData(); var dataJSON = JSON.stringify(data); return { hash: (0, _md2.default)(dataJSON).toString(), data: data }; }, toogleZoom: function toogleZoom() { var dir = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'in'; var zoomLevels = [0.2, 0.3, 0.5, 0.8, 1, 1.5, 2, 3, 4]; var currentZoom = this.zoom; var idx = zoomLevels.findIndex(function (zoom) { return zoom >= currentZoom; }); idx += dir === 'in' ? 1 : -1; idx = Math.max(0, Math.min(zoomLevels.length - 1, idx)); this.setZoom(zoomLevels[idx]); }, getStagePointerByEvenet: function getStagePointerByEvenet(e) { var offset = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.canvasPosition; var _getPagePosition = this.getPagePosition(e), pageX = _getPagePosition.pageX, pageY = _getPagePosition.pageY; return { x: pageX - offset.x, y: pageY - offset.y }; }, getPagePosition: function getPagePosition(e) { var pageX = e.pageX, pageY = e.pageY; if (this.isMobileDevice()) { pageX = e.changedTouches[0].pageX; pageY = e.changedTouches[0].pageY; } return { pageX: pageX, pageY: pageY }; }, exportImage: function exportImage() { var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}, _ref2$type = _ref2.type, type = _ref2$type === undefined ? 'png' : _ref2$type, _ref2$quality = _ref2.quality, quality = _ref2$quality === undefined ? 0.92 : _ref2$quality; var url = this.lastResultImageUrl; var backgroundColor = this.mattingData.backgroundColor; type = /jpe?g/.test(type) ? 'jpeg' : type; var supportExportImageExt = _mattingDefault2.default.supportExportImageExt; if (supportExportImageExt.indexOf(type) < 0) { throw new Error('\u4E0D\u652F\u6301\u5BFC\u51FA ' + type + ' \u683C\u5F0F'); } if (url === '') { url = this.mattingData.sourceImage; } return (0, _loadImageByPixi2.default)(url).then(function (res) { var canvas = document.createElement('canvas'); var ctx = canvas.getContext('2d'); var img = res.data; var width = img.width, height = img.height; canvas.height = height; canvas.width = width; if (type === 'jpeg') { ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, width, height); } if (backgroundColor) { ctx.fillStyle = backgroundColor; ctx.fillRect(0, 0, width, height); } ctx.drawImage(img, 0, 0, width, height); var dataURL = canvas.toDataURL('image/' + type, quality); return dataURL; }); }, showLoading: function showLoading() { this.resultUpdating = true; }, hideLoading: function hideLoading() { clearTimeout(this.loadingTimer); this.resultUpdating = false; }, undo: function undo() { this.applySnapshot(this.snapshot.currentIndex - 1); }, redo: function redo() { this.applySnapshot(this.snapshot.currentIndex + 1); }, zoomIn: function zoomIn() { this.toogleZoom('in'); }, zoomOut: function zoomOut() { this.toogleZoom('out'); }, setBrushSize: function setBrushSize(brushSize) { this.setMattingData({ brushSize: brushSize }); }, setFeatheringRadius: function setFeatheringRadius(featheringRadius) { this.setMattingData({ featheringRadius: featheringRadius }); this.updateResultLazy(); }, setBackgroundColor: function setBackgroundColor(backgroundColor) { this.setMattingData({ backgroundColor: backgroundColor }); this.showResult(); }, isMobileDevice: function isMobileDevice() { return this.isMobile || (this.isMobile = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)); }, hexToDecimal: function hexToDecimal(hex) { var rShortHex = /^#?([0-9a-f])([0-9a-f])([0-9a-f])$/i; if (hex.length < 6) { hex = hex.replace(rShortHex, '#$1$1$2$2$3$3'); } return parseInt(hex.replace('#', '0x')); }, elementIsVisible: function elementIsVisible(el) { var rect = el.getBoundingClientRect(); return !(rect.width === 0 && rect.height === 0); }, mattingReady: function mattingReady() { this.$emit('ready'); }, mattingChange: function mattingChange(mattingData) { this.$emit('change', mattingData); }, mattinged: function mattinged(mattingResult, mattingData) { this.$emit('mattinged', mattingResult, mattingData); }, mattingUpdate: function mattingUpdate(mattingData) { this.$emit('update', mattingData); }, mattingError: function mattingError(err) { this.$emit('error', err); } }, events: { 'destroy': function destroy() { var remove = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; this.sourceApp.destroy(remove); this.resultApp.destroy(remove); } }, mounted: function mounted() { if (this.options) { this.setOptions(this.options); } }, beforeDestroy: function beforeDestroy() { this.$events.$emit('destroy'); } };