CSS3动画的Javascript降级解决方案

发布于 2024-11-08 06:38:25 字数 2117 浏览 4 评论 0原文

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

我的 webkit 特定实现对所有动画/转换使用 CSS 类,在设计时就知道开始和结束状态,在 javascript 中使用添加/删除类并利用相关的 webkitTransitionEnd/webkitAnimationEnd 事件。

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

我想通过简单的添加/删除类等来保持用于应用转换的内部 API 与当前实现尽可能相似。我通常有一个应用程序的 CSS 和 js 文件(都缩小了)。

因此,有几个问题/要点,我希望您能提供任何意见:

  1. IE7/8 问题 - IE9.js

  2. 动态添加供应商特定前缀 - 到目前为止发现' jquery.css3finalize'。

  3. 转换到类:'jquery.animateToClass' - 似乎每次应用类时都会搜索样式表 - 是否应该在进一步查找时缓存相关类?这很慢/资源匮乏吗?

  4. 对于“@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
  }
}

动画哈希等的创建可以在客户端完成,或者简单地在设计时创建(使用批处理/构建文件)。

任何对已经以更明智的方式做到这一点的图书馆的想法或指示将不胜感激。

I've been creating a number of small thick client JavaScript apps for an iPad app, which loads the relevant app in a UIWebview. I am now making them cross browser and need to incorporate some fallbacks for CSS animations and transitions using JavaScript.

My webkit specific implementation uses CSS classes for all animations/transitions, for which the start and end states are known at design time, using add/remove class in javascript and utilising the relevant webkitTransitionEnd/webkitAnimationEnd events.

For 'dynamic' transitions I have a simple 'animate' function which just applies styling properties to relevant elements.

I would like to keep the internal API for appling transitions as similar as possible to the current implementation by simple adding/removing classes etc. I generally have a CSS and js file (both minified) for an app.

So a few questions/points that I would appreciate any input on:

  1. IE7/8 issues - IE9.js

  2. Dynamically adding vendor specific prefixes - so far found 'jquery.css3finalize'.

  3. Transitioning to a class: 'jquery.animateToClass' - seems to search stylesheet(s) every time a class is applied - should relevant classes be cached on further lookups? Is this slow/resource hungry?

  4. For '@keyframe' animations: I'd like to have a javascript object 'representation' of keyframes of each CSS3 animation. Therefore passing a class to the 'doAnimationWithClass' function would use normal css3 animation if available in the browser but if not it would pass the 'object version' to a function that would chain the each key frame transition using css3 transitions (if available) or jQuery.animate (or equivalent), ultimately arriving at the same result.

So for instance:

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

The creation of animationHash etc could be done client side, or simply created at design time (with a batch/build file).

Any thoughts or pointers to a library that already does this in a more sensible way would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一张白纸 2024-11-15 06:38:25

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

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

Yes, that's right. You need to transfer keyframes setting to js object. I think css animation and keyframe is a better way to write animation. JS animation way is hardly to maintain. Here is my workaround solution. And I also write a small tool for translating css keyframes to js object(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); 
棒棒糖 2024-11-15 06:38:25

Blackbingo,你的回答非常适合我。我添加了缓动选项,以在视差星空中实现 ie8 的 jquery 回退(请参阅 CSS 视差背景星星)像这样:

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

Blackbingo, you answer served to me perfectly. I added the easing option, to implement a jquery fallback for ie8 in a parallax starfield (see CSS parallax background of stars) like this:

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');
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文