- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
上下文:@AnaTudor (@daredevil) is talking about使用 skewX
或 skewY
时 SVG 的 d
移动距离,所以我想知道是否有任何方法可以按顺序计算该距离补偿翻译,并避免使用链式 translate
。
测试用例:在下面的代码片段中,我们不会使用特定于 SVG 的链接和/或嵌套,我们仅使用相同的变换值,但按照变换函数的特定顺序;
style
:translate
、rotate
、skewX
、 skewY
, scale
; transform
属性:translate
、scale
、rotate
, skewX
, `skewY.现在,如您所见,两个矩形的位置不同,如果您单击按钮,第二个矩形会更接近我们的预期,但仍需要针对所有情况进行更多计算。
问题:我们如何更改 fixOrigin
函数来调整所有可能的变换函数组合的翻译,以一种看起来与 CSS3 变换相同的方式?
var el1 = document.querySelectorAll('path')[0],
el2 = document.querySelectorAll('path')[1],
el2BB = el2.getBBox(), el2cx = el2BB.x + el2BB.width/2, el2cy = el2BB.y + el2BB.height/2,
btn = document.querySelectorAll('button')[0], btn1 = document.querySelectorAll('button')[1],
x = 20, y = 20, scale = 0.6, rotate = 45, skewX = 20, skewY = -20;
el1.style.transform = 'translate(20px, 20px) rotate(45deg) skewX(20deg) skewY(-20deg) scale(0.6)';
el1.style.transformOrigin = '50% 50% 0px';
el2.setAttribute('transform', 'translate('+x+','+y+') scale('+scale+') rotate('+rotate+' '+el2cx+','+el2cy+') skewX('+skewX+') skewY('+skewY+')');
function fixOrigin(){
x += (1-scale) * el2BB.width/2;
y += (1-scale) * el2BB.height/2;
el2.setAttribute('transform', 'translate('+x+','+y+') scale('+scale+') rotate('+rotate+' '+el2cx+','+el2cy+') skewX('+skewX+') skewY('+skewY+')');
}
btn.addEventListener('click',fixOrigin,false);
function fixEverything() {
// scale binds all transform functions together
if ( !!scale ) {
//most important make sure we have translation values
//!!(x) && (x=0); !!(y) && (y=0);
// first adjust translate based on scale value
x += (1-scale) * el2BB.width/2;
y += (1-scale) * el2BB.height/2;
//now we also adjust the rotation transform origin based on SKEWS
if (!!rotate) {
// el2cx += .... el2cy += ...
}
//almost there, now we adjust the translation based on SKEWS
// x += ... y += ...
// last case, when SKEWS are used alone
} else if ( !scale && !rotate ) {
// adjust translation here
// x += ... y += ...
}
el2.setAttribute('transform', 'translate(' + x + ',' + y + ') scale(' + scale + ') rotate(' + rotate + ' ' + el2cx + ',' + el2cy + ') skewX(' + skewX + ') skewY(' + skewY + ')');
}
btn1.addEventListener('click', fixEverything, false);
/* desired transform
transform-origin: 50% 50% 0px;
transform: translate(20px, 20px) rotate(45deg) skewX(20deg) skewY(-20deg) scale(0.6);
*/
svg {
overflow: visible; width:30%;
border: 1px solid #eee; /* some sort of ruler */
}
<button>Fix Transform Origin</button><button>Fix All</button><br>
<p>Click to change the `transform` attribute</p>
<svg id="svgMixedCSS" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 500">
<path fill="green" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z" ></path>
</svg>
<svg id="svgMixedAttr" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 600 500">
<path fill="indigo" d="M426.671 0h-341.328c-46.937 0-85.343 38.405-85.343 85.345v341.311c0 46.969 38.406 85.344 85.343 85.344h341.328c46.938 0 85.329-38.375 85.329-85.345v-341.31c0-46.94-38.391-85.345-85.329-85.345z"></path>
</svg>
我制作了一个超酷的片段供您玩玩。更新:它还有一个包含所有可能情况的功能草案。
最佳答案
由于您目前的核心问题似乎是如何计算 d
距离。它来自一个谈话,其中对于 skewX
的情况,倾斜操作基本上被描述为 (x, y) ↦ (x + d, y) .如果你看the SVG spec你会发现一个矩阵,它基本上说明了 skewX(a)
的确切公式是(x, y) ↦ (x + cos(a) y, y)
.同样对于 skewY(a)
你有(x, y) ↦ (x, y + cos(a) x)
.所以我会说 d := cos(a) * y
在第一种情况下和 d := cos(a) * x
在第二种情况下。
不过,问题标题向我提出了一个不同的问题。该问题可以表述如下:给定 transform="skewX(c) translate(a, b)"
对于一些数字 a
, b
和 c
, 找到 d
和 e
这样我刚才给出的转换与 translate(d, e) skewX(c)
相同.或者换句话说:我必须如何更改 transform
的条目?如果我想将转换移动到 skewX
的外部.
要找到这些数字,请查看相应的矩阵乘积,如defined in the spec :
⎡1 tan(c) 0⎤ ⎡1 0 a⎤ ⎡1 tan(c) a + tan(c) b⎤ ⎡1 0 a + tan(c) b⎤ ⎡1 tan(c) 0⎤
⎢0 1 0⎥∙⎢0 1 b⎥ = ⎢0 1 b ⎥ = ⎢0 1 b ⎥∙⎢0 1 0⎥
⎣0 0 1⎦ ⎣0 0 1⎦ ⎣0 0 1 ⎦ ⎣0 0 1 ⎦ ⎣0 0 1⎦
所以你会得到 d = a + tan(c) * b
和 e = b
.您只需将倾斜变换应用于平移向量。换句话说:
skewX(c) translate(a, b) = translate(a + tan(c) * b, b) skewX(c)
您可以对 y
进行类似的计算并获得:
skewY(c) translate(a, b) = translate(a, b + tan(c) * a) skewY(c)
如果你同时拥有 skewX
和 skewY
合并后,您可以移动 translate
一次走出一步,这样在每一步你只需要处理一个倾斜方向。如果你想要相反的方向(即移动 translate
更接近倾斜的内部),使用 - tan(c)
而不是 + tan(c)
在这些公式中。
关于javascript - 在 SVG 上使用 skewX 和 skewY 时如何补偿平移,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39191054/
这个问题在这里已经有了答案: CSS Transform Skew [duplicate] (8 个答案) How to transform each side of a shape separat
请不要使用 jQuery 和 SCCS(即使我在这里使用 UIkit3 进行样式设置)。导航栏有一个倾斜的背景图像,这是通过 CSS 中的线性渐变和固定高度完成的。我的方法是使用 transform:
在为 skewY() 属性设置动画时,该问题很明显。看起来元素的宽度缩小了一点,不再接触到同样宽度的容器的边。 使用 skewX() 设置动画时不会发生同样的情况 - 高度按预期设置动画。 我只在桌面
考虑到可能存在仅使用旋转或仅使用 skewX 等的多种场景,我如何才能找到元素上当前的旋转、skewX 和 skewY 变换设置。 到目前为止,我很好地返回了旋转 Angular : getAngle
这个问题在这里已经有了答案: one sided skew with css (2 个答案) 关闭 5 年前。
我试图在 HTML 中组合两张图片,但在 CSS 中使用 skewY 后我看到了空白点。我如何制作底部图像和白点以将其组合以适合设计 View ? 下面是 HTML。我将图片 1 添加到 中和图像
谁能解释一下这是怎么回事 site在调整大小时实现 skeyY 变换对象的完美缩放? 我可以使用下面的代码实现静态效果,但我无法让它在调整大小时保持完美的垂直对齐。我尝试使用媒体查询,但结果 Not
在我的网站上为某些对象创建一些转换时,我发现了以下内容。如果一个对象被赋予转换属性 skew(20deg,45deg) 将不同于另一个具有 的对象skewX(20deg) 和 skewY(45deg)
上下文:@AnaTudor (@daredevil) is talking about使用 skewX 或 skewY 时 SVG 的 d 移动距离,所以我想知道是否有任何方法可以按顺序计算该距离补偿
我是一名优秀的程序员,十分优秀!