diff --git a/src/components/ui/zcanvas/layer-sprite.js b/src/components/ui/zcanvas/layer-sprite.js index 16619f5..35b7af8 100644 --- a/src/components/ui/zcanvas/layer-sprite.js +++ b/src/components/ui/zcanvas/layer-sprite.js @@ -24,69 +24,71 @@ import { sprite } from "zcanvas"; import { createCanvas } from "@/utils/canvas-util"; import { LAYER_GRAPHIC, LAYER_MASK } from "@/definitions/layer-types"; -function LayerSprite( layer ) { - this._layer = layer; +class LayerSprite extends sprite { + constructor( layer ) { + if ( layer.type === LAYER_GRAPHIC && !layer.bitmap ) { + // create a Bitmap on which this layer will render its drawable content. + // assign this Bitmap to the layer + const { cvs } = createCanvas( layer.width, layer.height ); + layer.bitmap = cvs; + } + let { bitmap, x, y, width, height } = layer; - if ( layer.type === LAYER_GRAPHIC && !layer.bitmap ) { - // create a Bitmap on which this layer will render its drawable content. - // assign this Bitmap to the layer - const { cvs } = createCanvas( layer.width, layer.height ); - layer.bitmap = cvs; + // zCanvas inheritance + super({ bitmap, x, y, width, height } ); + this.setDraggable( true ); + + this._layer = layer; + + // create brush (always as all layers can be maskable) + const brushCanvas = createCanvas(); + this._brushCvs = brushCanvas.cvs; + this._brushCtx = brushCanvas.ctx; + this._halfRadius = 0; + + this.cacheGradient( "rgba(255,0,0,1)" ); } - let { bitmap, x, y, width, height } = layer; - // zCanvas inheritance - LayerSprite.super( this, "constructor", { bitmap, x, y, width, height } ); - this.setDraggable( true ); + isDrawable() { + return this._layer.type === LAYER_GRAPHIC || this.isMaskable(); + } - // create brush (always as all layers can be maskable) - const brushCanvas = createCanvas(); - this._brushCvs = brushCanvas.cvs; - this._brushCtx = brushCanvas.ctx; - this._halfRadius = 0; + isMaskable() { + return !!this._layer.mask; + } - this.cacheGradient( "rgba(255,0,0,1)" ); + cacheGradient( color, radius = 30 ) { + const innerRadius = radius / 6; + const outerRadius = radius * 2; + + const x = radius; + const y = radius; + + // update brush Canvas size + this._brushCvs.width = outerRadius; + this._brushCvs.height = outerRadius; + + const gradient = this._brushCtx.createRadialGradient( x, y, innerRadius, x, y, outerRadius ); + gradient.addColorStop( 0, color ); + gradient.addColorStop( 1, 'rgba(255,255,255,0)' ); + + this._brushCtx.clearRect( 0, 0, this._brushCvs.width, this._brushCvs.height ); + this._brushCtx.arc( x, y, radius, 0, 2 * Math.PI ); + this._brushCtx.fillStyle = gradient; + this._brushCtx.fill(); + + this._halfRadius = radius / 2; + } + + // overridden from zCanvas.sprite + handleMove( x, y ) { + if ( !this.isDrawable() ) { + return super.handleMove( x, y ); + } + // cache this upfront + const ctx = this.isMaskable() ? this._layer.mask.getContext( "2d" ) : this._bitmap.getContext( "2d" ); + // note we draw onto the layer bitmap to make this permanent + ctx.drawImage( this._brushCvs, x - this._halfRadius, y - this._halfRadius ); + } } -sprite.extend( LayerSprite ); export default LayerSprite; - -/* instance methods */ - -LayerSprite.prototype.isDrawable = function() { - return this._layer.type === LAYER_GRAPHIC || this.isMaskable(); -}; - -LayerSprite.prototype.isMaskable = function() { - return !!this._layer.mask; -}; - -LayerSprite.prototype.cacheGradient = function( color, radius = 30 ) { - const innerRadius = radius / 6; - const outerRadius = radius * 2; - - const x = radius; - const y = radius; - - // update brush Canvas size - this._brushCvs.width = outerRadius; - this._brushCvs.height = outerRadius; - - const gradient = this._brushCtx.createRadialGradient( x, y, innerRadius, x, y, outerRadius ); - gradient.addColorStop( 0, color ); - gradient.addColorStop( 1, 'rgba(255,255,255,0)' ); - - this._brushCtx.clearRect( 0, 0, this._brushCvs.width, this._brushCvs.height ); - this._brushCtx.arc( x, y, radius, 0, 2 * Math.PI ); - this._brushCtx.fillStyle = gradient; - this._brushCtx.fill(); - - this._halfRadius = radius / 2; -}; - -// overridden from zCanvas.sprite -LayerSprite.prototype.handleMove = function( x, y ) { - // cache this upfront - const ctx = this.isMaskable() ? this._layer.mask.getContext( "2d" ) : this._bitmap.getContext( "2d" ); - // note we draw onto the layer bitmap to make this permanent - ctx.drawImage( this._brushCvs, x - this._halfRadius, y - this._halfRadius ); -}; diff --git a/src/components/ui/zcanvas/zoomable-canvas.js b/src/components/ui/zcanvas/zoomable-canvas.js index 2ed2fe4..eefbd33 100644 --- a/src/components/ui/zcanvas/zoomable-canvas.js +++ b/src/components/ui/zcanvas/zoomable-canvas.js @@ -22,77 +22,76 @@ */ import { canvas } from "zcanvas"; -function ZoomableCanvas( opts ) { - ZoomableCanvas.super( this, "constructor", opts ); // zCanvas inheritance +class ZoomableCanvas extends canvas { + constructor( opts ) { + super( opts ); + this.setZoomFactor( 1 ); + } - this.setZoomFactor = function( xScale, yScale ) { + setZoomFactor( xScale, yScale ) { this.zoomFactor = xScale; // This zoom factor logic should move into the zCanvas // library where updateCanvasSize() takes this additional factor into account - this._canvasContext.scale( xScale, yScale ); - this.invalidate(); - }; + this._canvasContext.scale( xScale, yScale ); + this.invalidate(); + } + // TODO add the lines suffixed with // QQQ to zCanvas lib instead of using these overrides - this.setZoomFactor( 1 ); -} -canvas.extend( ZoomableCanvas ); -export default ZoomableCanvas; + handleInteraction( aEvent ) { + const numChildren = this._children.length; + let theChild, touches, found; -// TODO add the lines suffixed with // QQQ to zCanvas lib instead of using these overrides + if ( numChildren > 0 ) { -ZoomableCanvas.prototype.handleInteraction = function( aEvent ) { - const numChildren = this._children.length; - let theChild, touches, found; + // reverse loop to first handle top layers + theChild = this._children[ numChildren - 1 ]; - if ( numChildren > 0 ) { + switch ( aEvent.type ) { - // reverse loop to first handle top layers - theChild = this._children[ numChildren - 1 ]; + // all touch events + default: + let eventOffsetX = 0, eventOffsetY = 0; + touches /** @type {TouchList} */ = ( aEvent.touches.length > 0 ) ? aEvent.touches : aEvent.changedTouches; - switch ( aEvent.type ) { + if ( touches.length > 0 ) { + const offset = this.getCoordinate(); - // all touch events - default: - let eventOffsetX = 0, eventOffsetY = 0; - touches /** @type {TouchList} */ = ( aEvent.touches.length > 0 ) ? aEvent.touches : aEvent.changedTouches; - - if ( touches.length > 0 ) { - const offset = this.getCoordinate(); - - eventOffsetX = ( touches[ 0 ].pageX - offset.x ) / this.zoomFactor ; // QQQ - eventOffsetY = ( touches[ 0 ].pageY - offset.y ) / this.zoomFactor; // QQQ - } - - while ( theChild ) { - theChild.handleInteraction( eventOffsetX, eventOffsetY, aEvent ); - theChild = theChild.last; // note we don't break this loop for multi touch purposes - } - break; - - // all mouse events - case "mousedown": - case "mousemove": - case "mouseup": - let { offsetX, offsetY } = aEvent; - offsetX /= this.zoomFactor; // QQQ - offsetY /= this.zoomFactor; // QQQ - while ( theChild ) { - found = theChild.handleInteraction( offsetX, offsetY, aEvent ); - if ( found ) { - break; + eventOffsetX = ( touches[ 0 ].pageX - offset.x ) / this.zoomFactor ; // QQQ + eventOffsetY = ( touches[ 0 ].pageY - offset.y ) / this.zoomFactor; // QQQ } - theChild = theChild.last; - } - break; + + while ( theChild ) { + theChild.handleInteraction( eventOffsetX, eventOffsetY, aEvent ); + theChild = theChild.last; // note we don't break this loop for multi touch purposes + } + break; + + // all mouse events + case "mousedown": + case "mousemove": + case "mouseup": + let { offsetX, offsetY } = aEvent; + offsetX /= this.zoomFactor; // QQQ + offsetY /= this.zoomFactor; // QQQ + while ( theChild ) { + found = theChild.handleInteraction( offsetX, offsetY, aEvent ); + if ( found ) { + break; + } + theChild = theChild.last; + } + break; + } } + if ( this._preventDefaults ) { + aEvent.stopPropagation(); + aEvent.preventDefault(); + } + // update the Canvas contents + this.invalidate(); } - if ( this._preventDefaults ) { - aEvent.stopPropagation(); - aEvent.preventDefault(); - } - // update the Canvas contents - this.invalidate(); -}; +} +export default ZoomableCanvas;