@js-draw/math 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -133,19 +133,6 @@ export declare class Mat33 {
133
133
  * @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
134
134
  */
135
135
  toCSSMatrix(): string;
136
- /**
137
- * @beta May change or even be removed between minor releases.
138
- *
139
- * Converts this matrix into a list of CSS transforms that attempt to preserve
140
- * this matrix's translation.
141
- *
142
- * In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
143
- * of using lower-precision floating point numbers). This works around
144
- * that by expanding this matrix into the product of several CSS transforms.
145
- *
146
- * **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
147
- */
148
- toSafeCSSTransformList(): string;
149
136
  /**
150
137
  * Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
151
138
  *
package/dist/cjs/Mat33.js CHANGED
@@ -6,7 +6,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Mat33 = void 0;
7
7
  const Vec2_1 = require("./Vec2");
8
8
  const Vec3_1 = __importDefault(require("./Vec3"));
9
- const rounding_1 = require("./rounding");
10
9
  /**
11
10
  * Represents a three dimensional linear transformation or
12
11
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
@@ -326,123 +325,6 @@ class Mat33 {
326
325
  toCSSMatrix() {
327
326
  return `matrix(${this.a1},${this.b1},${this.a2},${this.b2},${this.a3},${this.b3})`;
328
327
  }
329
- /**
330
- * @beta May change or even be removed between minor releases.
331
- *
332
- * Converts this matrix into a list of CSS transforms that attempt to preserve
333
- * this matrix's translation.
334
- *
335
- * In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
336
- * of using lower-precision floating point numbers). This works around
337
- * that by expanding this matrix into the product of several CSS transforms.
338
- *
339
- * **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
340
- */
341
- toSafeCSSTransformList() {
342
- // Check whether it's safe to return just the CSS matrix
343
- const translation = Vec2_1.Vec2.of(this.a3, this.b3);
344
- const translationRoundedX = (0, rounding_1.toRoundedString)(translation.x);
345
- const translationRoundedY = (0, rounding_1.toRoundedString)(translation.y);
346
- const nonDigitsRegex = /[^0-9]+/g;
347
- const translationXDigits = translationRoundedX.replace(nonDigitsRegex, '').length;
348
- const translationYDigits = translationRoundedY.replace(nonDigitsRegex, '').length;
349
- // Is it safe to just return the default CSS matrix?
350
- if (translationXDigits <= 5 && translationYDigits <= 5) {
351
- return this.toCSSMatrix();
352
- }
353
- // Remove the last column (the translation column)
354
- let transform = new Mat33(this.a1, this.a2, 0, this.b1, this.b2, 0, 0, 0, 1);
355
- const transforms = [];
356
- let lastScale = null;
357
- // Appends a translate() command to the list of `transforms`.
358
- const addTranslate = (translation) => {
359
- lastScale = null;
360
- if (!translation.eq(Vec2_1.Vec2.zero)) {
361
- transforms.push(`translate(${(0, rounding_1.toRoundedString)(translation.x)}px, ${(0, rounding_1.toRoundedString)(translation.y)}px)`);
362
- }
363
- };
364
- // Appends a scale() command to the list of transforms, possibly merging with
365
- // the last command, if a scale().
366
- const addScale = (scale) => {
367
- // Merge with the last scale
368
- if (lastScale) {
369
- const newScale = lastScale.scale(scale);
370
- // Don't merge if the new scale has very large values
371
- if (newScale.maximumEntryMagnitude() < 1e7) {
372
- const previousCommand = transforms.pop();
373
- console.assert(previousCommand.startsWith('scale'), 'Invalid state: Merging scale commands');
374
- scale = newScale;
375
- }
376
- }
377
- if (scale.x === scale.y) {
378
- transforms.push(`scale(${(0, rounding_1.toRoundedString)(scale.x)})`);
379
- }
380
- else {
381
- transforms.push(`scale(${(0, rounding_1.toRoundedString)(scale.x)}, ${(0, rounding_1.toRoundedString)(scale.y)})`);
382
- }
383
- lastScale = scale;
384
- };
385
- // Returns the number of digits before the `.` in the given number string.
386
- const digitsPreDecimalCount = (numberString) => {
387
- let decimalIndex = numberString.indexOf('.');
388
- if (decimalIndex === -1) {
389
- decimalIndex = numberString.length;
390
- }
391
- return numberString.substring(0, decimalIndex).replace(nonDigitsRegex, '').length;
392
- };
393
- // Returns the number of digits (positive for left shift, negative for right shift)
394
- // required to shift the decimal to the middle of the number.
395
- const getShift = (numberString) => {
396
- const preDecimal = digitsPreDecimalCount(numberString);
397
- const postDecimal = (numberString.match(/[.](\d*)/) ?? ['', ''])[1].length;
398
- // The shift required to center the decimal point.
399
- const toCenter = postDecimal - preDecimal;
400
- // toCenter is positive for a left shift (adding more pre-decimals),
401
- // so, after applying it,
402
- const postShiftPreDecimal = preDecimal + toCenter;
403
- // We want the digits before the decimal to have a length at most 4, however.
404
- // Thus, right shift until this is the case.
405
- const shiftForAtMost5DigitsPreDecimal = 4 - Math.max(postShiftPreDecimal, 4);
406
- return toCenter + shiftForAtMost5DigitsPreDecimal;
407
- };
408
- const addShiftedTranslate = (translate, depth = 0) => {
409
- const xString = (0, rounding_1.toRoundedString)(translate.x);
410
- const yString = (0, rounding_1.toRoundedString)(translate.y);
411
- const xShiftDigits = getShift(xString);
412
- const yShiftDigits = getShift(yString);
413
- const shift = Vec2_1.Vec2.of(Math.pow(10, xShiftDigits), Math.pow(10, yShiftDigits));
414
- const invShift = Vec2_1.Vec2.of(Math.pow(10, -xShiftDigits), Math.pow(10, -yShiftDigits));
415
- addScale(invShift);
416
- const shiftedTranslate = translate.scale(shift);
417
- const roundedShiftedTranslate = Vec2_1.Vec2.of(Math.floor(shiftedTranslate.x), Math.floor(shiftedTranslate.y));
418
- addTranslate(roundedShiftedTranslate);
419
- // Don't recurse more than 3 times -- the more times we recurse, the more
420
- // the scaling is influenced by error.
421
- if (!roundedShiftedTranslate.eq(shiftedTranslate) && depth < 3) {
422
- addShiftedTranslate(shiftedTranslate.minus(roundedShiftedTranslate), depth + 1);
423
- }
424
- addScale(shift);
425
- return translate;
426
- };
427
- const adjustTransformFromScale = () => {
428
- if (lastScale) {
429
- const scaledTransform = transform.rightMul(Mat33.scaling2D(lastScale));
430
- // If adding the scale to the transform leads to large values, avoid
431
- // doing this.
432
- if (scaledTransform.maximumEntryMagnitude() < 1e12) {
433
- transforms.pop();
434
- transform = transform.rightMul(Mat33.scaling2D(lastScale));
435
- lastScale = null;
436
- }
437
- }
438
- };
439
- addShiftedTranslate(translation);
440
- adjustTransformFromScale();
441
- if (!transform.eq(Mat33.identity)) {
442
- transforms.push(transform.toCSSMatrix());
443
- }
444
- return transforms.join(' ');
445
- }
446
328
  /**
447
329
  * Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
448
330
  *
@@ -0,0 +1 @@
1
+ export {};
@@ -133,19 +133,6 @@ export declare class Mat33 {
133
133
  * @see {@link fromCSSMatrix} and {@link toSafeCSSTransformList}
134
134
  */
135
135
  toCSSMatrix(): string;
136
- /**
137
- * @beta May change or even be removed between minor releases.
138
- *
139
- * Converts this matrix into a list of CSS transforms that attempt to preserve
140
- * this matrix's translation.
141
- *
142
- * In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
143
- * of using lower-precision floating point numbers). This works around
144
- * that by expanding this matrix into the product of several CSS transforms.
145
- *
146
- * **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
147
- */
148
- toSafeCSSTransformList(): string;
149
136
  /**
150
137
  * Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
151
138
  *
@@ -1,6 +1,5 @@
1
1
  import { Vec2 } from './Vec2.mjs';
2
2
  import Vec3 from './Vec3.mjs';
3
- import { toRoundedString } from './rounding.mjs';
4
3
  /**
5
4
  * Represents a three dimensional linear transformation or
6
5
  * a two-dimensional affine transformation. (An affine transformation scales/rotates/shears
@@ -320,123 +319,6 @@ export class Mat33 {
320
319
  toCSSMatrix() {
321
320
  return `matrix(${this.a1},${this.b1},${this.a2},${this.b2},${this.a3},${this.b3})`;
322
321
  }
323
- /**
324
- * @beta May change or even be removed between minor releases.
325
- *
326
- * Converts this matrix into a list of CSS transforms that attempt to preserve
327
- * this matrix's translation.
328
- *
329
- * In Chrome/Firefox, translation attributes only support 6 digits (likely an artifact
330
- * of using lower-precision floating point numbers). This works around
331
- * that by expanding this matrix into the product of several CSS transforms.
332
- *
333
- * **Note**: Assumes `this.c1 = this.c2 = 0` and `this.c3 = 1`.
334
- */
335
- toSafeCSSTransformList() {
336
- // Check whether it's safe to return just the CSS matrix
337
- const translation = Vec2.of(this.a3, this.b3);
338
- const translationRoundedX = toRoundedString(translation.x);
339
- const translationRoundedY = toRoundedString(translation.y);
340
- const nonDigitsRegex = /[^0-9]+/g;
341
- const translationXDigits = translationRoundedX.replace(nonDigitsRegex, '').length;
342
- const translationYDigits = translationRoundedY.replace(nonDigitsRegex, '').length;
343
- // Is it safe to just return the default CSS matrix?
344
- if (translationXDigits <= 5 && translationYDigits <= 5) {
345
- return this.toCSSMatrix();
346
- }
347
- // Remove the last column (the translation column)
348
- let transform = new Mat33(this.a1, this.a2, 0, this.b1, this.b2, 0, 0, 0, 1);
349
- const transforms = [];
350
- let lastScale = null;
351
- // Appends a translate() command to the list of `transforms`.
352
- const addTranslate = (translation) => {
353
- lastScale = null;
354
- if (!translation.eq(Vec2.zero)) {
355
- transforms.push(`translate(${toRoundedString(translation.x)}px, ${toRoundedString(translation.y)}px)`);
356
- }
357
- };
358
- // Appends a scale() command to the list of transforms, possibly merging with
359
- // the last command, if a scale().
360
- const addScale = (scale) => {
361
- // Merge with the last scale
362
- if (lastScale) {
363
- const newScale = lastScale.scale(scale);
364
- // Don't merge if the new scale has very large values
365
- if (newScale.maximumEntryMagnitude() < 1e7) {
366
- const previousCommand = transforms.pop();
367
- console.assert(previousCommand.startsWith('scale'), 'Invalid state: Merging scale commands');
368
- scale = newScale;
369
- }
370
- }
371
- if (scale.x === scale.y) {
372
- transforms.push(`scale(${toRoundedString(scale.x)})`);
373
- }
374
- else {
375
- transforms.push(`scale(${toRoundedString(scale.x)}, ${toRoundedString(scale.y)})`);
376
- }
377
- lastScale = scale;
378
- };
379
- // Returns the number of digits before the `.` in the given number string.
380
- const digitsPreDecimalCount = (numberString) => {
381
- let decimalIndex = numberString.indexOf('.');
382
- if (decimalIndex === -1) {
383
- decimalIndex = numberString.length;
384
- }
385
- return numberString.substring(0, decimalIndex).replace(nonDigitsRegex, '').length;
386
- };
387
- // Returns the number of digits (positive for left shift, negative for right shift)
388
- // required to shift the decimal to the middle of the number.
389
- const getShift = (numberString) => {
390
- const preDecimal = digitsPreDecimalCount(numberString);
391
- const postDecimal = (numberString.match(/[.](\d*)/) ?? ['', ''])[1].length;
392
- // The shift required to center the decimal point.
393
- const toCenter = postDecimal - preDecimal;
394
- // toCenter is positive for a left shift (adding more pre-decimals),
395
- // so, after applying it,
396
- const postShiftPreDecimal = preDecimal + toCenter;
397
- // We want the digits before the decimal to have a length at most 4, however.
398
- // Thus, right shift until this is the case.
399
- const shiftForAtMost5DigitsPreDecimal = 4 - Math.max(postShiftPreDecimal, 4);
400
- return toCenter + shiftForAtMost5DigitsPreDecimal;
401
- };
402
- const addShiftedTranslate = (translate, depth = 0) => {
403
- const xString = toRoundedString(translate.x);
404
- const yString = toRoundedString(translate.y);
405
- const xShiftDigits = getShift(xString);
406
- const yShiftDigits = getShift(yString);
407
- const shift = Vec2.of(Math.pow(10, xShiftDigits), Math.pow(10, yShiftDigits));
408
- const invShift = Vec2.of(Math.pow(10, -xShiftDigits), Math.pow(10, -yShiftDigits));
409
- addScale(invShift);
410
- const shiftedTranslate = translate.scale(shift);
411
- const roundedShiftedTranslate = Vec2.of(Math.floor(shiftedTranslate.x), Math.floor(shiftedTranslate.y));
412
- addTranslate(roundedShiftedTranslate);
413
- // Don't recurse more than 3 times -- the more times we recurse, the more
414
- // the scaling is influenced by error.
415
- if (!roundedShiftedTranslate.eq(shiftedTranslate) && depth < 3) {
416
- addShiftedTranslate(shiftedTranslate.minus(roundedShiftedTranslate), depth + 1);
417
- }
418
- addScale(shift);
419
- return translate;
420
- };
421
- const adjustTransformFromScale = () => {
422
- if (lastScale) {
423
- const scaledTransform = transform.rightMul(Mat33.scaling2D(lastScale));
424
- // If adding the scale to the transform leads to large values, avoid
425
- // doing this.
426
- if (scaledTransform.maximumEntryMagnitude() < 1e12) {
427
- transforms.pop();
428
- transform = transform.rightMul(Mat33.scaling2D(lastScale));
429
- lastScale = null;
430
- }
431
- }
432
- };
433
- addShiftedTranslate(translation);
434
- adjustTransformFromScale();
435
- if (!transform.eq(Mat33.identity)) {
436
- transforms.push(transform.toCSSMatrix());
437
- }
438
- return transforms.join(' ');
439
- }
440
322
  /**
441
323
  * Converts a CSS-form `matrix(a, b, c, d, e, f)` to a Mat33.
442
324
  *
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@js-draw/math",
3
- "version": "1.3.1",
3
+ "version": "1.4.0",
4
4
  "description": "A math library for js-draw. ",
5
5
  "types": "./dist/mjs/lib.d.ts",
6
6
  "main": "./dist/cjs/lib.js",
@@ -28,7 +28,7 @@
28
28
  "bezier-js": "6.1.3"
29
29
  },
30
30
  "devDependencies": {
31
- "@js-draw/build-tool": "^1.0.2",
31
+ "@js-draw/build-tool": "^1.4.0",
32
32
  "@types/bezier-js": "4.1.0",
33
33
  "@types/jest": "29.5.3",
34
34
  "@types/jsdom": "21.1.1"
@@ -45,5 +45,5 @@
45
45
  "svg",
46
46
  "math"
47
47
  ],
48
- "gitHead": "65af7ec944f70b69b2a4b07d98e5bb92eeeca029"
48
+ "gitHead": "b520078c16a4d23d9bed4531eafda87bfce3f6b1"
49
49
  }