简体   繁体   English

SVG在具有速度或snap.svg的悬停上设置动画路径属性“ d”

[英]SVG animate path attribute “d” on hover with velocity or snap.svg

First, I'm a complete beginner with svg's and I can't find a good answer to solve my problem on Google. 首先,我是svg的完全入门者,我找不到在Google上解决我的问题的好答案。 What I've been trying to do, is simply animating an svg path on hover. 我一直试图做的只是在悬停时为svg路径设置动画。

I've downloaded and used snap.svg and velocity.js, so if you know an answer using one of this or maybe booth feel free. 我已经下载并使用了snap.svg和Velocity.js,因此,如果您知道使用其中之一的答案,甚至可以免费使用。

My current code and what I tried with velocity: 我当前的代码以及我尝试过的速度:

<div class="g50">
    <svg class="curtain" viewBox="0 0 180 320" preserveAspectRatio="none">
        <path d="M 180,160 0,200 0,0 180,0 z"/>
    </svg>
</div>

<div class="g50">
    <svg class="curtain" viewBox="0 0 180 320" preserveAspectRatio="none">
        <path d="M 180,200 0,160 0,0 180,0 z"/>
    </svg>
</div>

JS: JS:

$('.curtain').on('mouseenter', function(){
    $(this).find('path').velocity({ 'd': "m 180,34.57627 -180,0 L 0,0 180,0 z" });
});

JS Fiddle Demo: JS小提琴演示:

HERE 这里

There are two solutions for this. 有两种解决方案。 The first is pretty straightforward, but it will produce unwanted effects if a user quickly enters and exits the SVG element. 第一个非常简单,但是如果用户快速进入和退出SVG元素,它将产生不想要的效果。 Essentially, the animation will looping for far too long; 本质上,动画将循环播放太长时间; however, it works just fine if the user is casually hovering over the element. 但是,如果用户随便将鼠标悬停在元素上,它就可以正常工作。

Here's a demo with that solution . 这是该解决方案的演示

The other solution is more robust and accounts for unusually rapid 'hover toggling' from the user. 另一种解决方案则更健壮,可以解决用户异常快速的“悬停切换”问题。 If the user rapidly hovers in and out of the element, this solution just stops and reverses the animation. 如果用户快速在元素中上下移动,则此解决方案将停止并反转动画。 This is what I use on any hover states with velocity. 这就是我在任何具有速度的悬停状态下使用的方法。

You can view that solution here . 您可以在此处查看该解决方案

Here's the javascript code using JQuery 这是使用JQuery的javascript代码

...

var svg = $('.curtain');
var path = svg.find('path'); // define svg path
path.data({animating:false}); // add data for animation queue purposes

path.hover(function() { // mouse enter

/*
if the path is in the middle of an animation, stop it immediately and reverse the animation. This prevents many unwanted animations if the user hovers in and out quickly
*/

if (path.data('animating') === true){
path.velocity("stop", true).velocity('reverse',{ duration:300});
path.data({animating:false});

} else {  // begin default animation
$(this).velocity({fill: '#ffcc00'},{
  duration:500,
  begin: function(){
    path.data({animating:true});
  },
  complete: function(){
    path.data({animating:false});
  }
});

} // end of conditional statement
}, function() { // mouse exit

/*
if the path is in the middle of an animation, stop it immediately and reverse the animation. This prevents many unwanted animations if the user hovers in and out quickly
*/

if (path.data('animating') === true){
path.velocity("stop", true).velocity('reverse',{ duration:300});
path.data({animating:false});


} else { // begin default animation

$(this).velocity({fill: '#000'},{
  duration:500,
  begin: function(){
    path.data({animating:true});
  },
  complete: function(){
    path.data({animating:false});
  }
});

} // end of conditional statement
}); // end of hover function

...

If you want to animate the path dimensions, I would suggest using Snap.svg. 如果要设置路径尺寸的动画,建议使用Snap.svg。 Here's a simple example using snap.svg to animate the paths. 这是一个使用snap.svg设置路径动画的简单示例。

HTML HTML

<!--add hover state data to div-->  
  <div class="g50" data-path-hover="m 180,34.57627 -180,0 L 0,0 180,0 z">
    <svg viewBox="0 0 180 320" preserveAspectRatio="none"><path d="M 180,160 0,218 0,0 180,0 z"/></svg>
</div>

 <!--add hover state data to div-->
<div class="g50" data-path-hover="m 180,34.57627 -180,0 L 0,0 180,0 z">
    <svg viewBox="0 0 180 320" preserveAspectRatio="none"><path d="M 180,160 0,218 0,0 180,0 z"/></svg>
</div>

JS JS

(function() {

    function init() {
        var speed = 250,
            easing = mina.easeinout;

        [].slice.call ( document.querySelectorAll( '.g50' ) ).forEach( function( el ) {
            var s = Snap( el.querySelector( 'svg' ) ),
            path = s.select( 'path' ),
                pathConfig = {
                    from : path.attr( 'd' ),
                    to : el.getAttribute( 'data-path-hover' )
                };

            el.addEventListener( 'mouseenter', function() {
                path.animate( { 'path' : pathConfig.to }, speed, easing );
        console.log(pathConfig.to);
            } );

            el.addEventListener( 'mouseleave', function() {
                path.animate( { 'path' : pathConfig.from }, speed, easing );
            } );
        } );
    }

    init();

})();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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