首页 文章

CSS3动画的Javascript降级解决方案

提问于
浏览
5

我一直在为iPad应用程序创建一些小型胖客户端JavaScript应用程序,它们在UIWebview中加载相关应用程序 . 我现在正在使用跨浏览器,需要使用JavaScript为CSS动画和过渡添加一些后备 .

我的webkit特定实现使用CSS类用于所有动画/转换,其中开始和结束状态在设计时已知,使用javascript中的add / remove类并使用相关的webkitTransitionEnd / webkitAnimationEnd事件 .

对于“动态”过渡,我有一个简单的“动画”功能,它只是将样式属性应用于相关元素 .

我想保留内部API,通过简单的添加/删除类等,尽可能地将转换应用到当前实现 . 我通常有一个应用程序的CSS和js文件(都缩小了) .

所以有几个问题/点我会感激任何输入:

  • IE7 / 8问题 - IE9.js

  • 动态添加供应商特定的前缀 - 到目前为止找到'jquery.css3finalize' .

  • 过渡到类:'jquery.animateToClass' - 似乎每次应用类时都会搜索样式表 - 是否应该在进一步的查找中缓存相关的类?这是缓慢的/资源饥饿的吗?

  • 对于'@keyframe'动画:我想要一个javascript对象'表示'每个CSS3动画的关键帧 . 因此,将类传递给'doAnimationWithClass'函数将使用普通的css3动画(如果在浏览器中可用),但如果不是,它会将'对象版本'传递给使用css3过渡(如果可用)链接每个关键帧过渡的函数或jQuery.animate(或等效的),最终得出相同的结果 .

例如:

CSS:

@-webkit-keyframes an-animation {
  0% { opacity: 0; }
  50% { opacity: 1; }
  100% { opacity: 0; }
}

.an-animation {
  -webkit-animation-name: an-animation;
  -webkit-animation-duration: 1s;
  -webkit-animation-timing-function: linear;
  -webkit-animation-iteration-count: 2;
}

JS:

var animations = {
    an-animation: {
      keyframes: [
      { 
        duration: '',
        timing: 'linear',
        props: {
          opacity: 0
        }
      },
      { 
        duration: '0.5s',
        timing: 'linear',
        props: {
          opacity: 1
        }
      },
      { 
        duration: '0.5s',
        timing: 'linear',
        props: {
          opacity: 0
        }
      }
    ]
  }
};

var animationClasses = [
  an-animation: {
    name: 'an-animation';
    duration: '1s';
    timing: 'linear';
    count: 2;
  }
];

function doAnimationWithClass(className) {
  if (modernizer.cssanimations) {
    //normal implementation
  }
  else {
    //lookup class in animationclasses
    //lookup relevant animation object in animationHash
    //pass to animation chaining function
  }
}

animationHash等的创建可以在客户端完成,也可以在设计时创建(使用批处理/构建文件) .

任何想法或指向已经以更明智的方式做到这一点的图书馆的人都会受到赞赏 .

3 回答

  • 1

    恩,那就对了 . 您需要将关键帧设置传输到js对象 . 我认为css动画和关键帧是一种更好的编写动画的方法 . JS动画方式很难维护 . 这是我的解决方案 . 我还写了一个小工具,用于将css关键帧转换为js对象(css keyframes to js object) .

    var myFrame = {
      '0%': {
        left: 0,
        top: 0
      },
      '25%': {
        left: 100,
        top: 100
      },
      '50%': {
        left: 0,
        top: 300
      },
      '100%': {
        left: 0,
        top: 0
      }
    };
    
    var keyframes = {
      set: function($el, frames, duration) {
        var animate;
        animate = function() {
          var spendTime;
          spendTime = 0;
          $.each(frames, function(idx, val) {
            var stepDuration, stepPercentage;
            stepPercentage = idx.replace('%', '') / 100;
            stepDuration = duration * stepPercentage - spendTime;
            $el.animate(val, stepDuration);
            return spendTime += stepDuration;
          });
          return setTimeout(animate, duration);
        };
        return animate();
      }
    };
    
    keyframes.set($('#mydiv'), myFrame, 2000);
    
  • 2
  • 1

    布莱克宾,你回答完美地服务于我 . 我添加了缓动选项,在视差星域(见CSS parallax background of stars)中实现ie8的jquery后备,如下所示:

    var animations = {
        'STAR-MOVE': {
            '0%': {
                'background-position-x': '5%',
                'background-position-y': '5%'
            },
            '100%': {
                'background-position-x': '1300%',
                'background-position-y': '600%'
            }
        }
    };
    
    var keyframes = {
      set: function($el, frames, duration, easing) {
        var animate;
        animate = function() {
          var spendTime;
          spendTime = 0;
          $.each(frames, function(idx, val) {
            var stepDuration, stepPercentage;
            stepPercentage = idx.replace('%', '') / 100;
            stepDuration = duration * stepPercentage - spendTime;
            $el.animate(val, stepDuration, easing);
            return spendTime += stepDuration;
          });
          return setTimeout(animate, duration);
        };
        return animate();
      }
    };
    
    keyframes.set($('.midground'), animations['STAR-MOVE'], 150000,'linear');
    keyframes.set($('.foreground'), animations['STAR-MOVE'], 100000,'linear');
    

相关问题