mirror of
https://github.com/igorski/bitmappery.git
synced 2026-06-17 03:34:56 +02:00
Document resize now takes layers with sizes different to the document into account
This commit is contained in:
23
README.md
23
README.md
@@ -49,23 +49,22 @@ npm run lint
|
||||
|
||||
# TODO / Roadmap
|
||||
|
||||
* Something weird with best fit only fitting when window resize fires (also see weird non-cleared canvas areas)
|
||||
* When resizing document, layers are not always equal to the document size/width (e.g. pasted from selections)
|
||||
* Layer bitmaps and masks must not be stored as Vue observables
|
||||
* Layer and mask coordinates are not saved when saving / switching document?
|
||||
* When resizing document, positioned layers do not scale their position correctly
|
||||
* Layer bitmaps and masks must not be stored as Vue observables
|
||||
* Make canvas only as large as its wrapper. Use viewport in zCanvas to render visible content (requires custom scroll handlers for panning)
|
||||
* Layer view in options-panel: allow naming, repositioning, toggle visibility, opacity
|
||||
* Canvas util : store transparency of images
|
||||
* Layer view in options-panel: allow naming, repositioning, toggling visibility and opacity
|
||||
* Canvas util : store transparency of images into saved document
|
||||
* Restored base64 images should be treated as binary once more (see layer-factory)
|
||||
* scale logic should move from zoomable-canvas into zCanvas (as handleInteraction needs to transform offsets by zoom ratio, see LayerSprite!)
|
||||
* Zoom set original size isn't that accurate (check also on mobile views), needs calculateMaxScaling ?
|
||||
* Unload Blobs when images are no longer used in document (see sprite-factory disposeSprite, keep instance count of usages)
|
||||
* Load/save documents directly from/to Dropbox
|
||||
* Implement layer rotation
|
||||
* Implement layer scaling
|
||||
* Implement rectangular selection
|
||||
* Implement merged layer selection
|
||||
* Unload Blobs when images are no longer used in document (see sprite-factory disposeSprite, keep instance count of usages)
|
||||
* Load/save documents from/to Dropbox
|
||||
* Text editing using Google fonts!
|
||||
* Add tools for layer rotation and scaling
|
||||
* Implement layer scale
|
||||
* Implement clone brush
|
||||
* Implement document crop
|
||||
* Implement clone brush
|
||||
* Implement change history
|
||||
* Implement text editing using Google fonts!
|
||||
* Scale logic should move from zoomable-canvas into zCanvas (as handleInteraction needs to transform offsets by zoom ratio, see LayerSprite!)
|
||||
|
||||
@@ -156,7 +156,8 @@ class LayerSprite extends sprite {
|
||||
}
|
||||
|
||||
async resize( width, height ) {
|
||||
const ratio = width / this.width;
|
||||
const ratioX = width / this._bounds.width;
|
||||
const ratioY = height / this._bounds.height;
|
||||
|
||||
if ( this.layer.bitmap ) {
|
||||
this.layer.bitmap = await resizeImage(
|
||||
@@ -169,7 +170,7 @@ class LayerSprite extends sprite {
|
||||
);
|
||||
this.cacheMask();
|
||||
}
|
||||
this.setBounds( this.getX() * ratio, this.getY() * ratio, width, height );
|
||||
this.setBounds( this.getX() * ratioX, this.getY() * ratioY, width, height );
|
||||
this.invalidate();
|
||||
}
|
||||
|
||||
|
||||
@@ -48,13 +48,15 @@ export default {
|
||||
},
|
||||
setActiveDocumentSize( state, { width, height }) {
|
||||
const document = state.documents[ state.activeIndex ];
|
||||
const ratioX = width / document.width;
|
||||
const ratioY = height / document.height;
|
||||
document.width = width;
|
||||
document.height = height;
|
||||
document.layers?.forEach( layer => {
|
||||
layer.width = width;
|
||||
layer.height = height;
|
||||
layer.width *= ratioX;
|
||||
layer.height *= ratioY;
|
||||
getSpriteForLayer( layer )?.resize( layer.width, layer.height );
|
||||
});
|
||||
runSpriteFn( sprite => sprite.resize( width, height ), document );
|
||||
},
|
||||
addNewDocument( state, nameOrDocument ) {
|
||||
const document = typeof nameOrDocument === "object" ? nameOrDocument : DocumentFactory.create({ name: nameOrDocument });
|
||||
|
||||
@@ -106,15 +106,16 @@ describe( "Vuex document module", () => {
|
||||
it( "should request the invalidate() method on each Sprite for the given Document", () => {
|
||||
const state = {
|
||||
documents: [
|
||||
{ name: "foo", width: 30, height: 30 },
|
||||
{ name: "bar", width: 50, height: 50 }
|
||||
{ name: "foo", width: 30, height: 30, layers: [ { name: "layer1", width: 30, height: 30 } ] },
|
||||
{ name: "bar", width: 50, height: 50, layers: [ { name: "layer2", width: 20, height: 10 }, { name: "layer3", width: 15, height: 15 } ] }
|
||||
],
|
||||
activeIndex : 1,
|
||||
};
|
||||
const size = { width: 75, height: 40 };
|
||||
mockUpdateFn = jest.fn();
|
||||
mutations.setActiveDocumentSize( state, size );
|
||||
expect( mockUpdateFn ).toHaveBeenCalledWith( "runSpriteFn", expect.any( Function ), state.documents[ state.activeIndex ]);
|
||||
expect( mockUpdateFn ).toHaveBeenNthCalledWith( 1, "getSpriteForLayer", state.documents[ 1 ].layers[ 0 ]);
|
||||
expect( mockUpdateFn ).toHaveBeenNthCalledWith( 2, "getSpriteForLayer", state.documents[ 1 ].layers[ 1 ]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user