Skip to content

Commit

Permalink
Create a utility to build animation properties (#222)
Browse files Browse the repository at this point in the history
  • Loading branch information
elchininet authored Jan 1, 2025
1 parent 0cd0515 commit d816d8b
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 142 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [3.11.1] - 2025-01-01

- Created a utility to build animation properties and refactored the classes to make use of this utility to avoid code repetition

## [3.11.0] - 2024-12-22

- Added a new option to set a CSS class to `IsometricCircle`, `IsometricPath`, `IsometricPentagram`, `IsometricRectangle`, `IsometricStarPolygon` and `IsometricText`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
addSVGProperties,
getSVGProperty,
getPatternTransform,
isSVGProperty
isSVGProperty,
getAnimationProperties
} from '@utils/svg';
import { uuid, round, getPointFromIsometricPoint } from '@utils/math';
import { IsometricElementAbstract } from '../IsometricElementAbstract';
Expand Down Expand Up @@ -162,23 +163,15 @@ export abstract class IsometricGraphicAbstract extends IsometricElementAbstract

this.addAnimationBasicProperties(property, animation);

if (animation.values) {
addSVGProperties(
animation.element,
{
values: Array.isArray(animation.values)
? animation.values.map((value: string | number): string => `${value}`).join(';')
: `${animation.values}`
}
);
} else {
addSVGProperties(
animation.element, {
from: `${animation.from}`,
to: `${animation.to}`
}
);
}
const properties = getAnimationProperties(
(value: string | number) => `${value}`,
animation
);

