Skip to content

Commit

Permalink
refactor: parseArrayTransform support standard format
Browse files Browse the repository at this point in the history
  • Loading branch information
Aarebecca committed Oct 8, 2024
1 parent 1196edd commit 3984117
Show file tree
Hide file tree
Showing 4 changed files with 231 additions and 32 deletions.
198 changes: 198 additions & 0 deletions __tests__/unit/css/parser/transform.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,204 @@ describe('Property Transform', () => {
expect(result[2].d[1].toString()).toBe('-100px');
});

it('parse empty transform array', () => {
expect(parseTransform([])).toStrictEqual([]);
});

it('parse scale transform array', () => {
const scale = parseTransform([
['scale', -2],
['scale', 3, -4],
['scaleX', 5],
['scaleY', -1],
['scaleZ', -3],
['scale3d', -2, 0, 7],
]);
expect(scale[0].t).toBe('scale');
expect(scale[0].d[0].value).toBe(-2);
expect(scale[0].d[1].value).toBe(-2); // default value sy is sx
expect(scale[1].t).toBe('scale');
expect(scale[1].d[0].value).toBe(3);
expect(scale[1].d[1].value).toBe(-4);
expect(scale[2].t).toBe('scaleX');
expect(scale[2].d[0].value).toBe(5);
expect(scale[3].t).toBe('scaleY');
expect(scale[3].d[0].value).toBe(-1);
expect(scale[4].t).toBe('scaleZ');
expect(scale[4].d[0].value).toBe(-3);
expect(scale[5].t).toBe('scale3d');
expect(scale[5].d[0].value).toBe(-2);
expect(scale[5].d[1].value).toBe(0);
expect(scale[5].d[2].value).toBe(7);

const scale3d = parseTransform([['scale3d', -2, 0, 7]]);

expect(scale3d[0].t).toBe('scale3d');
expect(scale3d[0].d[0].value).toBe(-2);
expect(scale3d[0].d[1].value).toBe(0);
expect(scale3d[0].d[2].value).toBe(7);
});

it('parse rotate transform array', () => {
const rotate = parseTransform([
['rotate', 10],
['rotate', 1],
['rotateX', 0],
['rotateY', 1.5],
['rotateZ', 50],
['rotate3d', 0, 0, 1, 0],
]);

expect(rotate[0].t).toBe('rotate');
expect(rotate[0].d[0].value).toBe(10);
expect(rotate[1].t).toBe('rotate');
expect(rotate[1].d[0].value).toBe(1);
expect(rotate[2].t).toBe('rotateX');
expect(rotate[2].d[0].value).toBe(0);
expect(rotate[3].t).toBe('rotateY');
expect(rotate[3].d[0].value).toBe(1.5);
expect(rotate[4].t).toBe('rotateZ');
expect(rotate[4].d[0].value).toBe(50);
expect(rotate[5].t).toBe('rotate3d');
expect(rotate[5].d[0].value).toBe(0);
expect(rotate[5].d[1].value).toBe(0);
expect(rotate[5].d[2].value).toBe(1);
expect(rotate[5].d[3].value).toBe(0);

const rotate3d = parseTransform([['rotate3d', 0, 0, 1, 0]]);
expect(rotate3d[0].t).toBe('rotate3d');
expect(rotate3d[0].d[0].value).toBe(0);
expect(rotate3d[0].d[1].value).toBe(0);
expect(rotate3d[0].d[2].value).toBe(1);
expect(rotate3d[0].d[3].value).toBe(0);
});

it('parse translate transform array', () => {
const translate = parseTransform([
['translate', 20, 30],
['translate', 10],
['translateX', 10],
['translateX', 20],
['translateX', 0],
['translateY', 10],
['translateY', 20],
['translateY', 0],
['translateZ', 10],
['translateZ', 0],
['translate3d', 10, 20, 30],
['translate3d', 0, 40, 0],
['translate3d', 50, 0, 60],
]);

expect(translate[0].t).toBe('translate');
expect(translate[0].d[0].value).toBe(20);
expect(translate[0].d[1].value).toBe(30);
expect(translate[1].t).toBe('translate');
expect(translate[1].d[0].value).toBe(10);
expect(translate[1].d[1].value).toBe(0); // default value is 0
expect(translate[2].t).toBe('translateX');
expect(translate[2].d[0].value).toBe(10);
expect(translate[3].t).toBe('translateX');
expect(translate[3].d[0].value).toBe(20);
expect(translate[4].t).toBe('translateX');
expect(translate[4].d[0].value).toBe(0);
expect(translate[5].t).toBe('translateY');
expect(translate[5].d[0].value).toBe(10);
expect(translate[6].t).toBe('translateY');
expect(translate[6].d[0].value).toBe(20);
expect(translate[7].t).toBe('translateY');
expect(translate[7].d[0].value).toBe(0);
expect(translate[8].t).toBe('translateZ');
expect(translate[8].d[0].value).toBe(10);
expect(translate[9].t).toBe('translateZ');
expect(translate[9].d[0].value).toBe(0);
expect(translate[10].t).toBe('translate3d');
expect(translate[10].d[0].value).toBe(10);
expect(translate[10].d[1].value).toBe(20);
expect(translate[10].d[2].value).toBe(30);
expect(translate[11].t).toBe('translate3d');
expect(translate[11].d[0].value).toBe(0);
expect(translate[11].d[1].value).toBe(40);
expect(translate[11].d[2].value).toBe(0);
expect(translate[12].t).toBe('translate3d');
expect(translate[12].d[0].value).toBe(50);
expect(translate[12].d[1].value).toBe(0);
expect(translate[12].d[2].value).toBe(60);
});

