有没有一种方法可以翻转SVG坐标系,使得[0,0]在左下角而不是左上角?
我进行了大量实验,唯一合理的方法如下:
<g transform="translate(0,400)">
<g transform="scale(1,-1)">
这里的400是图片的高度。这样做的效果是将所有内容向下移动,以使得图片顶部与页面顶部对齐,然后缩放操作会翻转Y坐标,使得现在位于页面/图片之外的部分被翻转回来填充留下来的空间。
svg.cartesian {
display:flex;
}
/* Flip the vertical axis in <g> to emulate cartesian. */
svg.cartesian > g {
transform: scaleY(-1);
}
/* Re-flip all <text> element descendants to their original side up. */
svg.cartesian > g text {
transform: scaleY(-1);
}
<html>
<head></head>
<body>
<svg class="cartesian" viewBox="-100 -100 200 200" preserveAspectRatio="xMidYMid meet">
<g>
<!-- SVG Start -->
<!-- Vertical / Horizontal Axis: Can be removed if you don't want x/y axes. -->
<path d="M0 -100 V 200" stroke="green" stroke-width="0.5" stroke-opacity="0.5" />
<path d="M-100 0 H 200" stroke="green" stroke-width="0.5" stroke-opacity="0.5" />
<!-- Plotting: This is an example plotting two points at (20, 20) and (-50, -35), replace it with your data. -->
<g transform="translate(20, 20)">
<circle r="1" />
<text>(20, 20)</text>
</g>
<g transform="translate(-50, -35)">
<circle r="0.5" />
<text>(-50, -35)</text>
</g>
<!-- SVG End -->
</g>
</svg>
</body>
</html>
scaleY(-1)
自动翻转页面上的所有文本元素。我知道这已经过时了,但我正在做同样的事情,尝试了@Nippysaurus的版本,但由于所有内容都将被旋转(因此如果您放置图像,则必须将它们旋转回来),这太烦人了。不过有另一种解决方案。
我所做的就是简单地移动svg
的viewBox,并在y轴上反转所有坐标(还删除了对象的高度,使其位于左下角),如下:
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="300" viewBox="0 -300 200 300">
<rect x="20" y="-40" width="20" height="20" stroke="black" stroke-width="1px"></rect>
</svg>
这将在svg
的左下角距离为20,20处放置一个rect
,见http://jsfiddle.net/DUVGz/
#parrot {
transform-origin: 50% 50%; /* center of rotation is set to the center of the element */
transform: scale(1,-1);
}
Credits: https://sarasoueidan.com/blog/svg-transformations/#transforming-svgs-with-css
是的,先进行一个-90度的坐标旋转,然后再进行一个+新图形高度的平移即可。在W3C有一个示例。
<g transform="translate(0,400) scale(1,-1)">
这也等同于以下内容:
<g transform="scale(1,-1) translate(0,-400) ">
因为
<g transform="matrix(1 0 0 -1 0 svgHeight)">
matrix(a b c d e f)
如下所示。
| a c e |
| b d f |
| 0 0 1 |
| x |
| y |
| 1 |
| a c e | |x| | ax+cy+e |
| b d f | . |y| = | bx+dy+f |
| 0 0 1 | |1| | 0x+0y+1 |
什么时候
a, b, c, d, e, f
1, 0, 0, -1, 0, heght
=>
| ax+cy+e | | x |
| bx+dy+f | = | -y + height |
| 0x+0y+1 | | 1 |
<style>
svg {
border: 1px solid
}
</style>
<table>
<tr>
<th>org</th>
<th>svg</th>
</tr>
<tr>
<td>top left</td>
<td>
<svg width="100" height="100" stroke="black">
<path d="
M 50 70
L 80 30
"/>
<circle fill='#ff0000' cx="50" cy="70" r="2"></circle>
<text x=55 y=75 style="font-size: 10px;" fill="blue">(50, 70)</text>
<!-- x -->
<!-- https://bennettfeely.com/clippy/ -->
<polygon points="30 7 10 15 10 0" fill="gray" />
<!-- y -->
<polygon points="15,20 0,20 7 40" fill="gray" />
</svg>
</td>
</tr>
<tr>
<td>bottom left</td>
<td>
<svg width="100" height="100" stroke="black">
<g transform="matrix(1 0 0 -1 0 100)"> <!-- -->
<path d="
M 50 70
L 80 30
"/>
<circle fill='#ff0000' cx="50" cy="70" r="2"></circle>
<!-- x -->
<polygon points="30 7 10 15 10 0" fill="gray" />
<!-- y -->
<polygon points="15,20 0,20 7 40" fill="gray" />
</g>
<!-- y=-75+100=25 -->
<text x=55 y=25 style="font-size: 10px;" fill="blue">(50, 70)</text>
</svg>
</td>
</tr>
</table>
另一种选择是使用 D3 v4 scaleLinear ,创建一个能够为您执行交换的函数。
import * as d3 from "d3";
...
// Set the height to the actual value to where you want to shift the coords.
// Most likely based on the size of the element it is contained within
let height = 1;
let y = d3.scaleLinear()
.domain([0,1])
.range([height,0]);
console.log("0 = " + y(0)); // = 1
console.log("0.5 = " + y(0.5)); // = 0.5
console.log("1 = " + y(1)); // = 0
console.log("100 = " + y(100)); // = -99
console.log("-100 = " + y(-100)); // = 101
我认为将元素旋转180度的最简单方法是将其旋转180.1度;
transform="translate(180.1,0,0)"
viewbox="-200 -200 400 400"
完成了翻译。 - SimplyKnownAsG<g transform="matrix(1 0 0 -1 0 400)">
(其中400是图像的高度)。 - r3mainer