addSVGProperties(
animation.element,
properties
);

}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,15 @@ import {
IsometricPoint,
LinePoint,
CommandPoint,
SVGPositionableProperties,
SVGPentagramProperties,
SVGPentagramAnimation,
SVGAnimationObject
} from '@types';
import {
getSVGPath,
translateCommandPoints,
addSVGProperties,
isSVGProperty
isSVGProperty,
getAnimationProperties
} from '@utils/svg';
import { IsometricShapeAbstract } from '@classes/abstract/IsometricShapeAbstract';
import {
Expand Down Expand Up @@ -175,7 +174,7 @@ export abstract class IsometricStarPolygonAbstract extends IsometricShapeAbstrac

if (!isNativeSVGProperty) {

const props = {
const props: GetStarPolygonAbstractPathArguments = {
right: this.right,
left: this.left,
top: this.top,
Expand All @@ -187,37 +186,11 @@ export abstract class IsometricStarPolygonAbstract extends IsometricShapeAbstrac

if (Object.prototype.hasOwnProperty.call(props, animation.property)) {

const property = animation.property as SVGPositionableProperties | SVGPentagramProperties;
let properties: Record<string, string>;

if (animation.values) {

if (Array.isArray(animation.values)) {
properties = {
values: animation.values.map((value: string | number): string => {
const modifiedArgs = { ...props };
modifiedArgs[property] = +value;
return this.getPentagramPath(modifiedArgs);
}).join(';')
};
} else {
const modifiedArgs = { ...props };
modifiedArgs[property] = +animation.values;
properties = {
values: this.getPentagramPath(modifiedArgs)
};
}

} else {
const fromArgs = { ...props };
const toArgs = { ...props };
fromArgs[property] = +animation.from;
toArgs[property] = +animation.to;
properties = {
from: this.getPentagramPath(fromArgs),
to: this.getPentagramPath(toArgs)
};
}
const properties: Record<string, string> = getAnimationProperties(
this.getPentagramPath.bind(this),
animation,
props
);

if (!animation.element) {
animation.element = document.createElementNS(SVG_NAMESPACE, SVG_ELEMENTS.animate) as SVGAnimateElement;
Expand Down
43 changes: 8 additions & 35 deletions src/@classes/public/IsometricCircle/IsometricCircle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import {
import {
CommandPoint,
SVGCircleAnimation,
SVGPositionableProperties,
SVGCircleProperties,
SVGAnimationObject
} from '@types';
import {
getSVGPath,
translateCommandPoints,
addSVGProperties,
isSVGProperty
isSVGProperty,
getAnimationProperties
} from '@utils/svg';
import { IsometricShapeAbstract } from '@classes/abstract/IsometricShapeAbstract';
import {
Expand Down Expand Up @@ -121,7 +120,7 @@ export class IsometricCircle extends IsometricShapeAbstract {

if (!isNativeSVGProperty) {

const props = {
const props: GetCirclePathArguments = {
right: this.right,
left: this.left,
top: this.top,
Expand All @@ -130,37 +129,11 @@ export class IsometricCircle extends IsometricShapeAbstract {

if (Object.prototype.hasOwnProperty.call(props, animation.property)) {

const property = animation.property as SVGPositionableProperties | SVGCircleProperties;
let properties: Record<string, string>;

if (animation.values) {

if (Array.isArray(animation.values)) {
properties = {
values: animation.values.map((value: string | number): string => {
const modifiedArgs = { ...props };
modifiedArgs[property] = +value;
return this.getCirclePath(modifiedArgs);
}).join(';')
};
} else {
const modifiedArgs = { ...props };
modifiedArgs[property] = +animation.values;
properties = {
values: this.getCirclePath(modifiedArgs)
};
}

} else {
const fromArgs = { ...props };
const toArgs = { ...props };
fromArgs[property] = +animation.from;
toArgs[property] = +animation.to;
properties = {
from: this.getCirclePath(fromArgs),
to: this.getCirclePath(toArgs)
};
}
const properties: Record<string, string> = getAnimationProperties(
this.getCirclePath.bind(this),
animation,
props
);

if (!animation.element) {
animation.element = document.createElementNS(SVG_NAMESPACE, SVG_ELEMENTS.animate) as SVGAnimateElement;
Expand Down
27 changes: 8 additions & 19 deletions src/@classes/public/IsometricPath/IsometricPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import {
import {
addSVGProperties,
parseDrawCommands,
getSVGPath
getSVGPath,
getAnimationProperties
} from '@utils/svg';
import { IsometricPathAbstract } from '@classes/abstract/IsometricPathAbstract';
import { IsometricPathProps } from './types';
Expand All @@ -31,8 +32,8 @@ export class IsometricPath extends IsometricPathAbstract {
private commands: CommandPoint[];
private _autoclose: boolean;

private getPathFromCommands = (commands: string): string => getSVGPath(
parseDrawCommands(commands),
private getPathFromCommands = (commands: string | number): string => getSVGPath(
parseDrawCommands(`${commands}`),
this.data.centerX,
this.data.centerY,
this.data.scale,
Expand All @@ -45,22 +46,10 @@ export class IsometricPath extends IsometricPathAbstract {

if (animation.property === 'path') {

let properties: Record<string, string>;

if (animation.values) {
properties = {
values: Array.isArray(animation.values)
? animation.values.map((value: string | number): string => {
return this.getPathFromCommands(`${value}`);
}).join(';')
: this.getPathFromCommands(`${animation.values}`)
};
} else {
properties = {
from: this.getPathFromCommands(`${animation.from}`),
to: this.getPathFromCommands(`${animation.to}`)
};
}
const properties: Record<string, string> = getAnimationProperties(
this.getPathFromCommands.bind(this),
animation
);

if (!animation.element) {
animation.element = document.createElementNS(SVG_NAMESPACE, SVG_ELEMENTS.animate) as SVGAnimateElement;
Expand Down
43 changes: 8 additions & 35 deletions src/@classes/public/IsometricRectangle/IsometricRectangle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,15 @@ import {
import {
LinePoint,
CommandPoint,
SVGPositionableProperties,
SVGRectangleProperties,
SVGRectangleAnimation,
SVGAnimationObject
} from '@types';
import {
getSVGPath,
translateCommandPoints,
addSVGProperties,
isSVGProperty
isSVGProperty,
getAnimationProperties
} from '@utils/svg';
import { IsometricShapeAbstract } from '@classes/abstract/IsometricShapeAbstract';
import {
Expand Down Expand Up @@ -92,7 +91,7 @@ export class IsometricRectangle extends IsometricShapeAbstract {

if (!isNativeSVGProperty) {

const props = {
const props: GetRectanglePathArguments = {
right: this.right,
left: this.left,
top: this.top,
Expand All @@ -102,37 +101,11 @@ export class IsometricRectangle extends IsometricShapeAbstract {

if (Object.prototype.hasOwnProperty.call(props, animation.property)) {

const property = animation.property as SVGPositionableProperties | SVGRectangleProperties;
let properties: Record<string, string>;

if (animation.values) {

if (Array.isArray(animation.values)) {
properties = {
values: animation.values.map((value: string | number): string => {
const modifiedArgs = { ...props };
modifiedArgs[property] = +value;
return this.getRectanglePath(modifiedArgs);
}).join(';')
};
} else {
const modifiedArgs = { ...props };
modifiedArgs[property] = +animation.values;
properties = {
values: this.getRectanglePath(modifiedArgs)
};
}

} else {
const fromArgs = { ...props };
const toArgs = { ...props };
fromArgs[property] = +animation.from;
toArgs[property] = +animation.to;
properties = {
from: this.getRectanglePath(fromArgs),
to: this.getRectanglePath(toArgs)
};
}
const properties: Record<string, string> = getAnimationProperties(
this.getRectanglePath.bind(this),
animation,
props,
);

if (!animation.element) {
animation.element = document.createElementNS(SVG_NAMESPACE, SVG_ELEMENTS.animate) as SVGAnimateElement;
Expand Down
42 changes: 42 additions & 0 deletions src/@utils/svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
SVGProperties,
SVGNativeProperties,
SVGProps,
SVGAnimationObject,
AddEventListenerCallback
} from '@types';
import {
Expand Down Expand Up @@ -239,4 +240,45 @@ export const elementHasSVGParent = (element: Node): boolean => {
return elementHasSVGParent(element.parentNode);
}
return false;
};

export const getAnimationProperties = <P>(
getPath: (...args: unknown[]) => string,
animation: SVGAnimationObject,
props?: P
): Record<string, string> => {

let properties: Record<string, string>;

const localGetPath = (value: string | number): string => {
if (props) {
return getPath({
...props,
[animation.property]: +value
});
}
return getPath(value);
};

if (animation.values) {
if (Array.isArray(animation.values)) {
properties = {
values: animation.values.map((value: string | number): string => {
return localGetPath(value);
}).join(';')
};
} else {
properties = {
values: localGetPath(animation.values)
};
}
} else {
properties = {
from: localGetPath(animation.from),
to: localGetPath(animation.to)
};
}

return properties;

};

0 comments on commit d816d8b

Please sign in to comment.