All files / core/src/RenderingEngine/helpers/cpuFallback/rendering transform.ts

0% Statements 0/55
100% Branches 0/0
0% Functions 0/10
0% Lines 0/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127                                                                                                                                                                                                                                                             
import type {
  CPUFallbackTransform,
  Point2,
  TransformMatrix2D,
} from '../../../../types';
 
// By Simon Sarris
// Www.simonsarris.com
// Sarris@acm.org
//
// Free to use and distribute at will
// So long as you are nice to people, etc
 
// Simple class for keeping track of the current transformation matrix
 
// For instance:
//    Var t = new Transform();
//    T.rotate(5);
//    Var m = t.m;
//    Ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);
 
// Is equivalent to:
//    Ctx.rotate(5);
 
// But now you can retrieve it :)
 
// Remember that this does not account for any CSS transforms applied to the canvas
export class Transform implements CPUFallbackTransform {
  private m: TransformMatrix2D;
 
  constructor() {
    this.reset();
  }
 
  getMatrix(): TransformMatrix2D {
    return this.m;
  }
 
  reset(): void {
    this.m = [1, 0, 0, 1, 0, 0];
  }
 
  clone(): CPUFallbackTransform {
    const transform = new Transform();
 
    transform.m[0] = this.m[0];
    transform.m[1] = this.m[1];
    transform.m[2] = this.m[2];
    transform.m[3] = this.m[3];
    transform.m[4] = this.m[4];
    transform.m[5] = this.m[5];
 
    return transform;
  }
 
  multiply(matrix: TransformMatrix2D): void {
    const m11 = this.m[0] * matrix[0] + this.m[2] * matrix[1];
    const m12 = this.m[1] * matrix[0] + this.m[3] * matrix[1];
 
    const m21 = this.m[0] * matrix[2] + this.m[2] * matrix[3];
    const m22 = this.m[1] * matrix[2] + this.m[3] * matrix[3];
 
    const dx = this.m[0] * matrix[4] + this.m[2] * matrix[5] + this.m[4];
    const dy = this.m[1] * matrix[4] + this.m[3] * matrix[5] + this.m[5];
 
    this.m[0] = m11;
    this.m[1] = m12;
    this.m[2] = m21;
    this.m[3] = m22;
    this.m[4] = dx;
    this.m[5] = dy;
  }
 
  invert(): void {
    const d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);
    const m0 = this.m[3] * d;
    const m1 = -this.m[1] * d;
    const m2 = -this.m[2] * d;
    const m3 = this.m[0] * d;
    const m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);
    const m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);
 
    this.m[0] = m0;
    this.m[1] = m1;
    this.m[2] = m2;
    this.m[3] = m3;
    this.m[4] = m4;
    this.m[5] = m5;
  }
 
  rotate(rad: number): void {
    const c = Math.cos(rad);
    const s = Math.sin(rad);
    const m11 = this.m[0] * c + this.m[2] * s;
    const m12 = this.m[1] * c + this.m[3] * s;
    const m21 = this.m[0] * -s + this.m[2] * c;
    const m22 = this.m[1] * -s + this.m[3] * c;
 
    this.m[0] = m11;
    this.m[1] = m12;
    this.m[2] = m21;
    this.m[3] = m22;
  }
 
  translate(x: number, y: number): void {
    this.m[4] += this.m[0] * x + this.m[2] * y;
    this.m[5] += this.m[1] * x + this.m[3] * y;
  }
 
  scale(sx: number, sy: number) {
    this.m[0] *= sx;
    this.m[1] *= sx;
    this.m[2] *= sy;
    this.m[3] *= sy;
  }
 
  transformPoint(point: Point2): Point2 {
    const x = point[0];
    const y = point[1];
 
    return [
      x * this.m[0] + y * this.m[2] + this.m[4],
      x * this.m[1] + y * this.m[3] + this.m[5],
    ];
  }
}