在悬停时开始和暂停SVG动画

时间:2014-08-06 01:19:36

标签: svg svg-animate

当用户将鼠标悬停在其上时,我想在下面的SVG上设置齿轮动画。也就是说,当鼠标进入时,两个齿轮在它们停止的地方开始旋转。当鼠标离开时,齿轮会停在它们所处的任何位置。如果可能的话,我希望动画以易于进/出功能开始和结束。如何使用SVG动画完成这项工作?

Codepen

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="256" height="256" viewBox="0 0 256 256">

    <path d="M249.363 80.921l-6.402-15.451c-1.769-4.267-6.659-6.292-10.927-4.528l-9.032 3.7 c-8.043-12.801-18.893-23.646-31.692-31.689l3.744-9.032c1.768-4.266-0.258-9.162-4.528-10.926l-15.45-6.402 c-4.264-1.764-9.16 0.261-10.923 4.523l-3.744 9.032c-14.458-3.293-29.542-3.478-44.817 0l-3.74-9.028 c-1.768-4.267-6.659-6.292-10.926-4.528l-15.451 6.402c-4.267 1.768-6.296 6.656-4.528 10.926l3.744 9 C71.893 41 61 51.9 53 64.687l-9.032-3.744c-4.263-1.764-9.158 0.261-10.927 4.528l-6.398 15.5 c-1.768 4.3 0.3 9.2 4.5 10.926l9.028 3.74c-3.349 14.666-3.435 29.8 0 44.816l-9.028 3.7 c-4.271 1.768-6.296 6.664-4.528 10.926l6.398 15.451c1.772 4.3 6.7 6.3 10.9 4.524l9.032-3.741 c8.044 12.8 18.9 23.6 31.7 31.693l-3.74 9.032c-1.768 4.3 0.3 9.2 4.5 10.927l15.451 6.4 c4.267 1.8 9.158-0.257 10.926-4.528l3.74-9.028c14.613 3.3 29.7 3.4 44.8 0l3.739 9 c1.768 4.3 6.7 6.3 10.9 4.528l15.45-6.402c4.267-1.768 6.292-6.663 4.524-10.927l-3.744-9.032 c12.8-8.048 23.649-18.896 31.692-31.693l9.032 3.741c4.268 1.8 9.158-0.254 10.927-4.524l6.398-15.451 c1.768-4.262-0.257-9.162-4.524-10.922l-9.032-3.739c3.328-14.583 3.458-29.682 0-44.825l9.032-3.74 C249.103 90.1 251.1 85.2 249.4 80.921z M138 176.536c-32.278 0-58.537-26.259-58.537-58.536 c0-32.281 26.259-58.536 58.537-58.536c32.276 0 58.5 26.3 58.5 58.536C196.535 150.3 170.3 176.5 138 176.536z">
        <animateTransform
            attributeName="transform"
            repeatCount="indefinite"
            type="rotate"
            from="00 138 118"
            to="+360 138 118"
            begin="0s" dur="30s"/>
    </path>

    <path d="M57.552 217.745l-2.16 0.895c0.811 3.6 0.8 7.2 0 10.721l2.16 0.895c1.021 0.4 1.5 1.6 1.1 2.612l-1.53 3.7 c-0.423 1.021-1.593 1.506-2.613 1.082l-2.16-0.895c-1.924 3.061-4.519 5.655-7.58 7.58l0.895 2.2 c0.423 1.02-0.062 2.19-1.082 2.613l-3.695 1.531c-1.021 0.422-2.191-0.063-2.614-1.083l-0.895-2.16 c-3.508 0.801-7.12 0.821-10.719 0l-0.895 2.159c-0.423 1.021-1.593 1.506-2.613 1.083l-3.695-1.53 c-1.021-0.423-1.505-1.594-1.082-2.613l0.895-2.16c-3.062-1.924-5.656-4.519-7.581-7.58l-2.16 0.9 c-1.021 0.424-2.189-0.061-2.613-1.082l-1.53-3.695c-0.423-1.02 0.062-2.19 1.083-2.613l2.159-0.895 c-0.801-3.507-0.821-7.121 0-10.719l-2.159-0.895c-1.021-0.424-1.506-1.594-1.083-2.613l1.53-3.696 c0.423-1.021 1.594-1.505 2.613-1.083l2.161 0.896c1.924-3.062 4.519-5.655 7.58-7.579l-0.896-2.16 c-0.423-1.021 0.063-2.19 1.083-2.613l3.695-1.531c1.021-0.422 2.2 0.1 2.6 1.083l0.895 2.159c3.427-0.78 7.035-0.839 10.7 0 l0.895-2.16c0.422-1.02 1.593-1.504 2.612-1.082l3.695 1.531c1.021 0.4 1.5 1.6 1.1 2.613l-0.895 2.2 c3.061 1.9 5.7 4.5 7.6 7.579l2.161-0.896c1.021-0.422 2.2 0.1 2.6 1.083l1.531 3.7 C59.057 216.2 58.6 217.3 57.6 217.745z M46 224c0-7.721-6.28-14-14-14s-14 6.279-14 14c0 7.7 6.3 14 14 14 S46 231.7 46 224z">
        <animateTransform
            attributeName="transform"
            repeatCount="indefinite"
            type="rotate"
            from="00 32 224"
            to="-360 32 224"
            begin="0s" dur="20s"/>
    </path>

