@@ -146,14 +146,6 @@ export default class PgInputPixelEditor extends HTMLElement {
146146 'pointerdown' ,
147147 this . handlePointerDown . bind ( this )
148148 ) ;
149- this . $canvas . addEventListener (
150- 'pointerup' ,
151- this . handlePointerUp . bind ( this )
152- ) ;
153- this . $canvas . addEventListener (
154- 'pointermove' ,
155- this . handlePointerMove . bind ( this )
156- ) ;
157149 this . $canvas . addEventListener (
158150 'pointerenter' ,
159151 this . handlePointerEnter . bind ( this )
@@ -266,11 +258,13 @@ export default class PgInputPixelEditor extends HTMLElement {
266258 } ;
267259
268260 #setPixel( x : number , y : number , color : number ) {
269- if ( x > this . width ) {
270- throw new Error ( `Invalid x; ${ x } > ${ this . width } ` ) ;
261+ if ( x >= this . width || x < 0 ) {
262+ return ;
263+ // throw new Error(`Invalid x; ${x} > ${this.width} or ${x} < 0`);
271264 }
272- if ( y > this . height ) {
273- throw new Error ( `Invalid y; ${ y } > ${ this . height } ` ) ;
265+ if ( y >= this . height || y < 0 ) {
266+ return ;
267+ // throw new Error(`Invalid y; ${y} > ${this.height} or ${x} < 0`);
274268 }
275269 const totalSize = this . size + this . gridSize ;
276270 // Edit Layer
@@ -306,7 +300,6 @@ export default class PgInputPixelEditor extends HTMLElement {
306300 x * totalSize , y * totalSize , this . size + 2 , this . size + 2 ,
307301 x * totalSize , y * totalSize , this . size + 2 , this . size + 2
308302 ) ;
309- console . log ( 'draw pixel(x, y, color, data):' , x , y , color , this . #data[ this . #layer] [ y ] [ x ] ) ;
310303 // Verify this is the only place setting pixel data!
311304 this . #data[ this . #layer] [ y ] [ x ] = color ;
312305 this . #delayedChange( ) ;
@@ -411,6 +404,9 @@ export default class PgInputPixelEditor extends HTMLElement {
411404 event ?. preventDefault ( ) ;
412405 }
413406
407+ #handlePointerMoveCache;
408+ #handlePointerUpCache;
409+
414410 handlePointerDown ( event : MouseEvent ) {
415411 if ( event . buttons !== 1 && event . buttons !== 32 ) {
416412 event . preventDefault ( ) ;
@@ -443,18 +439,40 @@ export default class PgInputPixelEditor extends HTMLElement {
443439 break ;
444440 }
445441 console . log ( this . #inputMode, newX , newY ) ;
442+ // track movement
443+ this . #handlePointerMoveCache = this . handlePointerMove . bind ( this ) ;
444+ document . addEventListener ( 'pointermove' , this . #handlePointerMoveCache) ;
445+ // pointer outside
446+ this . #handlePointerUpCache = this . handlePointerUp . bind ( this ) ;
447+ document . addEventListener ( 'pointerup' , this . #handlePointerUpCache) ;
448+ }
449+
450+ #pointerOutside = false ;
451+ handlePointerUpGlobal ( ) {
452+ if ( this . #pointerOutside) {
453+ this . handlePointerUp ( {
454+ clientX : 100 ,
455+ clientY : 100
456+ } as any ) ;
457+ this . cleanupPointerGlobal ( ) ;
458+ }
459+ }
460+
461+ cleanupPointerGlobal ( ) {
462+ document . removeEventListener ( 'pointermove' , this . #handlePointerMoveCache) ;
463+ document . removeEventListener ( 'pointerup' , this . #handlePointerUpCache) ;
446464 }
447465
448466 handlePointerUp ( event : MouseEvent ) {
449467 const rect = this . $canvas . getBoundingClientRect ( ) ;
450468 const totalSize = this . size + this . gridSize ;
451469 let newX = Math . floor ( ( event . clientX - rect . left ) / totalSize ) ;
452470 let newY = Math . floor ( ( event . clientY - rect . top ) / totalSize ) ;
453- if ( newX >= this . width ) { newX = this . width - 1 ; }
454- if ( newY >= this . height ) { newY = this . height - 1 ; }
455- if ( this . #startX === - 1 && this . #startY === - 1 ) {
456- return ;
457- }
471+ // if (newX >= this.width) { newX = this.width - 1; }
472+ // if (newY >= this.height) { newY = this.height - 1; }
473+ // if (this.#startX === -1 && this.#startY === -1) {
474+ // return;
475+ // }
458476 // Single Tap
459477 if ( newX === this . #startX && newY === this . #startY && this . #startColor === 1 ) {
460478 switch ( this . #inputMode) {
@@ -495,6 +513,7 @@ export default class PgInputPixelEditor extends HTMLElement {
495513 this . #x = - 1 ;
496514 this . #y = - 1 ;
497515 this . #isPressed = false ;
516+ this . cleanupPointerGlobal ( ) ;
498517 }
499518
500519 handlePointerMove ( event : PointerEvent ) {
@@ -518,7 +537,7 @@ export default class PgInputPixelEditor extends HTMLElement {
518537 for ( const evt of events ) {
519538 let tX = Math . floor ( ( evt . clientX - rect . left ) / totalSize ) ;
520539 let tY = Math . floor ( ( evt . clientY - rect . top ) / totalSize ) ;
521- if ( tX >= this . width || tY >= this . height || ( tX === x && tY === y ) ) {
540+ if ( tX === x && tY === y ) {
522541 continue ;
523542 }
524543 points . push ( [ tX , tY ] ) ;
@@ -527,8 +546,6 @@ export default class PgInputPixelEditor extends HTMLElement {
527546 let newX = Math . floor ( ( event . clientX - rect . left ) / totalSize ) ;
528547 let newY = Math . floor ( ( event . clientY - rect . top ) / totalSize ) ;
529548 if ( newX === x && newY === y ) { return ; }
530- if ( newX >= this . width ) { newX = this . width - 1 ; }
531- if ( newY >= this . height ) { newY = this . height - 1 ; }
532549 points . push ( [ newX , newY ] ) ;
533550 }
534551 // Is Eraser
@@ -575,6 +592,7 @@ export default class PgInputPixelEditor extends HTMLElement {
575592 // editing layer to main canvas
576593 this . #context. drawImage ( this . #isEditing ? this . #editLayer : this . #noEditLayer, 0 , 0 ) ;
577594 }
595+ this . #pointerOutside = false ;
578596 }
579597
580598 handlePointerLeave ( event : MouseEvent ) {
@@ -584,6 +602,8 @@ export default class PgInputPixelEditor extends HTMLElement {
584602 this . #context. drawImage ( this . #baseLayer, 0 , 0 ) ;
585603 // editing layer to main canvas
586604 this . #context. drawImage ( this . #isEditing ? this . #editLayer : this . #noEditLayer, 0 , 0 ) ;
605+ } else if ( this . #isEditing) {
606+ this . #pointerOutside = true ;
587607 }
588608 }
589609
0 commit comments