SVGPanZoom 丢弃原始 viewBox
SVGPanZoom discards original viewBox
我正在使用 SVGPanZoom 在我的混合 Android 应用程序中管理 SVG 图像的缩放(出于所有意图和目的,与 Chrome 中的行为相同)。虽然缩放效果很好,但我发现了一个奇怪的问题。我原来的内联 SVG 元素是这样的
<svg id='puzzle' viewBox='0 0 1600 770' preserveAspectRatio='none'
width='100vw' height='85.5vh' fill-rule='evenodd' clip-rule='evenodd'
stroke-linejoin='round' stroke-miterlimit='1.414'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://
www.w3.org/1999/xlink'>
最初此 SVG 元素为空,并在 运行 时间从 JavaScript 以编程方式填充,之后我按如下方式启动 SVGPanZoom
var panZoom = svgPanZoom('#puzzle',
{panEnabled:false,controlIconsEnabled:false,
zoomEnabled:true,dblClickZoomEnabled:true,onZoom:postZoom});
panZoom.refreshRate = 10;
panZoom.zoomScaleSensitivity = 0.02;
我 运行 遇到的问题是这个 - 我希望我的 SVG 图像填充可用区域,100vw x 85.5vh
完全按照我通过上面的 preserveAspectRatio="none"
属性指示它的方式来完成随着 viewBox="0 0 1600 770" attribute. I have found that this works - so long as I don't use SVGPanZoom. As soon as I initiate panZoom the
zoomBox` 属性被剥离,我最终得到一个图像,它的默认 stretching/filling 行为不太正常。
SVGPanZoom 被广泛使用,所以我认为这种行为是我没有正确设置它造成的。深入研究我发现 SVGPanZoom 的代码会创建一个 cacheViewBox
,然后继续删除原始的 zoomBox 属性。
如果在此之后缩放有效并且应用程序的原始行为没有改变,这很好,这不是我发现的。我在这里做错了什么?
我最近也 运行 关注这个问题。根据我的研究,这就是图书馆的运作方式。我选择暂时忍受这个限制,但我发现了一些其他库可能会按照您的预期工作(我还没有尝试过):
- jquery.panzoom 是一个 jquery 库,它提供了这个功能并且还有一些不错的特性。我知道很多人试图避免 jquery 但它很小,可以做你想做的事。它处理 SVG,但我不知道它对 viewBox 属性做了什么。
- react-svg-pan-zoom 是一个 React 组件,如果您正在使用 React,它可能会有用。
我也试过 PanZoom 库,但这也有同样的 viewBox 限制。
任何人 运行 进入此线程的注意事项。最后我放弃了 SVGPanZoom 并决定完全避免使用任何 pan/zoom 库。与此同时,我决定完全停止使用 SVG viewBox
并通过 SVG 转换完全由我自己处理所有 zooming/panning。涉及的核心步骤
- 将整个 SVG 内容包装在一个组中,以便更轻松地管理转换。我为这个组
使用 id
属性 gOuter
- 设置 SVG 的初始比例以占据所需的客户端矩形。在我的例子中,我有一个原始的
viewBox
of 0 0 1600 770
打算占据屏幕宽度的 100% 和屏幕高度的 85%。所以我的缩放比例是 scaleX = 1600/window.innerWidth
和 scaleY = 770/)0.85*window.innerHeight)
.
- 将此初始转换应用于包装外组,
gOuter.setAttribute('transform','0 0 scaleX,scaleY)
- 现在为了缩放到一个对象,其在原始 viewBox 中的虚拟左上角坐标为
Ox,Oy
,您将使用变换
gOuter.setAttribute('transform',
scale(scaleX,scaleY) translate(-Ox,-Oy) scale(2*scaleX,2*scaleY) translate(Ox,Oy))
放大 x 2
倍。此处需要了解的重要事项
- 在 SVG 中,变换是从右到左应用的。
- 这里我们将缩放点平移到顶部l.h.s。缩放然后将其平移回其原始位置。
- 问题是我们还需要通过初始缩放允许原始级别的缩放,因此我们将其标记为最后一个变换
这让您可以完全控制缩放过程,作为附带好处,操作变得比使用 pan/zoom 库时更加流畅。
我正在使用 SVGPanZoom 在我的混合 Android 应用程序中管理 SVG 图像的缩放(出于所有意图和目的,与 Chrome 中的行为相同)。虽然缩放效果很好,但我发现了一个奇怪的问题。我原来的内联 SVG 元素是这样的
<svg id='puzzle' viewBox='0 0 1600 770' preserveAspectRatio='none'
width='100vw' height='85.5vh' fill-rule='evenodd' clip-rule='evenodd'
stroke-linejoin='round' stroke-miterlimit='1.414'
xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://
www.w3.org/1999/xlink'>
最初此 SVG 元素为空,并在 运行 时间从 JavaScript 以编程方式填充,之后我按如下方式启动 SVGPanZoom
var panZoom = svgPanZoom('#puzzle',
{panEnabled:false,controlIconsEnabled:false,
zoomEnabled:true,dblClickZoomEnabled:true,onZoom:postZoom});
panZoom.refreshRate = 10;
panZoom.zoomScaleSensitivity = 0.02;
我 运行 遇到的问题是这个 - 我希望我的 SVG 图像填充可用区域,100vw x 85.5vh
完全按照我通过上面的 preserveAspectRatio="none"
属性指示它的方式来完成随着 viewBox="0 0 1600 770" attribute. I have found that this works - so long as I don't use SVGPanZoom. As soon as I initiate panZoom the
zoomBox` 属性被剥离,我最终得到一个图像,它的默认 stretching/filling 行为不太正常。
SVGPanZoom 被广泛使用,所以我认为这种行为是我没有正确设置它造成的。深入研究我发现 SVGPanZoom 的代码会创建一个 cacheViewBox
,然后继续删除原始的 zoomBox 属性。
如果在此之后缩放有效并且应用程序的原始行为没有改变,这很好,这不是我发现的。我在这里做错了什么?
我最近也 运行 关注这个问题。根据我的研究,这就是图书馆的运作方式。我选择暂时忍受这个限制,但我发现了一些其他库可能会按照您的预期工作(我还没有尝试过):
- jquery.panzoom 是一个 jquery 库,它提供了这个功能并且还有一些不错的特性。我知道很多人试图避免 jquery 但它很小,可以做你想做的事。它处理 SVG,但我不知道它对 viewBox 属性做了什么。
- react-svg-pan-zoom 是一个 React 组件,如果您正在使用 React,它可能会有用。
我也试过 PanZoom 库,但这也有同样的 viewBox 限制。
任何人 运行 进入此线程的注意事项。最后我放弃了 SVGPanZoom 并决定完全避免使用任何 pan/zoom 库。与此同时,我决定完全停止使用 SVG viewBox
并通过 SVG 转换完全由我自己处理所有 zooming/panning。涉及的核心步骤
- 将整个 SVG 内容包装在一个组中,以便更轻松地管理转换。我为这个组 使用
- 设置 SVG 的初始比例以占据所需的客户端矩形。在我的例子中,我有一个原始的
viewBox
of0 0 1600 770
打算占据屏幕宽度的 100% 和屏幕高度的 85%。所以我的缩放比例是scaleX = 1600/window.innerWidth
和scaleY = 770/)0.85*window.innerHeight)
. - 将此初始转换应用于包装外组,
gOuter.setAttribute('transform','0 0 scaleX,scaleY)
- 现在为了缩放到一个对象,其在原始 viewBox 中的虚拟左上角坐标为
Ox,Oy
,您将使用变换
id
属性 gOuter
gOuter.setAttribute('transform',
scale(scaleX,scaleY) translate(-Ox,-Oy) scale(2*scaleX,2*scaleY) translate(Ox,Oy))
放大 x 2
倍。此处需要了解的重要事项
- 在 SVG 中,变换是从右到左应用的。
- 这里我们将缩放点平移到顶部l.h.s。缩放然后将其平移回其原始位置。
- 问题是我们还需要通过初始缩放允许原始级别的缩放,因此我们将其标记为最后一个变换
这让您可以完全控制缩放过程,作为附带好处,操作变得比使用 pan/zoom 库时更加流畅。