11// 3 shears
22
3-
43export function threeShears ( spriteCanv , canvas , angle ) {
54 const spriteCtx = spriteCanv . getContext ( '2d' ) ;
65
76 const flipped = angle > 90 && angle < 270 ;
8- // TODO: fix padding clipping
97
10- let { diagonal , xMargin , yMargin } = getRotateDiagonal (
8+ const diag = getRotateDiagonal (
119 spriteCanv . width ,
1210 spriteCanv . height ,
1311 ) ;
12+ const minXPad = 1 + ( 0 | ( spriteCanv . width / 2 ) ) ;
13+ const overflow = diag . xMargin < minXPad ? minXPad - diag . xMargin : 0 ;
14+ const diagonal = diag . diagonal + overflow * 2 ;
15+ const xMargin = diag . xMargin + overflow ;
16+ const yMargin = diag . yMargin + overflow ;
1417 const width = diagonal ;
1518 const height = diagonal ;
1619
@@ -21,29 +24,29 @@ export function threeShears(spriteCanv, canvas, angle) {
2124 spriteCanv . height ,
2225 ) ;
2326
27+
2428 spriteCanv . width = diagonal ;
25- spriteCanv . height = diagonal ;
29+ spriteCanv . height = spriteCanv . width ;
2630
2731 if ( flipped ) {
28- spriteCtx . putImageData ( flipImageData ( copy ) , xMargin + 1 , yMargin + 1 ) ;
32+ spriteCtx . putImageData (
33+ flipImageData ( copy ) ,
34+ xMargin + 1 ,
35+ yMargin + 1 ,
36+ ) ;
2937 } else {
3038 spriteCtx . putImageData ( copy , xMargin , yMargin ) ;
31-
3239 }
3340
3441 const ctx = canvas . getContext ( '2d' ) ;
35- canvas . width = width ;
36- canvas . height = height ;
37-
38- // ctx.drawImage(spriteCanv,0,0);
39- // return;
42+ canvas . width = diagonal ;
43+ canvas . height = diagonal ;
4044
4145 // rotate
4246
4347 const clampedAngle = flipped ? angle - 180 : angle ;
4448 const theta = ( clampedAngle * Math . PI ) / 180 ;
4549 const alpha = - Math . tan ( theta / 2 ) ;
46- const beta = Math . sin ( theta ) ;
4750
4851 for ( let y = 0 ; y < height ; ++ y ) {
4952 const shear = Math . round ( ( y - height / 2 ) * alpha ) ;
@@ -53,7 +56,7 @@ export function threeShears(spriteCanv, canvas, angle) {
5356 spriteCtx . drawImage ( canvas , 0 , 0 ) ;
5457 ctx . clearRect ( 0 , 0 , width , height ) ;
5558 for ( let x = 0 ; x < width ; ++ x ) {
56- const shear = Math . round ( ( x - width / 2 ) * beta ) ;
59+ const shear = Math . round ( ( x - width / 2 ) * Math . sin ( theta ) ) ;
5760 ctx . drawImage ( spriteCanv , x , 0 , 1 , height , x , shear , 1 , height ) ;
5861 }
5962 spriteCtx . clearRect ( 0 , 0 , width , height ) ;
@@ -63,6 +66,12 @@ export function threeShears(spriteCanv, canvas, angle) {
6366 const shear = Math . round ( ( y - height / 2 ) * alpha ) ;
6467 ctx . drawImage ( spriteCanv , 0 , y , width , 1 , shear , y , width , 1 ) ;
6568 }
69+
70+ // crop overflow
71+ const inner = ctx . getImageData ( overflow , overflow , diag . diagonal , diag . diagonal ) ;
72+ canvas . width = diag . diagonal ;
73+ canvas . height = diag . diagonal ;
74+ ctx . putImageData ( inner , 0 , 0 ) ;
6675}
6776
6877function flipImageData ( imageData ) {
@@ -84,7 +93,6 @@ function flipImageData(imageData) {
8493 return rotatedImageData ;
8594}
8695
87-
8896// common
8997
9098function getRotateDiagonal ( width , height ) {
@@ -103,7 +111,6 @@ function getRotateDiagonal(width, height) {
103111// stole code from ChaseMor/pxt-arcade-rotsprite
104112// some generated with chatGPT
105113
106-
107114export function rotsprite ( spriteCanv , canvas , angle ) {
108115 const spriteCtx = spriteCanv . getContext ( '2d' ) ;
109116 const { width, height } = spriteCanv ;
@@ -119,11 +126,7 @@ export function rotsprite(spriteCanv, canvas, angle) {
119126function rotateImageData ( imageData , angle , width , height ) {
120127 const { diagonal, xMargin, yMargin } = getRotateDiagonal ( width , height ) ;
121128
122- const spriteData = addMarginToImageData (
123- imageData ,
124- xMargin ,
125- yMargin ,
126- ) ;
129+ const spriteData = addMarginToImageData ( imageData , xMargin , yMargin ) ;
127130
128131 const data = new Uint32Array ( diagonal ** 2 ) ;
129132
0 commit comments