</svg>

2 个答案:

答案 0 :(得分:11)

假设cog有id biglittle,这里有一种方法可以使用css动画:

#big {
    transform-origin: 138px 118px;
    animation-duration: 30s;
    animation-name: rotateBig;
    animation-fill-mode: forwards;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-play-state: paused;
}
#little {
    transform-origin: 32px 224px;
    animation-duration: 20s;
    animation-name: rotateLittle;
    animation-fill-mode: forwards;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
    animation-play-state: paused;
}
#big:hover, #little:hover {
    animation-play-state: running;
}
@keyframes rotateBig {
    to {
        transform: rotate(360deg);
    }
}
@keyframes rotateLittle {
    to {
        transform: rotate(-360deg);
    }
}

live example。当悬停时,这会使每个齿轮单独动画。

对于整个svg悬停时动画两个齿轮的东西:

#big {
    transform-origin: 138px 118px;
    animation-duration: 30s;
    animation-name: rotateBig;
    animation-fill-mode: forwards;
    animation-timing-function: linear;
    animation-iteration-count: infinite;
}
#little {
    transform-origin: 32px 224px;
    animation-duration: 20s;
    animation-name: rotateLittle;
    animation-fill-mode: forwards;
    animation-timing-function: linear;
    animation-iteration-count: infinite;        
}
svg > * { 
    animation-play-state: paused; 
}
svg:hover > * {
    animation-play-state: running;
}
@keyframes rotateBig {
    to {
        transform: rotate(360deg);
    }
}
@keyframes rotateLittle {
    to {
        transform: rotate(-360deg);
    }
}

live example。唯一的区别是选择器设置animation-play-state

您可能不得不求助于使用css供应商前缀来使其更兼容,但我已经以最干净的形式提供了它。小提琴至少可以在Opera 25,Chrome 38和Firefox Nightly 34中运行良好。

这里的解决方案略有不足之处在于,开始和结束并非使用轻松进出,这是因为这使得重复可见。如果有人对如何在不使用脚本的情况下解决问题有一个聪明的想法,我会全力以赴。

答案 1 :(得分:3)

几乎那里。添加此调整:

  • id="gear1"添加到第一个<path...>
  • id="gear2"添加到第二个<path...>
  • 使用此<path...
  • 结束onmouseover=runGears(); onmouseout=stopGears(); >
  • <animate .....>
  • 中移除<path....>

在JS魔术上旋转齿轮,请使用以下代码:

var animateGears ; // event handler
var angle = 0; // rotation of angle

var gear1 = document.getElementById("gear1");
var gear2 = document.getElementById("gear2");

function runGears() {
animateGears = setInterval( function () {
        angle += 5;
        if (angle == 360 ) { angle = 0 } ; // 360 == 0 degrees

        gear1.setAttribute("transform", "rotate(" + angle + " 138 118)");
        gear2.setAttribute("transform", "rotate(" + angle + " 32 224)");
    }, 100);
}

function stopGears() {
    clearInterval(animateGears);
}

注意:使用100毫秒的超时和+5的角度来使它看起来更平滑。

更新可能为您工作的其他JS编码(不删除<animate....): -

var svgDoc =  document.getElementsByTagName('svg');

svgdoc[0].pauseAnimations(); // pause animation at load time

function runGears() {
 svgDoc[0].unpauseAnimations(); // resumes ALL animations
}
function stopGears() {
 svgDoc[0].pauseAnimations(); // pause ALL animations
}