it('parse skew transform array', () => {
const skew = parseTransform([
['skew', 15],
['skew', 0],
['skew', -0.06, 18],
['skew', 0.312],
['skewX', 0.312],
['skewY', 0.312],
]);

expect(skew[0].t).toBe('skew');
expect(skew[0].d[0].value).toBe(15);
expect(skew[0].d[1].value).toBe(0); // default value is 0
expect(skew[1].t).toBe('skew');
expect(skew[1].d[0].value).toBe(0);
expect(skew[1].d[1].value).toBe(0);
expect(skew[2].t).toBe('skew');
expect(skew[2].d[0].value).toBe(-0.06);
expect(skew[2].d[1].value).toBe(18);
expect(skew[3].t).toBe('skew');
expect(skew[3].d[0].value).toBe(0.312);
expect(skew[3].d[1].value).toBe(0);
expect(skew[4].t).toBe('skewX');
expect(skew[4].d[0].value).toBe(0.312);
expect(skew[5].t).toBe('skewY');
expect(skew[5].d[0].value).toBe(0.312);
});

it('parse matrix transform array', () => {
// prettier-ignore
const matrix = parseTransform([
[
'matrix',
1, 2,
-1, 1,
80, 80
],
[
'matrix3d',
1, 2, -1, 1,
80, 80, 0, 0,
0, 0, 0, 0,
-50, -100, 0, 1.1,
],
]);

expect(matrix[0].t).toBe('matrix');
expect(matrix[0].d[0].value).toBe(1);
expect(matrix[0].d[1].value).toBe(2);
expect(matrix[0].d[2].value).toBe(-1);
expect(matrix[0].d[3].value).toBe(1);
expect(matrix[0].d[4].value).toBe(80);
expect(matrix[0].d[5].value).toBe(80);

expect(matrix[1].t).toBe('matrix3d');
expect(matrix[1].d[0].value).toBe(1);
expect(matrix[1].d[1].value).toBe(2);
expect(matrix[1].d[2].value).toBe(-1);
expect(matrix[1].d[3].value).toBe(1);
expect(matrix[1].d[4].value).toBe(80);
expect(matrix[1].d[5].value).toBe(80);
expect(matrix[1].d[6].value).toBe(0);
expect(matrix[1].d[7].value).toBe(0);
expect(matrix[1].d[8].value).toBe(0);
expect(matrix[1].d[9].value).toBe(0);
expect(matrix[1].d[10].value).toBe(0);
expect(matrix[1].d[11].value).toBe(0);
expect(matrix[1].d[12].value).toBe(-50);
expect(matrix[1].d[13].value).toBe(-100);
expect(matrix[1].d[14].value).toBe(0);
expect(matrix[1].d[15].value).toBe(1.1);
});

