Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update dependencies and rendering logic to use zCanvas 6.0.1 #32

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3,444 changes: 1,756 additions & 1,688 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"register-service-worker": "^1.7.1",
"tiny-script-loader": "^2.2.1",
"v-tooltip": "^2.0.3",
"vue": "^2.7.14",
"vuex": "^3.4.0"
"vue": "v2-latest",
"vuex": "^3.6.2"
},
"devDependencies": {
"@aws-sdk/client-s3": "^3.315.0",
Expand All @@ -49,6 +49,6 @@
"vue-js-toggle-button": "^1.3.3",
"vue-select": "^3.6.0",
"vuedraggable": "^2.24.3",
"zcanvas": "^5.1.8"
"zcanvas": "^6.0.1"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,8 +98,8 @@ export default {
background-size: 50%;

img {
width: 100%;
height: 100%;
width: calc(100% - #{$spacing-small});
height: calc(100% - #{$spacing-small});
object-fit: cover;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/components/cloud-file-selector/cloud-file-selector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
<script lang="ts">
import type { Component } from "vue";
import { mapState, mapMutations, mapActions } from "vuex";
import { loader } from "zcanvas";
import { Loader } from "zcanvas";
import { ACCEPTED_FILE_EXTENSIONS, isThirdPartyDocument, getMimeForThirdPartyDocument } from "@/definitions/file-types";
import type { FileNode } from "@/definitions/storage-types";
import ImageToDocumentManager from "@/mixins/image-to-document-manager";
Expand Down Expand Up @@ -305,7 +305,7 @@ export default {
const blob = await fetch( url ).then( r => r.blob() );
await this.loadThirdPartyDocuments([ blob ], getMimeForThirdPartyDocument( node ));
} else {
const { image, size } = await loader.loadImage( url );
const { image, size } = await Loader.loadImage( url );
this.setStorageType( this.STORAGE_PROVIDER );
await this.addLoadedFile({ type: this.STORAGE_PROVIDER, name: node.name }, { image, size });
}
Expand Down
1 change: 0 additions & 1 deletion src/components/document-canvas/document-canvas.vue
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,6 @@ export default {
height: this.cvsHeight,
animate: false,
smoothing: this.antiAlias,
stretchToFit: false,
viewport: {
width : this.viewportWidth,
height : this.viewportHeight
Expand Down
8 changes: 7 additions & 1 deletion src/definitions/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export type CanvasContextPairing = {

// technically a more limited version of "CanvasImageSource", these are the only
// data types handled internally by BitMappery as the canvas source content
export type CanvasDrawable = HTMLCanvasElement | HTMLImageElement;
export type CanvasDrawable = HTMLCanvasElement | HTMLImageElement | ImageBitmap; // @todo make ImageBitmap only?

export type CanvasDimensions = {
// the base dimensions describe the "best fit" scale to represent
Expand Down Expand Up @@ -137,3 +137,9 @@ export type WandToolOptions = {
threshold: number;
sampleMerged: boolean;
};

// @todo we shouldn't need this when using and loading ImageBitmap throughout!
export type SizedImage = {
image: HTMLImageElement;
size: Size;
};
9 changes: 5 additions & 4 deletions src/mixins/image-to-document-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
import { mapGetters, mapMutations, mapActions } from "vuex";
import type { Size, SizedImage } from "zcanvas";
import type { Size } from "zcanvas";
import type { Document, Layer } from "@/definitions/document";
import type { SizedImage } from "@/definitions/editor";
import { isTransparent } from "@/definitions/image-types";
import { ACCEPTED_FILE_EXTENSIONS, PSD, PDF, isImageFile, isProjectFile, isThirdPartyDocument } from "@/definitions/file-types";
import { LayerTypes } from "@/definitions/layer-types";
Expand Down Expand Up @@ -145,9 +146,9 @@ export default {
}
for ( const file of documents ) {
const serviceImport = await getServiceForThirdPartyFile( optMime || file.type );
const document = await serviceImport( file );
if ( document !== null ) {
this.addNewDocument( document );
const doc = await serviceImport( file );
if ( doc !== null ) {
this.addNewDocument( doc );
}
}
},
Expand Down
18 changes: 12 additions & 6 deletions src/rendering/blending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@
* 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 { Rectangle } from "zcanvas";
import type { IRenderer, Rectangle } from "zcanvas";
import { BlendModes } from "@/definitions/blend-modes";
import type { RGB, HSV } from "@/definitions/colors";
import { createCanvas } from "@/utils/canvas-util";
import { rgb2YCbCr, YCbCr2rgb, rgb2hsv, hsv2rgb } from "@/utils/color-util";
import ZoomableCanvas from "./canvas-elements/zoomable-canvas";

const { cvs, ctx } = createCanvas();

Expand All @@ -48,22 +49,27 @@ export const getBlendContext = ( documentCanvas: HTMLCanvasElement ): CanvasRend
/**
* Blend a Layer onto the underlying Document content
*
* @param {CanvasRenderingContext2D} dest the context that contains all rendered content below the Layer
* @param {ZoomableCanvas} zoomableCanvas the ZoomableCanvas instance to render on
* @param {CanvasRenderingContext2D} layer the context that contains the content of the Layer (see getBlendContext)
* @param {BlendModes} blendMode the blend mode to use
* @param {Rectangle?} bounds optional bounds to constrain blending within. defaults to full dest size
*/
export const blendLayer = ( dest: CanvasRenderingContext2D, layer: CanvasRenderingContext2D,
export const blendLayer = async ( zoomableCanvas: ZoomableCanvas, layer: CanvasRenderingContext2D,
blendMode: BlendModes, bounds?: Rectangle ): void => {
let left = 0;
let top = 0;
let { width, height } = dest.canvas;
let width = zoomableCanvas.getWidth();
let height = zoomableCanvas.getHeight();
const renderer = zoomableCanvas.getRenderer();

if ( bounds ) {
({ left, top, width, height } = bounds );
}

const srcImageData: ImageData = layer.getImageData( left, top, width, height );
const dstImageData: ImageData = dest.getImageData( left, top, width, height );
// @todo is Promise but should be sync when not using Worker, this entire method should be sync!
const content = await zoomableCanvas.getContent();
const dstImageData: ImageData = content.getContext( "2d" )!.getImageData( left, top, width, height );

const src: Uint8ClampedArray = srcImageData.data;
const dst: Uint8ClampedArray = dstImageData.data;
Expand Down Expand Up @@ -235,7 +241,7 @@ export const blendLayer = ( dest: CanvasRenderingContext2D, layer: CanvasRenderi
break;
}
}
dest.putImageData( dstImageData, left, top );
renderer.drawImageData( dstImageData, left, top );

// free allocated memory of temp context
layer.canvas.width = layer.canvas.height = 1;
Expand Down
46 changes: 24 additions & 22 deletions src/rendering/canvas-elements/guide-renderer.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* The MIT License (MIT)
*
* Igor Zinken 2021-2022 - https://www.igorski.nl
* Igor Zinken 2021-2023 - https://www.igorski.nl
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
Expand All @@ -20,17 +20,18 @@
* 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 { sprite } from "zcanvas";
import type { Rectangle, Viewport } from "zcanvas";
import { Sprite } from "zcanvas";
import type { Rectangle, Viewport, IRenderer, StrokeProps } from "zcanvas";
import { fastRound } from "@/math/unit-math";
import type ZoomableCanvas from "@/rendering/canvas-elements/zoomable-canvas";
import { getClosestSnappingPoints } from "@/rendering/snapping";

const AMOUNT_OF_PIXELS = 1; // currently only 1 pixel grid supported

class GuideRenderer extends sprite {
class GuideRenderer extends Sprite {
private drawGuides: boolean;
private drawPixelGrid: boolean;
private strokeProps: StrokeProps = { color: "#FFF", size: 1 };

constructor( zCanvasInstance: ZoomableCanvas = null ) {
// @ts-expect-error ignoring some arguments...
Expand All @@ -51,51 +52,52 @@ class GuideRenderer extends sprite {
this.drawPixelGrid = drawPixelGrid;
}

draw( ctx: CanvasRenderingContext2D, viewport: Viewport = null ): void {
override draw( renderer: IRenderer, viewport?: Viewport ): void {

const canvas = this.canvas as ZoomableCanvas;

this.strokeProps.color = "#000";
this.strokeProps.size = 1 / canvas.zoomFactor;

/* grid */

if ( this.drawPixelGrid ) {
const width = viewport?.width || this.canvas.getWidth();
const height = viewport?.height || this.canvas.getHeight();
const width = viewport?.width || canvas.getWidth();
const height = viewport?.height || canvas.getHeight();

ctx.strokeStyle = "000";
ctx.lineWidth = 1 / this.canvas.zoomFactor;
// @todo cache the points ?

ctx.beginPath();
for ( let x = 0; x < width; x += AMOUNT_OF_PIXELS ) {
ctx.moveTo( x, 0 );
ctx.lineTo( x, height );
renderer.drawPath([ { x, y: 0 }, { x, y: height }], undefined, this.strokeProps );
}
for ( let y = 0; y < height; y += AMOUNT_OF_PIXELS ) {
ctx.moveTo( 0, y );
ctx.lineTo( width, y );
renderer.drawPath([ { x: 0, y }, { x: width, y }], undefined, this.strokeProps );
}
ctx.stroke();
}

/* guides */

if ( !this.drawGuides || !this.canvas.guides || !this.canvas.draggingSprite ) {
if ( !this.drawGuides || !canvas.guides || !canvas.draggingSprite ) {
return;
}

const vpLeft = viewport?.left || 0;
const vpTop = viewport?.top || 0;

// we can snap the currently draggingSprite against its edge and center
const guides: Rectangle[] = getClosestSnappingPoints( this.canvas.draggingSprite, this.canvas.guides );
ctx.strokeStyle = "red";
const guides: Rectangle[] = getClosestSnappingPoints( canvas.draggingSprite, canvas.guides );

this.strokeProps.color = "red";

for ( const { left, top, width, height } of guides ) {
// make up for canvas viewport offset
const localX = left - vpLeft;
const localY = top - vpTop;

ctx.beginPath();
ctx.moveTo( fastRound( localX ), fastRound( localY ));
ctx.lineTo( fastRound( localX + width ), fastRound( localY + height ));
ctx.stroke();
renderer.drawPath([
{ x: fastRound( localX ), y: fastRound( localY ) },
{ x: fastRound( localX + width ), y: fastRound( localY + height ) }
], undefined, this.strokeProps );
}
}
}
Expand Down
Loading