UNPKG

aico-image-editor

Version:

Combine multiple image into and create single combined image

137 lines (116 loc) 5.06 kB
/** * TransormCommand for other properties undo and redo */ export class TransformCommand { constructor(object,canvas, options = {}) { this.object = object; this.canvas = canvas; this._initStateProperties(options); this.state = {}; this.prevState = {}; this._saveState(options); this._savePrevState(options); } _initStateProperties(options) { this.stateProperties = this.object.stateProperties; //check if custom passed property's name already exists in the list of this.stateProperties // and if not then add that name in this.stateProperties array to save it for undo/redo // if(options.stateProperties && options.stateProperties.length) { // options.stateProperties.forEach(prop => { // if(!this.stateProperties.includes(prop.name)) { // this.stateProperties.push(prop.name); // } // }) // } } execute() { this._restoreState(); this.object.setCoords(); } undo() { this._restorePrevState(); this.object.setCoords(); } _restoreState() { this._restore(this.state); } _restorePrevState() { this._restore(this.prevState); } _restore(state) { this.stateProperties.forEach((prop) => { if(prop !== 'clipPath') { this.object.set(prop, state[prop]); } // if(prop === 'symbolSVGColor') { // //console.log(state[prop]); // var filter = new fabric.Image.filters.ReplaceColor({ // color: state[prop].prev, // Set the color you want to replace (black) // replace: state[prop].next // Set the color you want to replace it with (red) // }); // this.object.filters.push(filter); // this.object.applyFilters(); // } if(prop === 'svgPathColor') { this.object._objects?.filter(object => object.type === 'path').forEach(function(object) { if(object.fill !== '#fff' || object.fill === '#ffffff' || object.fill === 'rgb(255,255,255)') { object.set({fill: state[prop]}) } }) } if(prop === 'filters') { this.object.applyFilters(); } //while doing restore operation(aka undo/redo), you will also call savestate incase you need to update // history from that point/ rewriting history from middle of history array }) this.object.saveState(); if(this.object.filters) { Alpine.store('canvas').saveStateForFilters(this.object); } let self = this; window.dispatchEvent(new CustomEvent('object-restored-via-undo-redo', { detail: { object: self.object } })) this.canvas.renderAll() } _saveState(options) { this.stateProperties.forEach((prop) => { if(prop !== 'filters') { this.state[prop] = this.object.get(prop) } if(prop === 'filters') { //console.log(this.state[prop]) this.state[prop] = this.object.get(prop).slice() } }) } _savePrevState(options) { if(this.object._stateProperties) { this.stateProperties.forEach((prop) => { if(prop !== 'filters') { this.prevState[prop] = this.object._stateProperties[prop]; } if(prop === 'path' && this.prevState[prop] !== null) { Object.setPrototypeOf(this.prevState[prop], fabric.Path.prototype) } //same thing for filters prototype except the change that filters is array hence it;s individual element // needs to be updated with correct prototype when stored as prevState[prop] i.e. prevState['filters'] if(prop === 'filters') { // _stateProperties does not work here properly for state properties // if(this.object.filters.length) { // this.prevState[prop] = this.object._stateProperties[prop].slice(); // this.prevState[prop].forEach((filterObject,filterObjectIndex) => { // const originalFilterObjectPrototypeAtSameIndex = Object.getPrototypeOf(this.object.filters[filterObjectIndex]) // Object.setPrototypeOf(filterObject, originalFilterObjectPrototypeAtSameIndex) // }) // } //console.log(this.prevState[prop]) this.prevState[prop] = this.object.myOwnStateProps?.filters?.slice() || []; } }) } } }