diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0223f243489..fdf43405b00 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,7 @@
## [next]
+- chore(TS): migrate Line [#8413](https://github.com/fabricjs/fabric.js/pull/8413)
- chore(TS): migrate Polyline/Polygon [#8417](https://github.com/fabricjs/fabric.js/pull/8417)
- chore(TS): migrate Rect [#8411](https://github.com/fabricjs/fabric.js/pull/8411)
- chore(TS): migrate Ellipse [#8408](https://github.com/fabricjs/fabric.js/pull/8408)
diff --git a/src/shapes/line.class.ts b/src/shapes/line.class.ts
index f2eb40d4bc5..5cfe0e99a6f 100644
--- a/src/shapes/line.class.ts
+++ b/src/shapes/line.class.ts
@@ -1,340 +1,327 @@
-//@ts-nocheck
+// @ts-nocheck
+
+import { fabric } from '../../HEADER';
+import { SHARED_ATTRIBUTES } from '../parser/attributes';
+import { parseAttributes } from '../parser/parseAttributes';
+import { TClassProperties } from '../typedefs';
+import { clone } from '../util/lang_object';
import { FabricObject } from './fabricObject.class';
+import { fabricObjectDefaultValues } from './object.class';
-(function (global) {
- var fabric = global.fabric || (global.fabric = {}),
- extend = fabric.util.object.extend,
- clone = fabric.util.object.clone,
- coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 };
+const coordProps = { x1: 1, x2: 1, y1: 1, y2: 1 };
+export class Line extends FabricObject {
/**
- * Line class
- * @class fabric.Line
- * @extends fabric.Object
- * @see {@link fabric.Line#initialize} for constructor definition
+ * x value or first line edge
+ * @type Number
+ * @default
*/
- fabric.Line = fabric.util.createClass(
- fabric.Object,
- /** @lends fabric.Line.prototype */ {
- /**
- * Type of an object
- * @type String
- * @default
- */
- type: 'line',
-
- /**
- * x value or first line edge
- * @type Number
- * @default
- */
- x1: 0,
-
- /**
- * y value or first line edge
- * @type Number
- * @default
- */
- y1: 0,
-
- /**
- * x value or second line edge
- * @type Number
- * @default
- */
- x2: 0,
-
- /**
- * y value or second line edge
- * @type Number
- * @default
- */
- y2: 0,
-
- cacheProperties: FabricObject.prototype.cacheProperties.concat(
- 'x1',
- 'x2',
- 'y1',
- 'y2'
- ),
-
- /**
- * Constructor
- * @param {Array} [points] Array of points
- * @param {Object} [options] Options object
- * @return {fabric.Line} thisArg
- */
- initialize: function (points, options) {
- if (!points) {
- points = [0, 0, 0, 0];
- }
-
- this.callSuper('initialize', options);
-
- this.set('x1', points[0]);
- this.set('y1', points[1]);
- this.set('x2', points[2]);
- this.set('y2', points[3]);
-
- this._setWidthHeight(options);
- },
+ x1: number;
- /**
- * @private
- * @param {Object} [options] Options
- */
- _setWidthHeight: function (options) {
- options || (options = {});
+ /**
+ * y value or first line edge
+ * @type Number
+ * @default
+ */
+ y1: number;
- this.width = Math.abs(this.x2 - this.x1);
- this.height = Math.abs(this.y2 - this.y1);
+ /**
+ * x value or second line edge
+ * @type Number
+ * @default
+ */
+ x2: number;
- this.left = 'left' in options ? options.left : this._getLeftToOriginX();
+ /**
+ * y value or second line edge
+ * @type Number
+ * @default
+ */
+ y2: number;
- this.top = 'top' in options ? options.top : this._getTopToOriginY();
- },
+ /**
+ * Constructor
+ * @param {Array} [points] Array of points
+ * @param {Object} [options] Options object
+ * @return {Line} thisArg
+ */
+ constructor(points, options) {
+ if (!points) {
+ points = [0, 0, 0, 0];
+ }
- /**
- * @private
- * @param {String} key
- * @param {*} value
- */
- _set: function (key, value) {
- this.callSuper('_set', key, value);
- if (typeof coordProps[key] !== 'undefined') {
- this._setWidthHeight();
- }
- return this;
- },
+ super(options);
- /**
- * @private
- * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.
- */
- _getLeftToOriginX: makeEdgeToOriginGetter(
- {
- // property names
- origin: 'originX',
- axis1: 'x1',
- axis2: 'x2',
- dimension: 'width',
- },
- {
- // possible values of origin
- nearest: 'left',
- center: 'center',
- farthest: 'right',
- }
- ),
-
- /**
- * @private
- * @return {Number} topToOriginY Distance from top edge of canvas to originY of Line.
- */
- _getTopToOriginY: makeEdgeToOriginGetter(
- {
- // property names
- origin: 'originY',
- axis1: 'y1',
- axis2: 'y2',
- dimension: 'height',
- },
- {
- // possible values of origin
- nearest: 'top',
- center: 'center',
- farthest: 'bottom',
- }
- ),
-
- /**
- * @private
- * @param {CanvasRenderingContext2D} ctx Context to render on
- */
- _render: function (ctx) {
- ctx.beginPath();
-
- var p = this.calcLinePoints();
- ctx.moveTo(p.x1, p.y1);
- ctx.lineTo(p.x2, p.y2);
-
- ctx.lineWidth = this.strokeWidth;
-
- // TODO: test this
- // make sure setting "fill" changes color of a line
- // (by copying fillStyle to strokeStyle, since line is stroked, not filled)
- var origStrokeStyle = ctx.strokeStyle;
- ctx.strokeStyle = this.stroke || ctx.fillStyle;
- this.stroke && this._renderStroke(ctx);
- ctx.strokeStyle = origStrokeStyle;
- },
+ this.set('x1', points[0]);
+ this.set('y1', points[1]);
+ this.set('x2', points[2]);
+ this.set('y2', points[3]);
- /**
- * This function is an helper for svg import. it returns the center of the object in the svg
- * untransformed coordinates
- * @private
- * @return {Object} center point from element coordinates
- */
- _findCenterFromElement: function () {
- return {
- x: (this.x1 + this.x2) / 2,
- y: (this.y1 + this.y2) / 2,
- };
- },
+ this._setWidthHeight(options);
+ }
+
+ /**
+ * @private
+ * @param {Object} [options] Options
+ */
+ _setWidthHeight(options) {
+ options || (options = {});
+
+ this.width = Math.abs(this.x2 - this.x1);
+ this.height = Math.abs(this.y2 - this.y1);
+
+ this.left = 'left' in options ? options.left : this._getLeftToOriginX();
+
+ this.top = 'top' in options ? options.top : this._getTopToOriginY();
+ }
+
+ /**
+ * @private
+ * @param {String} key
+ * @param {*} value
+ */
+ _set(key, value) {
+ super._set(key, value);
+ if (typeof coordProps[key] !== 'undefined') {
+ this._setWidthHeight();
+ }
+ return this;
+ }
- /**
- * Returns object representation of an instance
- * @method toObject
- * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
- * @return {Object} object representation of an instance
- */
- toObject: function (propertiesToInclude) {
- return extend(
- this.callSuper('toObject', propertiesToInclude),
- this.calcLinePoints()
+ /**
+ * @private
+ * @param {CanvasRenderingContext2D} ctx Context to render on
+ */
+ _render(ctx) {
+ ctx.beginPath();
+
+ const p = this.calcLinePoints();
+ ctx.moveTo(p.x1, p.y1);
+ ctx.lineTo(p.x2, p.y2);
+
+ ctx.lineWidth = this.strokeWidth;
+
+ // TODO: test this
+ // make sure setting "fill" changes color of a line
+ // (by copying fillStyle to strokeStyle, since line is stroked, not filled)
+ const origStrokeStyle = ctx.strokeStyle;
+ ctx.strokeStyle = this.stroke || ctx.fillStyle;
+ this.stroke && this._renderStroke(ctx);
+ ctx.strokeStyle = origStrokeStyle;
+ }
+
+ /**
+ * This function is an helper for svg import. it returns the center of the object in the svg
+ * untransformed coordinates
+ * @private
+ * @return {Object} center point from element coordinates
+ */
+ _findCenterFromElement() {
+ return {
+ x: (this.x1 + this.x2) / 2,
+ y: (this.y1 + this.y2) / 2,
+ };
+ }
+
+ /**
+ * Returns object representation of an instance
+ * @method toObject
+ * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
+ * @return {Object} object representation of an instance
+ */
+ toObject(propertiesToInclude) {
+ return { ...super.toObject(propertiesToInclude), ...this.calcLinePoints() };
+ }
+
+ /*
+ * Calculate object dimensions from its properties
+ * @private
+ */
+ _getNonTransformedDimensions() {
+ const dim = super._getNonTransformedDimensions();
+ if (this.strokeLineCap === 'butt') {
+ if (this.width === 0) {
+ dim.y -= this.strokeWidth;
+ }
+ if (this.height === 0) {
+ dim.x -= this.strokeWidth;
+ }
+ }
+ return dim;
+ }
+
+ /**
+ * Recalculates line points given width and height
+ * @private
+ */
+ calcLinePoints() {
+ const xMult = this.x1 <= this.x2 ? -1 : 1,
+ yMult = this.y1 <= this.y2 ? -1 : 1,
+ x1 = xMult * this.width * 0.5,
+ y1 = yMult * this.height * 0.5,
+ x2 = xMult * this.width * -0.5,
+ y2 = yMult * this.height * -0.5;
+
+ return {
+ x1: x1,
+ x2: x2,
+ y1: y1,
+ y2: y2,
+ };
+ }
+
+ private makeEdgeToOriginGetter(propertyNames, originValues) {
+ const origin = propertyNames.origin,
+ axis1 = propertyNames.axis1,
+ axis2 = propertyNames.axis2,
+ dimension = propertyNames.dimension,
+ nearest = originValues.nearest,
+ center = originValues.center,
+ farthest = originValues.farthest;
+
+ switch (this.get(origin)) {
+ case nearest:
+ return Math.min(this.get(axis1), this.get(axis2));
+ case center:
+ return (
+ Math.min(this.get(axis1), this.get(axis2)) + 0.5 * this.get(dimension)
);
- },
+ case farthest:
+ return Math.max(this.get(axis1), this.get(axis2));
+ }
+ }
- /*
- * Calculate object dimensions from its properties
- * @private
- */
- _getNonTransformedDimensions: function () {
- var dim = this.callSuper('_getNonTransformedDimensions');
- if (this.strokeLineCap === 'butt') {
- if (this.width === 0) {
- dim.y -= this.strokeWidth;
- }
- if (this.height === 0) {
- dim.x -= this.strokeWidth;
- }
- }
- return dim;
+ /**
+ * @private
+ * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.
+ */
+ _getLeftToOriginX() {
+ return this.makeEdgeToOriginGetter(
+ {
+ // property names
+ origin: 'originX',
+ axis1: 'x1',
+ axis2: 'x2',
+ dimension: 'width',
},
+ {
+ // possible values of origin
+ nearest: 'left',
+ center: 'center',
+ farthest: 'right',
+ }
+ );
+ }
- /**
- * Recalculates line points given width and height
- * @private
- */
- calcLinePoints: function () {
- var xMult = this.x1 <= this.x2 ? -1 : 1,
- yMult = this.y1 <= this.y2 ? -1 : 1,
- x1 = xMult * this.width * 0.5,
- y1 = yMult * this.height * 0.5,
- x2 = xMult * this.width * -0.5,
- y2 = yMult * this.height * -0.5;
-
- return {
- x1: x1,
- x2: x2,
- y1: y1,
- y2: y2,
- };
+ /**
+ * @private
+ * @return {Number} leftToOriginX Distance from left edge of canvas to originX of Line.
+ */
+ _getTopToOriginY() {
+ return this.makeEdgeToOriginGetter(
+ {
+ // property names
+ origin: 'originY',
+ axis1: 'y1',
+ axis2: 'y2',
+ dimension: 'height',
},
+ {
+ // possible values of origin
+ nearest: 'top',
+ center: 'center',
+ farthest: 'bottom',
+ }
+ );
+ }
- /* _TO_SVG_START_ */
- /**
- * Returns svg representation of an instance
- * @return {Array} an array of strings with the specific svg representation
- * of the instance
- */
- _toSVG: function () {
- var p = this.calcLinePoints();
- return [
- '\n',
- ];
- },
- /* _TO_SVG_END_ */
- }
- );
+ /**
+ * Returns svg representation of an instance
+ * @return {Array} an array of strings with the specific svg representation
+ * of the instance
+ */
+ _toSVG() {
+ const p = this.calcLinePoints();
+ return [
+ '\n',
+ ];
+ }
/* _FROM_SVG_START_ */
+
/**
- * List of attribute names to account for when parsing SVG element (used by {@link fabric.Line.fromElement})
+ * List of attribute names to account for when parsing SVG element (used by {@link Line.fromElement})
* @static
- * @memberOf fabric.Line
+ * @memberOf Line
* @see http://www.w3.org/TR/SVG/shapes.html#LineElement
*/
- fabric.Line.ATTRIBUTE_NAMES = fabric.SHARED_ATTRIBUTES.concat(
- 'x1 y1 x2 y2'.split(' ')
- );
+ static ATTRIBUTE_NAMES = SHARED_ATTRIBUTES.concat('x1 y1 x2 y2'.split(' '));
/**
- * Returns fabric.Line instance from an SVG element
+ * Returns Line instance from an SVG element
* @static
- * @memberOf fabric.Line
+ * @memberOf Line
* @param {SVGElement} element Element to parse
* @param {Object} [options] Options object
* @param {Function} [callback] callback function invoked after parsing
*/
- fabric.Line.fromElement = function (element, callback, options) {
+ static fromElement(element, callback, options) {
options = options || {};
- var parsedAttributes = fabric.parseAttributes(
- element,
- fabric.Line.ATTRIBUTE_NAMES
- ),
+ const parsedAttributes = parseAttributes(element, Line.ATTRIBUTE_NAMES),
points = [
parsedAttributes.x1 || 0,
parsedAttributes.y1 || 0,
parsedAttributes.x2 || 0,
parsedAttributes.y2 || 0,
];
- callback(new fabric.Line(points, extend(parsedAttributes, options)));
- };
+ callback(new Line(points, { ...parsedAttributes, ...options }));
+ }
+
/* _FROM_SVG_END_ */
/**
- * Returns fabric.Line instance from an object representation
+ * Returns Line instance from an object representation
* @static
- * @memberOf fabric.Line
+ * @memberOf Line
* @param {Object} object Object to create an instance from
- * @returns {Promise}
+ * @returns {Promise}
*/
- fabric.Line.fromObject = function (object) {
- var options = clone(object, true);
+ static fromObject(object) {
+ const options = clone(object, true);
options.points = [object.x1, object.y1, object.x2, object.y2];
- return FabricObject._fromObject(fabric.Line, options, {
+ return FabricObject._fromObject(Line, options, {
extraParam: 'points',
}).then(function (fabricLine) {
delete fabricLine.points;
return fabricLine;
});
- };
-
- /**
- * Produces a function that calculates distance from canvas edge to Line origin.
- */
- function makeEdgeToOriginGetter(propertyNames, originValues) {
- var origin = propertyNames.origin,
- axis1 = propertyNames.axis1,
- axis2 = propertyNames.axis2,
- dimension = propertyNames.dimension,
- nearest = originValues.nearest,
- center = originValues.center,
- farthest = originValues.farthest;
-
- return function () {
- switch (this.get(origin)) {
- case nearest:
- return Math.min(this.get(axis1), this.get(axis2));
- case center:
- return (
- Math.min(this.get(axis1), this.get(axis2)) +
- 0.5 * this.get(dimension)
- );
- case farthest:
- return Math.max(this.get(axis1), this.get(axis2));
- }
- };
}
-})(typeof exports !== 'undefined' ? exports : window);
+}
+
+export const lineDefaultValues: Partial> = {
+ type: 'line',
+ x1: 0,
+ y1: 0,
+ x2: 0,
+ y2: 0,
+ cacheProperties: fabricObjectDefaultValues.cacheProperties.concat(
+ 'x1',
+ 'x2',
+ 'y1',
+ 'y2'
+ ),
+};
+
+Object.assign(Line.prototype, lineDefaultValues);
+/** @todo TODO_JS_MIGRATION remove next line after refactoring build */
+fabric.Line = Line;