mirror of
https://github.com/igorski/bitmappery.git
synced 2026-06-16 19:25:38 +02:00
Improved performance of selection copying
This commit is contained in:
@@ -142,4 +142,7 @@ export type WandToolOptions = {
|
||||
sampleMerged: boolean;
|
||||
};
|
||||
|
||||
export type CopiedSelection = SizedImage & { type: LayerTypes };
|
||||
export type CopiedSelection = {
|
||||
bitmap: HTMLCanvasElement;
|
||||
type: LayerTypes;
|
||||
};
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import type { Store } from "vuex";
|
||||
import type { BitMapperyState } from "@/store";
|
||||
import { type Store } from "vuex";
|
||||
import { type BitMapperyState } from "@/store";
|
||||
|
||||
/**
|
||||
* a history state should provide undo and redo functions and an optional
|
||||
@@ -38,7 +38,7 @@ const stateQueue = new Map();
|
||||
const ENQUEUE_TIMEOUT = 1000;
|
||||
|
||||
let timeout = 0;
|
||||
let store: Store<BitMapperyState>;
|
||||
let store: Store<BitMapperyState> | undefined;
|
||||
|
||||
export const initHistory = ( storeReference: Store<BitMapperyState> ): void => {
|
||||
store = storeReference;
|
||||
@@ -87,6 +87,6 @@ export const enqueueState = ( key: string, undoRedoState: UndoRedoState ): void
|
||||
|
||||
function processQueue(): void {
|
||||
window.clearTimeout( timeout );
|
||||
stateQueue.forEach( undoRedoState => store.commit( "saveState", undoRedoState ));
|
||||
stateQueue.forEach( undoRedoState => store?.commit( "saveState", undoRedoState ));
|
||||
stateQueue.clear();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import history, { HistoryState } from "./modules/history-module";
|
||||
import image, { ImageState } from "./modules/image-module";
|
||||
import preferences, { PreferencesState } from "./modules/preferences-module";
|
||||
import tool, { ToolState } from "./modules/tool-module";
|
||||
import { cloneCanvas, imageToCanvas } from "@/utils/canvas-util";
|
||||
import { cloneCanvas } from "@/utils/canvas-util";
|
||||
import { copySelection, deleteSelectionContent } from "@/utils/document-util";
|
||||
import { saveBlobAsFile, selectFile } from "@/utils/file-util";
|
||||
import { replaceLayerSource } from "@/utils/layer-util";
|
||||
@@ -281,13 +281,14 @@ export default {
|
||||
},
|
||||
pasteSelection({ commit, getters, dispatch, state }: ActionContext<BitMapperyState, any> ): void {
|
||||
const selection = state.selectionContent;
|
||||
const { image, size, type } = selection;
|
||||
const { bitmap, type } = selection;
|
||||
const layer = LayerFactory.create({
|
||||
type: ( !type || type === LayerTypes.LAYER_TEXT ) ? LayerTypes.LAYER_GRAPHIC : type,
|
||||
source: imageToCanvas( image, size.width, size.height ),
|
||||
...size,
|
||||
left: getters.activeDocument.width / 2 - size.width / 2,
|
||||
top : getters.activeDocument.height / 2 - size.height / 2,
|
||||
source: cloneCanvas( bitmap ),
|
||||
width: bitmap.width,
|
||||
height: bitmap.height,
|
||||
left: getters.activeDocument.width / 2 - bitmap.width / 2,
|
||||
top : getters.activeDocument.height / 2 - bitmap.height / 2,
|
||||
});
|
||||
const index = getters.activeDocument.layers.length;
|
||||
const paste = () => {
|
||||
@@ -295,7 +296,7 @@ export default {
|
||||
dispatch( "clearSelection" );
|
||||
};
|
||||
paste();
|
||||
enqueueState( `paste_${selection.size.width}_${selection.size.height}`, {
|
||||
enqueueState( `paste_${type}_${bitmap.width}_${bitmap.height}`, {
|
||||
undo() {
|
||||
commit( "setSelectionContent", selection );
|
||||
commit( "removeLayer", index );
|
||||
|
||||
@@ -20,9 +20,7 @@
|
||||
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
import { canvas, loader } from "zcanvas";
|
||||
import type { Rectangle } from "zcanvas";
|
||||
import { PNG } from "@/definitions/image-types";
|
||||
import { canvas, type Rectangle } from "zcanvas";
|
||||
import type { Document, Shape, Layer } from "@/definitions/document";
|
||||
import type { CopiedSelection } from "@/definitions/editor";
|
||||
import { renderEffectsForLayer } from "@/services/render-service";
|
||||
@@ -202,10 +200,8 @@ export const copySelection = async ( activeDocument: Document, activeLayer: Laye
|
||||
);
|
||||
zcvs.dispose();
|
||||
|
||||
const output = await loader.loadImage( selectionCanvas.cvs.toDataURL( PNG.mime ));
|
||||
|
||||
return {
|
||||
...output,
|
||||
bitmap: selectionCanvas.cvs,
|
||||
type: activeLayer.type,
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { it, beforeEach, describe, expect, afterAll, vi } from "vitest";
|
||||
import { mockZCanvas } from "../mocks";
|
||||
import { createMockCanvasElement, createState, mockZCanvas } from "../mocks";
|
||||
import { type Layer } from "@/definitions/document";
|
||||
import { type Dialog } from "@/definitions/editor";
|
||||
import { SAVE_DOCUMENT } from "@/definitions/modal-windows";
|
||||
@@ -10,7 +10,6 @@ import DocumentFactory from "@/factories/document-factory";
|
||||
import LayerFactory from "@/factories/layer-factory";
|
||||
import KeyboardService from "@/services/keyboard-service";
|
||||
import store, { type BitMapperyState } from "@/store";
|
||||
import { createState, createMockImageElement } from "../mocks";
|
||||
|
||||
const { getters, mutations, actions } = store;
|
||||
|
||||
@@ -28,6 +27,7 @@ vi.mock( "@/utils/file-util", () => ({
|
||||
}));
|
||||
vi.mock("@/utils/canvas-util", () => ({
|
||||
createCanvas: vi.fn(() => ({ cvs: {}, ctx: {} })),
|
||||
cloneCanvas: vi.fn( cvs => cvs ),
|
||||
imageToBase64: vi.fn(),
|
||||
imageToCanvas: vi.fn(),
|
||||
base64ToLayerImage: vi.fn()
|
||||
@@ -83,7 +83,7 @@ describe( "Vuex store", () => {
|
||||
|
||||
it( "should be able to set the current selection content", () => {
|
||||
const state = createState({ selectionContent: null });
|
||||
const selection = { image: createMockImageElement(), size: { width: 100, height: 50 }, type: LayerTypes.LAYER_GRAPHIC };
|
||||
const selection = { bitmap: createMockCanvasElement(), type: LayerTypes.LAYER_GRAPHIC };
|
||||
mutations.setSelectionContent( state, selection );
|
||||
expect( state.selectionContent ).toEqual( selection );
|
||||
});
|
||||
@@ -392,11 +392,7 @@ describe( "Vuex store", () => {
|
||||
beforeEach(() => {
|
||||
state = createState({
|
||||
selectionContent: {
|
||||
image: createMockImageElement(),
|
||||
size: {
|
||||
width: 40,
|
||||
height: 30
|
||||
},
|
||||
bitmap: createMockCanvasElement(),
|
||||
type: LayerTypes.LAYER_GRAPHIC,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user