UNPKG

fabric

Version:

Object model for HTML5 canvas, and SVG-to-canvas parser. Backed by jsdom and node-canvas.

118 lines (102 loc) 3.34 kB
import { Object as FabricObject, Point, util, Control, } from '../../dist/index.mjs'; // Swapping of calcCornerCoords in #9377 // OLD CODE FOR REFERENCE AND IMPLEMENTATION TEST const halfPI = Math.PI / 2; class OldControl extends Control { calcCornerCoords( objectAngle, angle, objectCornerSize, centerX, centerY, isTouch ) { let cosHalfOffset, sinHalfOffset, cosHalfOffsetComp, sinHalfOffsetComp; const xSize = isTouch ? this.touchSizeX : this.sizeX, ySize = isTouch ? this.touchSizeY : this.sizeY; if (xSize && ySize && xSize !== ySize) { // handle rectangular corners const controlTriangleAngle = Math.atan2(ySize, xSize); const cornerHypotenuse = Math.sqrt(xSize * xSize + ySize * ySize) / 2; const newTheta = controlTriangleAngle - util.degreesToRadians(objectAngle); const newThetaComp = halfPI - controlTriangleAngle - util.degreesToRadians(objectAngle); cosHalfOffset = cornerHypotenuse * util.cos(newTheta); sinHalfOffset = cornerHypotenuse * util.sin(newTheta); // use complementary angle for two corners cosHalfOffsetComp = cornerHypotenuse * util.cos(newThetaComp); sinHalfOffsetComp = cornerHypotenuse * util.sin(newThetaComp); } else { // handle square corners // use default object corner size unless size is defined const cornerSize = xSize && ySize ? xSize : objectCornerSize; const cornerHypotenuse = cornerSize * Math.SQRT1_2; // complementary angles are equal since they're both 45 degrees const newTheta = util.degreesToRadians(45 - objectAngle); cosHalfOffset = cosHalfOffsetComp = cornerHypotenuse * util.cos(newTheta); sinHalfOffset = sinHalfOffsetComp = cornerHypotenuse * util.sin(newTheta); } return { tl: new Point(centerX - sinHalfOffsetComp, centerY - cosHalfOffsetComp), tr: new Point(centerX + cosHalfOffset, centerY - sinHalfOffset), bl: new Point(centerX - cosHalfOffset, centerY + sinHalfOffset), br: new Point(centerX + sinHalfOffsetComp, centerY + cosHalfOffsetComp), }; } } class OldObject extends FabricObject { _calcCornerCoords(control, position) { const corner = control.calcCornerCoords( this.angle, this.cornerSize, position.x, position.y, false ); const touchCorner = control.calcCornerCoords( this.angle, this.touchCornerSize, position.x, position.y, true ); return { corner, touchCorner }; } } // END OF OLD CODE const newObject = new FabricObject({ width: 100, height: 100 }); const oldObject = new OldObject({ width: 100, height: 100 }); newObject.controls = { tl: new Control({ x: -0.5, y: -0.5, }), }; oldObject.controls = { tl: new OldControl({ x: -0.5, y: -0.5, }), }; const benchmark = (callback) => { const start = Date.now(); callback(); return Date.now() - start; }; const controlNew = benchmark(() => { for (let i = 0; i < 1_000_000; i++) { newObject._calcCornerCoords(newObject.controls.tl, new Point(4.5, 4.5)); } }); const controlOld = benchmark(() => { for (let i = 0; i < 1_000_000; i++) { oldObject._calcCornerCoords(oldObject.controls.tl, new Point(4.5, 4.5)); } }); console.log({ controlOld, controlNew });