【问题标题】:Why is this CSS3 Rotation Animation setup not working on Chrome & Safari?为什么这个 CSS3 旋转动画设置在 Chrome 和 Safari 上不起作用?
【发布时间】:2014-10-29 01:02:48
【问题描述】:

(JSFIDDLE提供..)

目标:

  • 不断旋转一个元素 3 秒然后停止
  • 旋转停止后,将元素旋转 175 度。从 当前 角度开始为旋转设置动画(无论恒定旋转停止时的角度是什么)

问题 #1

Chrome 上,停止持续旋转后,元素会旋转 175 度,但没有任何动画。我正在尝试重置动画(我暂停以停止持续旋转)但似乎没有任何效果。

问题 #2

Safari 上,停止持续旋转后,元素的 角度会重置为 0 度(自行),然后通过动画将其旋转到 175 度。

因此,在这两种情况下,事件顺序都无法按预期进行。你能看出我做错了什么吗?

您是否有包含 IE10+ 的跨浏览器检查解决方案?

请查看此 JSFIDDLE 以查看下面的代码

CSS:

span {
   position:absolute;
   top: 10px;
   left: 10px; 
}

div {
    position:absolute;
    top: 100px;
    left: 100px;
    height: 100px;
    width: 100px;
    background-color: black;
    border-top: 10px solid blue;
    border-bottom: 10px solid red;
    border-left: 10px solid green;
    border-right: 10px solid yellow;
}

@-webkit-keyframes constantrotate {  
    from {    
        -webkit-transform: rotate(0deg);  
    }  
    to {    
        -webkit-transform: rotate(360deg);  
    }
} 

HTML:

<span></span>
<div></div>

JAVASCRIPT:

/* This function returns the element's current degrees at any given time */
var currentDegreesFor = function($element) {
    var matrix = $element.css("-webkit-transform") ||
        $element.css("-moz-transform") ||
        $element.css("-ms-transform") ||
        $element.css("-o-transform") ||
        $element.css("transform");

    if (matrix !== 'none') {
        var values = matrix.split('(')[1].split(')')[0].split(',');
        var a = values[0];
        var b = values[1];
        var angle = Math.round(Math.atan2(b, a) * (180 / Math.PI));
    } else {
        var angle = 0;
    }

    return (angle < 0) ? angle += 360 : angle;
};

var $element = $('div');

// INITIALIZING CONSTANT ROTATION
$('span').text('rotating constantly');
$element.css({
    "-webkit-animation": "constantrotate infinite 5s linear",
    "animation": "constantrotate infinite 5s linear"
});

// AFTER 3 SECONDS
setTimeout(function() {
    // STOP CONTSTANT ROTATION
    $element.css({
        'animation-play-state': 'paused',
        '-webkit-animation-play-state': 'paused'
    });

    // get element's current degrees
    var degrees = currentDegreesFor($element);

    $('span').text('constant rotation stopped at ' + degrees +
        ' degrees');

    // AFTER 3 SECONDS
    setTimeout(function() {
        /* This animation has now stopped at X degrees
        However the element's current rotation isn't 
        set to X degrees explicitly with a CSS rule.
        Apparently, I need to add that rule myself if I want to 
        further rotate the element */
        $element.css({
            'transform': 'rotate(' + degrees + 'deg)',
            '-webkit-transform': 'rotate(' + degrees + 'deg)'
        });

        $('span').text('CSS tranform: rotate() set to ' + degrees +
            ' degrees');

        // AFTER 3 SECONDS
        setTimeout(function() {
            $('span').text('rotating to 175 degrees with animation');

            /* I'm now resetting the animation from 
            "constantrotate" to "transition". The element is
            rotated but with no animation (at least none on Chrome - on Safari the element's angle 
            is set back to 0 before this animation begins). What am I doing wrong ?
            */
            $element.css({
                '-webkit-animation': '-webkit-transition',
                'animation': 'transition',
                'transition': 'transform 10s ease-in',
                '-webkit-transition': '-webkit-transform 10s ease-in',
                'transform': 'rotate(175deg)',
                '-webkit-transform': 'rotate(175deg)'
            });
        }, 3000);
    }, 3000);
}, 4000);

【问题讨论】:

  • 您能详细说明一下吗?您可以在我提供的 JSFiddle(如果您喜欢 Chrome 和 Safari)上尝试您的建议,看看它是否真的有效。
  • 它本身不会工作。您将需要: 1. 暂停动画并知道停止角度后,将 css 设置为 animation:none,transition:transform 5s,transform: rotate( currentAngle deg) 2. 然后稍等一下并设置 transform: rotate(175deg )
  • 为什么我需要“稍等”?我认为这实际上一定是两个浏览器问题的根源。似乎在动画方面没有立即应用 CSS 样式。这是为什么?如果元素在应用新动画样式时已经被动画化(在这种情况下可能会产生冲突),这将是有意义的(需要一段时间才能应用新的动画相关样式)。但是,在我的情况下,我正在等待当前动画(恒定动画)完成,然后再应用新动画(旋转到 175 度)。
  • 在这种情况下需要稍等一下,因为您需要在更改转换动画的属性之前设置转换(在这种情况下为转换)

标签: css animation safari rotation transform


【解决方案1】:

更好的方法:

混合关键帧动画和过渡是不可靠的,并且在不同的浏览器中表现不同...... 所以我建议使用

requestAnimationFrame

在这里看到它的工作:http://jsfiddle.net/mc3v6xsw/5/

并在此处查看文档:https://developer.mozilla.org/en-US/docs/Web/API/window.requestAnimationFrame

这适用于 chrome、safari、firefox 和 ie10

function constantRotation(timestamp){
    if(startTime==null)
        startTime=timestamp;
    var delta = timestamp-startTime;
    degrees = (360/fullRotationTime)*delta;
    $element.css({
             'transform': 'rotate(' + degrees + 'deg)',
             '-webkit-transform': 'rotate(' + degrees + 'deg)'        
    });
    rotationAnimation=window.requestAnimationFrame(constantRotation);
}
var rotationAnimation=window.requestAnimationFrame(constantRotation);

你可以停止它

cancelAnimationFrame(rotationAnimation);

第一次尝试:

这适用于 chrome:http://jsfiddle.net/p08L6ndo/

我做了什么: 暂停后:

 $element.css({
     'transform': 'rotate(' + degrees + 'deg)',
     '-webkit-transform': 'rotate(' + degrees + 'deg)',
     'animation':'none',
     'transition':'transform 2s'
 });

又过了 3 秒:

 $element.css({
     '-webkit-transform': 'rotate(175deg)',
     'transform':'rotate(175deg)'
 });

【讨论】:

  • 这适用于 Chrome,但恐怕它仍然无法在 Safari 上运行。
  • 看起来在 Safari 上将动画设置为 none 并不会让元素在稍后旋转到 175 度时实际进行动画处理。这就是为什么它在没有任何动画的情况下旋转到 175 度。正如您会在我的帖子中注意到的那样,在我的脚本中,情况正好相反,即它没有在 Chrome 上进行动画处理,而是在 Safari 中进行了动画处理(但不是在角度自行设置为 0 之前...... )。我们似乎无法让它同时适用于两种浏览器,这很奇怪,因为它们都使用webkit
  • nop...错了...动画用于关键帧动画,过渡是不同的机制
  • @SproutCoder 我编辑了我的答案,现在它适用于所有现代浏览器
猜你喜欢
  • 2012-05-24
  • 1970-01-01
  • 2015-03-05
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 2011-10-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多