提供 x、y、宽度和高度值,如何获得从中心缩放的 svg 变换矩阵
Providing the x,y,width and height value, how do I get the svg transform matrix that scales from center
我有一个代码可以使用 php 和 imagemagick 从 svg 生成 gif 文件。
下面是示例 svg 代码。
假设要通过将缩放变换缩放值从 0 补间到 1 来创建动画,我如何使用 svg 元素属性 x、y、宽度、高度获取将变换原点居中的变换矩阵?
注意:我使用 php 进行所有计算,并使用我认为不支持 css transform-origin 样式的 Imagemagick 转换为光栅。
目前,过渡从左侧开始。我想用矩阵翻译它。
下面的link是当前实现的示例gif
https://i.imgur.com/juMX3uD.gifv
转换后的 SVG
<svg xmlns="http://www.w3.org/2000/svg" class="layer" overflow="visible"
stroke="none" stroke-width="0" preserveAspectRatio="none"
id="layer_1547759965149_0506449632092969" width="135.24545454545"
height="110.9375" x="86.896363636365" y="84.286250000001"><g
id="translateLayer" transform="matrix(1 0 0 1 0 0)"><g id="effectLayer"
transform="rotate(44.596407613288 67.622727272727 55.46875)"
fill="#FF4400"><svg viewBox="0 0 657.01 569" width="100%" height="100%"
preserveAspectRatio="none" overflow="hidden"><g id="Layer_2" data-
name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><polygon points="0 569
328.49 0 657.01 569 0 569"/></g></g></svg></g></g></svg>
转变发生在这里
<g id="translateLayer" transform="matrix(1 0 0 1 0 0)"></g>
如果我理解正确的话,您只是想通过设置 viewBox
来应用特定的变换而不更改 SVG 的用户坐标系,这样可以更容易。
原点是三角形的中心点。在这种情况下,这是图像的一半 width
和 2/3 height
。
那么,为什么不直接应用后续变换,而不是费力地进行矩阵计算呢? rotation
函数甚至采用原点参数。
var
svg = document.getElementById('layer_1547759965149_0506449632092969'),
sca = svg.getElementById('translateLayer'),
rot = svg.getElementById('effectLayer'),
deg = 0,
cx = svg.getAttribute('width') / 2,
cy = svg.getAttribute('height') * 2/3
;
function rotate()
{
deg++;
let scale = 1 + Math.sin(deg/180*Math.PI);
rot.setAttribute('transform', (()=>`rotate(${deg} ${cx} ${cy})`)());
sca.setAttribute('transform', (()=>`translate(${cx} ${cy}) scale(${scale} ${scale}) translate(-${cx} -${cy})`)());
}
setInterval(rotate, 50);
<svg xmlns="http://www.w3.org/2000/svg" class="layer" id="layer_1547759965149_0506449632092969"
overflow="visible"
stroke="none" stroke-width="0" preserveAspectRatio="none"
width="135.24545454545" height="110.9375"
x="86.896363636365" y="84.286250000001">
<!--<g id="translateLayer" transform="matrix(0 67.622727272725 0 0 73.95833333333333 0)">-->
<g id="translateLayer" transform="matrix(2 0 0 2 0.5 0.5)" transform-origin(200,100)>
<g id="effectLayer"
fill="#FF4400">
<svg viewBox="0 0 657.01 569" width="100%" height="100%"
preserveAspectRatio="none" overflow="hidden">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<polygon points="0 569 328.49 0 657.01 569 0 569"/>
</g>
</g>
</svg>
</g>
</g>
</svg>
经过几个小时的代码斗争,我得到了我正在寻找的修复。
下面是我实现的最终矩阵计算
x = (x/2);
y = (y/2);
matrix(scaleX 0 0 scaleY (x-scaleX*x) (y-scaleY*y));
我有一个代码可以使用 php 和 imagemagick 从 svg 生成 gif 文件。 下面是示例 svg 代码。 假设要通过将缩放变换缩放值从 0 补间到 1 来创建动画,我如何使用 svg 元素属性 x、y、宽度、高度获取将变换原点居中的变换矩阵?
注意:我使用 php 进行所有计算,并使用我认为不支持 css transform-origin 样式的 Imagemagick 转换为光栅。
目前,过渡从左侧开始。我想用矩阵翻译它。
下面的link是当前实现的示例gif https://i.imgur.com/juMX3uD.gifv
转换后的 SVG
<svg xmlns="http://www.w3.org/2000/svg" class="layer" overflow="visible"
stroke="none" stroke-width="0" preserveAspectRatio="none"
id="layer_1547759965149_0506449632092969" width="135.24545454545"
height="110.9375" x="86.896363636365" y="84.286250000001"><g
id="translateLayer" transform="matrix(1 0 0 1 0 0)"><g id="effectLayer"
transform="rotate(44.596407613288 67.622727272727 55.46875)"
fill="#FF4400"><svg viewBox="0 0 657.01 569" width="100%" height="100%"
preserveAspectRatio="none" overflow="hidden"><g id="Layer_2" data-
name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><polygon points="0 569
328.49 0 657.01 569 0 569"/></g></g></svg></g></g></svg>
转变发生在这里
<g id="translateLayer" transform="matrix(1 0 0 1 0 0)"></g>
如果我理解正确的话,您只是想通过设置 viewBox
来应用特定的变换而不更改 SVG 的用户坐标系,这样可以更容易。
原点是三角形的中心点。在这种情况下,这是图像的一半 width
和 2/3 height
。
那么,为什么不直接应用后续变换,而不是费力地进行矩阵计算呢? rotation
函数甚至采用原点参数。
var
svg = document.getElementById('layer_1547759965149_0506449632092969'),
sca = svg.getElementById('translateLayer'),
rot = svg.getElementById('effectLayer'),
deg = 0,
cx = svg.getAttribute('width') / 2,
cy = svg.getAttribute('height') * 2/3
;
function rotate()
{
deg++;
let scale = 1 + Math.sin(deg/180*Math.PI);
rot.setAttribute('transform', (()=>`rotate(${deg} ${cx} ${cy})`)());
sca.setAttribute('transform', (()=>`translate(${cx} ${cy}) scale(${scale} ${scale}) translate(-${cx} -${cy})`)());
}
setInterval(rotate, 50);
<svg xmlns="http://www.w3.org/2000/svg" class="layer" id="layer_1547759965149_0506449632092969"
overflow="visible"
stroke="none" stroke-width="0" preserveAspectRatio="none"
width="135.24545454545" height="110.9375"
x="86.896363636365" y="84.286250000001">
<!--<g id="translateLayer" transform="matrix(0 67.622727272725 0 0 73.95833333333333 0)">-->
<g id="translateLayer" transform="matrix(2 0 0 2 0.5 0.5)" transform-origin(200,100)>
<g id="effectLayer"
fill="#FF4400">
<svg viewBox="0 0 657.01 569" width="100%" height="100%"
preserveAspectRatio="none" overflow="hidden">
<g id="Layer_2" data-name="Layer 2">
<g id="Layer_1-2" data-name="Layer 1">
<polygon points="0 569 328.49 0 657.01 569 0 569"/>
</g>
</g>
</svg>
</g>
</g>
</svg>
经过几个小时的代码斗争,我得到了我正在寻找的修复。
下面是我实现的最终矩阵计算
x = (x/2);
y = (y/2);
matrix(scaleX 0 0 scaleY (x-scaleX*x) (y-scaleY*y));