动画 SVG viewBox 变化
Animate SVG viewBox change
我目前正在使用 velocity.js 来控制我正在创建的 SVG 绘图上的一些动画。它是与用户交互的,因此当某些部分发生点击时,图片可能会向右或向下增长。到目前为止,一切都运行良好,直到图片对于 SVG 框来说太大了。
在那些情况下,我只需调整 viewBox 的大小来缩放图像。
svgDoc.setAttribute("viewBox", "0 0 " + svgDocWidth + " " + svgDocHeight);
这可行,但它看起来不太好,因为它不是动画。它只是跳到新的大小。有没有办法通过 velocity.js viewBox 的变化来制作动画?
我试过这种方法:
$viewBox = $(svgDoc.viewBox);
$viewBox.velocity({height: svgDocHeight, width: svgDocWidth});
但这没有任何作用。
这是否超出了 velocity.js 可以支持的范围?
2015-11-21解决方案
@Ian 给出了我最终使用的解决方案。它最终看起来像这样:
var origHeight = this.svgDoc.viewBox.animVal.height;
var origWidth = this.svgDoc.viewBox.animVal.width;
var docHeight = this.SvgHeight();
var docWidth = this.SvgWidth();
if ((origHeight != docHeight) || (origWidth != docWidth))
{
var deltaHeight = docHeight - origHeight;
var deltaWidth = docWidth - origWidth;
$(this.svgDoc).velocity(
{
tween: 1
},
{
progress: function(elements, complete, remaining, start, tweenValue)
{
var newWidth = origWidth + complete * deltaWidth;
var newHeight = origHeight + complete * deltaHeight;
elements[0].setAttribute('viewBox', '0 0 ' + newWidth + ' ' + newHeight);
}
});
}
您可以通过 SMIL 流畅地设置 viewBox 的动画。像这样...
<svg width="100%" height="100%" viewBox="0 0 200 200">
<animate attributeName="viewBox" to="0 0 400 400" dur="5s" fill="freeze" />
<circle cx="100" cy="100" r="100" fill="green" />
</svg>
我认为 SMIL 在 Chrome 中被弃用(如果我错了,请纠正我),所以我猜对其他方法的依赖会越来越多。
你没有理由不能使用速度,但是你可以使用自己的计算和 progress/tweenValue 参数,例如有点像这样的东西......
$("#mysvg").velocity(
{ tween: 200 },
{ progress: animViewbox }
)
function animViewbox (elements, complete, remaining, start, tweenValue) {
elements[0].setAttribute('viewBox', '0 0 ' + tweenValue + ' ' + tweenValue);
}
我目前正在使用 velocity.js 来控制我正在创建的 SVG 绘图上的一些动画。它是与用户交互的,因此当某些部分发生点击时,图片可能会向右或向下增长。到目前为止,一切都运行良好,直到图片对于 SVG 框来说太大了。
在那些情况下,我只需调整 viewBox 的大小来缩放图像。
svgDoc.setAttribute("viewBox", "0 0 " + svgDocWidth + " " + svgDocHeight);
这可行,但它看起来不太好,因为它不是动画。它只是跳到新的大小。有没有办法通过 velocity.js viewBox 的变化来制作动画?
我试过这种方法:
$viewBox = $(svgDoc.viewBox);
$viewBox.velocity({height: svgDocHeight, width: svgDocWidth});
但这没有任何作用。
这是否超出了 velocity.js 可以支持的范围?
2015-11-21解决方案
@Ian 给出了我最终使用的解决方案。它最终看起来像这样:
var origHeight = this.svgDoc.viewBox.animVal.height;
var origWidth = this.svgDoc.viewBox.animVal.width;
var docHeight = this.SvgHeight();
var docWidth = this.SvgWidth();
if ((origHeight != docHeight) || (origWidth != docWidth))
{
var deltaHeight = docHeight - origHeight;
var deltaWidth = docWidth - origWidth;
$(this.svgDoc).velocity(
{
tween: 1
},
{
progress: function(elements, complete, remaining, start, tweenValue)
{
var newWidth = origWidth + complete * deltaWidth;
var newHeight = origHeight + complete * deltaHeight;
elements[0].setAttribute('viewBox', '0 0 ' + newWidth + ' ' + newHeight);
}
});
}
您可以通过 SMIL 流畅地设置 viewBox 的动画。像这样...
<svg width="100%" height="100%" viewBox="0 0 200 200">
<animate attributeName="viewBox" to="0 0 400 400" dur="5s" fill="freeze" />
<circle cx="100" cy="100" r="100" fill="green" />
</svg>
我认为 SMIL 在 Chrome 中被弃用(如果我错了,请纠正我),所以我猜对其他方法的依赖会越来越多。
你没有理由不能使用速度,但是你可以使用自己的计算和 progress/tweenValue 参数,例如有点像这样的东西......
$("#mysvg").velocity(
{ tween: 200 },
{ progress: animViewbox }
)
function animViewbox (elements, complete, remaining, start, tweenValue) {
elements[0].setAttribute('viewBox', '0 0 ' + tweenValue + ' ' + tweenValue);
}