简体   繁体   中英

Animate SVG viewBox change

I am currently using velocity.js to control some animation on an SVG drawing I am creating. It is interactive with the user, so when a click happens in certain parts, the picture might grow to the right or down. So far everything is working perfectly until the picture gets too big for the SVG box.

In those situations, I simply resize the viewBox to scale the image.

svgDoc.setAttribute("viewBox", "0 0 " + svgDocWidth + " " + svgDocHeight);

This works, but it doesn't look great because it isn't animated. It just jumps to the new size. Is there a way to animate with velocity.js a viewBox change?

I've tried this approach:

$viewBox = $(svgDoc.viewBox);
$viewBox.velocity({height: svgDocHeight, width: svgDocWidth});

But that doesn't do anything.

Is this beyond what velocity.js can support?

Solution on 2015-11-21

@Ian gave the solution I eventually used. It ended up looking like this:

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); 
        }
     });
}   

You can animate a viewBox smoothly via SMIL. Like this...

 <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> 

I think SMIL is being deprecated in Chrome (please correct me if I'm wrong), so I'm guessing there will be increasing reliance on other methods.

There's no reason you can't use velocity, but with your own calculations and the progress/tweenValue parameter, eg something a bit like this...

$("#mysvg").velocity(
    { tween: 200 },
    { progress: animViewbox }
)

function animViewbox (elements, complete, remaining, start, tweenValue) {
     elements[0].setAttribute('viewBox', '0 0 ' + tweenValue + ' ' + tweenValue);  
}

jsfiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM