Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

为数值变化添加过渡

  页面上经常要显示变化的数值,如果每次都直接修改文本,看起来就会比较生硬。CSS 动画本身又不支持文本的过渡效果,最终还得通过 JS 来实现。这个看似简单的东西如果考虑上各种临界情况的话实现起来还是挺麻烦的。下面我只实现了对整数的过渡效果。
<script>
var transition;
void function() {
  // 动画帧数
  var FRAMESNUM = 30;
  // 动画主过程
  var animate = function(node) {
    // 计算当前帧应增加的数值并增加到文本节点上
    var value = +node.data;
    var diff = node.destination - value;
    var result = node.progress ? Math.round(diff / node.progress) : diff;
    node.data = value + result; 
    // 如果进度条有剩余则请求下一帧,否则结束动画
    if(node.progress--) {
      setTimeout(function() {
        animate(node);
      }, 1000 / 60);
    } else {
      node.runing = false;
    }
  };
  // 接口函数
  transition = function(element, value) {
    // 获取或创建文本节点
    var node = element.childNodes[0];
    if(!(node && 'destination' in node && 'progress' in node)) {
      node = document.createTextNode(element.innerHTML.match(/-?\d+/) * 1);
      element.innerHTML = '';
      element.insertBefore(node, element.firstChild);
    }
    // 初始化或重置动画参数
    node.destination = value;
    node.progress = FRAMESNUM;
    // 如果当前是非播放状态则播放过渡效果
    if(!node.runing) {
      node.runing = true;
      animate(node);
    }
  };
}();

var a = 100;
</script>

<button onclick="transition(this, a *= 2)">100</button>
  考虑在一次动画完成之前就再次做数值更新,于是将动画播放以帧的形式计算,如果有更新则重置动画时间轴并重新计算帧,这样就不会因为多次执行动画而造成不流畅了。
  上面的例子只支持整数,如果需要小数支持的话需要稍微做个调整。但能做的只有固定精度的小数,如果小数位数是不固定的,那么使用这个过渡效果也会变得很奇怪。所以在我脑中的设定是这个效果不能支持不固定精度的小数。
  最后一个坑是上面的代码直接给 DOM 节点加了自定义属性。这个问题我在前天的文章「使用 UUID 解决 DOM 节点数据存储问题」中就已经纠结过。上面的代码只是图方便而直接在 DOM 节点上操作自定义属性,如果需要一个更优雅的实现应该改用 UUID 来存。
  上面的那段代码只是随手写的,还不是产品级的,直接复制使用前请仔细想想有没有坑。也许过段时间会封装成一个产品级的代码发到 Github 上吧。现在真懒得做这些。
网名:
34.203.245.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^