From c042a3fd201e795c8f80accc6c4685efcaa9c9fe Mon Sep 17 00:00:00 2001 From: pissang Date: Fri, 14 May 2021 14:12:35 +0800 Subject: [PATCH 1/2] fix skew with origin. add test --- src/core/Transformable.ts | 34 ++++---- test/origin.html | 161 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+), 15 deletions(-) create mode 100644 test/origin.html diff --git a/src/core/Transformable.ts b/src/core/Transformable.ts index 5e253a982..3fd74016a 100644 --- a/src/core/Transformable.ts +++ b/src/core/Transformable.ts @@ -292,25 +292,29 @@ class Transformable { const rotation = target.rotation || 0; const x = target.x; const y = target.y; - const skewX = target.skewX || 0; - const skewY = target.skewY || 0; - - // Also did identity in these operations. + const skewX = target.skewX ? Math.tan(target.skewX) : 0; + // TODO: zrender use different hand in coordinate system and y axis is inversed. + const skewY = target.skewY ? Math.tan(-target.skewY) : 0; - // Apply origin - m[4] = -ox * sx; - m[5] = -oy * sy; - // Apply scale + // The order of transform (-origin * scale * skew * rotate * origin * translate). + // We merge (-origin * scale * skew) into one. Also did identity in these operations. + // origin + if (ox || oy) { + m[4] = -ox * sx - skewX * oy * sy; + m[5] = -oy * sy - skewY * ox * sx; + } + else { + m[4] = m[5] = 0; + } + // scale m[0] = sx; m[3] = sy; - // Apply skew - // TODO: zrender use different hand in coordinate system and y axis is inversed. - m[1] = skewY ? Math.tan(-skewY) * sx : 0; - m[2] = skewX ? Math.tan(skewX) * sy : 0; + // skew + m[1] = skewY * sx; + m[2] = skewX * sy; + // Apply rotation - if (rotation) { - matrix.rotate(m, m, rotation); - } + rotation && matrix.rotate(m, m, rotation); // Translate back from origin and apply translation m[4] += ox + x; diff --git a/test/origin.html b/test/origin.html new file mode 100644 index 000000000..591a897ac --- /dev/null +++ b/test/origin.html @@ -0,0 +1,161 @@ + + + + + Transform Origin Test + + + + + + +
+
+ Dashed box: without transform. Gray box with transform. Red box: CSS transform as baseline. + + + + \ No newline at end of file From b41f39bd98f929fee3227f55a5882ab5a2b3ebcc Mon Sep 17 00:00:00 2001 From: pissang Date: Fri, 14 May 2021 14:14:24 +0800 Subject: [PATCH 2/2] test(transform): optimize css baseline in origin test --- test/origin.html | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/origin.html b/test/origin.html index 591a897ac..b36681e08 100644 --- a/test/origin.html +++ b/test/origin.html @@ -19,6 +19,7 @@ #css-baseline-container>div { position: absolute; border: 2px solid red; + box-sizing: border-box; } #description { position: absolute; @@ -138,11 +139,9 @@ baselineContainer.appendChild(baselineBox); // rotation and skewY in zrender has different direction with CSS transform. baselineBox.style.cssText = ` -left: ${offsetX + cellSize * column}px; -top: ${offsetY + row * cellSize}px; width: ${elSize}px; height: ${elSize}px; -transform: rotate(${-rot}deg) skew(${skew[0]}deg, ${-skew[1]}deg) scale(${scale[0]}, ${scale[1]}); +transform: translate(${offsetX + cellSize * column}px, ${offsetY + row * cellSize}px) rotate(${-rot}deg) skew(${skew[0]}deg, ${-skew[1]}deg) scale(${scale[0]}, ${scale[1]}); transform-origin: ${origin[0] * 100}% ${origin[1] * 100}%; `