如何在 SVG 中 "zooming" 时保持 viewBox 居中?
How to keep viewBox centered when "zooming" in SVGs?
我经常将 viewBox
属性用于 "zoom" SVG 元素。缩放当然是通过为 viewBox
属性使用较低的 width 和 height 值来实现的——但是 x 和 y 值很难弄清楚以保持场景居中。
下面是 viewBox="0 0 100 100"
的片段。 ( x y width height ) 这是我的起点。场景是按比例缩放的,从左上角开始。
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
(可在整页中查看。片段是响应式的)
正在放大
在 viewBox
中将 width 和 height 值更改为 50
缩放场景。但是,我必须将 x
和 y
值都调整为 viewBox
尺寸的一半:25
以保持绘图居中。
viewBox="25 25 50 50"
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="25 25 50 50"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
宽度和高度减半不一致
按照宽度和高度减半的模式使场景居中:
viewBox="12.5 12.5 25 25"
应继续缩放并保持居中。但它不会保持居中。我的问题是 SVG 使用什么公式或技术,我总能从数学上算出什么 x 和 y 值我需要将特定 [= viewBox
?
中的 63=]width 和 height 值
注意:我知道像 Snap.svg and Raphaël 这样的库。我正在避开图书馆以努力了解基础知识。
还有一件事:我想问您是否已经在 width 和 height 值=13=] 如何找到场景的中心坐标。反之则不然。
包含用于视觉认知的外部样式表。与此问题唯一相关的代码与 SVG 元素有关。
你的计算有误。如果 viewBox
的宽度和高度变小,则 x 和 y 值需要变大。
Initial viewBox: 0 0 100 100
Zoom X2: 25 25 50 50
Zoom X4: 37.5 37.5 25 25
要获得 x 或 y 值,您需要从最后一个(或原始)viewBox 的中间点减去新宽度或高度的一半。
Zoom X2: centre - newWidth/2
= (100/2) - (50/2) = 25
Zoom X4: (100/2) - (25/2) = 37.5, or
(25 + 50/2) - (25/2) = 37.5
另一种计算方法是用原来的宽度减去当前宽度再除以二
Zoom X4: (100 - 25) / 2 = 37.5
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="37.5 37.5 25 25"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
由于代码片段已过期,我不得不考虑如何实现它,我想我会避免其他人这样做,post 一个有效的代码片段。
var svg = document.querySelector('svg');
var viewBox = svg.viewBox.baseVal;
function zoomIn(){
viewBox.x = viewBox.x + viewBox.width / 4;
viewBox.y = viewBox.y + viewBox.height / 4;
viewBox.width = viewBox.width / 2;
viewBox.height = viewBox.height / 2;
}
function zoomOut(){
viewBox.x = viewBox.x - viewBox.width / 2;
viewBox.y = viewBox.y - viewBox.height / 2;
viewBox.width = viewBox.width * 2;
viewBox.height = viewBox.height * 2;
}
如果您实现了平移功能,它也无需任何修改即可使用。
我经常将 viewBox
属性用于 "zoom" SVG 元素。缩放当然是通过为 viewBox
属性使用较低的 width 和 height 值来实现的——但是 x 和 y 值很难弄清楚以保持场景居中。
下面是 viewBox="0 0 100 100"
的片段。 ( x y width height ) 这是我的起点。场景是按比例缩放的,从左上角开始。
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 100 100"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
(可在整页中查看。片段是响应式的)
正在放大
在 viewBox
中将 width 和 height 值更改为 50
缩放场景。但是,我必须将 x
和 y
值都调整为 viewBox
尺寸的一半:25
以保持绘图居中。
viewBox="25 25 50 50"
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="25 25 50 50"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
宽度和高度减半不一致
按照宽度和高度减半的模式使场景居中:
viewBox="12.5 12.5 25 25"
应继续缩放并保持居中。但它不会保持居中。我的问题是 SVG 使用什么公式或技术,我总能从数学上算出什么 x 和 y 值我需要将特定 [= viewBox
?
注意:我知道像 Snap.svg and Raphaël 这样的库。我正在避开图书馆以努力了解基础知识。
还有一件事:我想问您是否已经在 width 和 height 值=13=] 如何找到场景的中心坐标。反之则不然。
包含用于视觉认知的外部样式表。与此问题唯一相关的代码与 SVG 元素有关。
你的计算有误。如果 viewBox
的宽度和高度变小,则 x 和 y 值需要变大。
Initial viewBox: 0 0 100 100
Zoom X2: 25 25 50 50
Zoom X4: 37.5 37.5 25 25
要获得 x 或 y 值,您需要从最后一个(或原始)viewBox 的中间点减去新宽度或高度的一半。
Zoom X2: centre - newWidth/2
= (100/2) - (50/2) = 25
Zoom X4: (100/2) - (25/2) = 37.5, or
(25 + 50/2) - (25/2) = 37.5
另一种计算方法是用原来的宽度减去当前宽度再除以二
Zoom X4: (100 - 25) / 2 = 37.5
<head>
<link rel="stylesheet" href="https://codepen.io/basement/pen/oepKxY.css">
</head>
<body>
<iframe src="https://s.codepen.io/basement/debug/zdpVyV/PNAvYLZmJRQr"
id="grid"
></iframe>
<div class="wrp">
<!-- SVG relevant code below-->
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="37.5 37.5 25 25"
width="100" height="100"
class="canvas"
>
<defs>
<style type="text/css">
circle {
fill: #0ff;
fill-opacity: 0.25;
stroke-width: 0.25;
stroke: #0ee;
}
</style>
</defs>
<circle cx="37.5" cy="50" r="25" />
<circle cx="62.5" cy="50" r="25" />
<circle cx="50" cy="71.65" r="25" />
</svg>
</div>
</body>
由于代码片段已过期,我不得不考虑如何实现它,我想我会避免其他人这样做,post 一个有效的代码片段。
var svg = document.querySelector('svg');
var viewBox = svg.viewBox.baseVal;
function zoomIn(){
viewBox.x = viewBox.x + viewBox.width / 4;
viewBox.y = viewBox.y + viewBox.height / 4;
viewBox.width = viewBox.width / 2;
viewBox.height = viewBox.height / 2;
}
function zoomOut(){
viewBox.x = viewBox.x - viewBox.width / 2;
viewBox.y = viewBox.y - viewBox.height / 2;
viewBox.width = viewBox.width * 2;
viewBox.height = viewBox.height * 2;
}
如果您实现了平移功能,它也无需任何修改即可使用。