it('should parse matrix correctly.', () => {
let result = parseTransform('matrix(1, 2, -1, 1, 80, 80)');
expect(result).toStrictEqual([
Expand Down
5 changes: 2 additions & 3 deletions packages/g-lite/src/css/cssom/CSSNumericValue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ export class CSSUnitValue extends CSSStyleValue {
case UnitType.kSeconds:
// case UnitType.kHertz:
// case UnitType.kKilohertz:
case UnitType.kTurns: // case UnitType.kContainerMax: { // case UnitType.kContainerMin: // case UnitType.kContainerBlockSize: // case UnitType.kContainerInlineSize: // case UnitType.kContainerHeight: // case UnitType.kContainerWidth: // case UnitType.kDynamicViewportMax: // case UnitType.kDynamicViewportMin: // case UnitType.kDynamicViewportBlockSize: // case UnitType.kDynamicViewportInlineSize: // case UnitType.kDynamicViewportHeight: // case UnitType.kDynamicViewportWidth: // case UnitType.kLargeViewportMax: // case UnitType.kLargeViewportMin: // case UnitType.kLargeViewportBlockSize: // case UnitType.kLargeViewportInlineSize: // case UnitType.kLargeViewportHeight: // case UnitType.kLargeViewportWidth: // case UnitType.kSmallViewportMax: // case UnitType.kSmallViewportMin: // case UnitType.kSmallViewportBlockSize: // case UnitType.kSmallViewportInlineSize: // case UnitType.kSmallViewportHeight: // case UnitType.kSmallViewportWidth: // case UnitType.kViewportMax: // case UnitType.kViewportMin: // case UnitType.kViewportBlockSize: // case UnitType.kViewportInlineSize: // case UnitType.kViewportHeight: // case UnitType.kViewportWidth: // case UnitType.kFraction:
{
// case UnitType.kContainerMax: { // case UnitType.kContainerMin: // case UnitType.kContainerBlockSize: // case UnitType.kContainerInlineSize: // case UnitType.kContainerHeight: // case UnitType.kContainerWidth: // case UnitType.kDynamicViewportMax: // case UnitType.kDynamicViewportMin: // case UnitType.kDynamicViewportBlockSize: // case UnitType.kDynamicViewportInlineSize: // case UnitType.kDynamicViewportHeight: // case UnitType.kDynamicViewportWidth: // case UnitType.kLargeViewportMax: // case UnitType.kLargeViewportMin: // case UnitType.kLargeViewportBlockSize: // case UnitType.kLargeViewportInlineSize: // case UnitType.kLargeViewportHeight: // case UnitType.kLargeViewportWidth: // case UnitType.kSmallViewportMax: // case UnitType.kSmallViewportMin: // case UnitType.kSmallViewportBlockSize: // case UnitType.kSmallViewportInlineSize: // case UnitType.kSmallViewportHeight: // case UnitType.kSmallViewportWidth: // case UnitType.kViewportMax: // case UnitType.kViewportMin: // case UnitType.kViewportBlockSize: // case UnitType.kViewportInlineSize: // case UnitType.kViewportHeight: // case UnitType.kViewportWidth: // case UnitType.kFraction:
case UnitType.kTurns: {
const kMinInteger = -999999;
const kMaxInteger = 999999;

Expand All @@ -180,5 +180,4 @@ export class CSSUnitValue extends CSSStyleValue {
}

export const Opx: CSSUnitValue = new CSSUnitValue(0, 'px');
export const Lpx: CSSUnitValue = new CSSUnitValue(1, 'px');
export const Odeg: CSSUnitValue = new CSSUnitValue(0, 'deg');
13 changes: 9 additions & 4 deletions packages/g-lite/src/css/parser/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,16 @@ function parseArrayTransform(transform: TransformArray): ParsedTransform[] {
for (let i = 0; i < length; i++) {
const item = transform[i];
const name = item[0];
const args = item.slice(1);
const functionData = transformFunctions[name];
if (!functionData) {
return [];
const args = item.slice(1) as number[];
// infer default value
if (name === 'translate' || name === 'skew') {
if (args.length === 1) args.push(0);
} else if (name === 'scale') {
if (args.length === 1) args.push(args[0]);
}

const functionData = transformFunctions[name];
if (!functionData) return [];
const parsedArgs = args.map((value) => getOrCreateUnitValue(value));
result.push({ t: name, d: parsedArgs });
}
Expand Down
47 changes: 22 additions & 25 deletions packages/g-lite/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,48 +38,40 @@ export interface EventPosition {
y: number;
}

export type TransformScale = ['scale', number, number];
export type TransformScale = ['scale', number, number?];
export type TransformScaleX = ['scaleX', number];
export type TransformScaleY = ['scaleY', number];
export type TransformScaleZ = ['scaleZ', number];
export type TransformScale3d = ['scale3d', number, number, number];
export type TransformTranslate = ['translate', number, number];
export type TransformTranslate = ['translate', number, number?];
export type TransformTranslateX = ['translateX', number];
export type TransformTranslateY = ['translateY', number];
export type TransformTranslateZ = ['translateZ', number];
export type TransformTranslate3d = ['translate3d', number, number, number];
export type TransformRotate = ['rotate', number];
export type TransformSkew = ['skew', number, number];
export type TransformRotateX = ['rotateX', number];
export type TransformRotateY = ['rotateY', number];
export type TransformRotateZ = ['rotateZ', number];
export type TransformRotate3d = ['rotate3d', number, number, number, number?];
export type TransformSkew = ['skew', number, number?];
export type TransformSkewX = ['skewX', number];
export type TransformSkewY = ['skewY', number];
// prettier-ignore
export type TransformMatrix = [
'matrix',
number,
number,
number,
number,
number,
number,
number, number, // a, b
number, number, // c, d
number, number, // tx, ty
];
// prettier-ignore
export type TransformMatrix3d = [
'matrix3d',
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number,
number, number, number, number,
number, number, number, number,
number, number, number, number,
number, number, number, number,
];

export type TransformArray = (
| TransformScale
| TransformScaleX
Expand All @@ -92,10 +84,15 @@ export type TransformArray = (
| TransformTranslateZ
| TransformTranslate3d
| TransformRotate
| TransformRotateX
| TransformRotateY
| TransformRotateZ
| TransformRotate3d
| TransformSkew
| TransformSkewX
| TransformSkewY
| TransformMatrix
| TransformMatrix3d
)[];
export type TextTransform = 'capitalize' | 'uppercase' | 'lowercase' | 'none';
export type TextOverflow = 'clip' | 'ellipsis' | string;
Expand Down

0 comments on commit 3984117

Please sign in to comment.