• d3 使用记录: 插值


    插值:

      插值有很多种实现, 常用的如线性插值; 插值的概念适用于大多数场景
        如动画,通过计算出每一帧的形状, 位置, 绘制出逐帧画面
           曲线,通过插值, 计算出位置点, 链接样条可以得到近似曲线
     
    一个简易实现
    function ease(start, end) {
        var generate = null,
            dis = end - start,
            k = 0;
        return {
            step: function(k) {
                k = typeof generate === 'function' ? generate(k) : k;
                return k * dis + start
            },
            use: function(fn) {
                generate = fn
                 return this
            }
        }
    }
    function linear(t) {
        return t
    };
    function easeInOut(k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k;
        }
        return - 0.5 * (--k * (k - 2) - 1);
    }
    var ins0 = ease(10, 100).use(linear);
    var ins1 = ease(10, 100).use(easeInOut);
    ins0.step(0.1);  // 19
    ins0.step(0.2);  // 28
    ins1.step(0.1);  // 11.8
    ins1.step(0.2);  // 17.2

    d3 的插值不仅局限于数值, d3提供了很多插值的便捷方法, 究其原理都是一样的。

    interpolateNumber: 数值的线性插值, 如: d3.interpolateNumber(10, 100)(0.5); // 55
    interpolateRgb: 对 rgba 四个属性值的线性插值, 如: d3.interpolateRgb('green', 'rgba(100, 20, 10, 0.8)')(0.5); // rgba(50, 74, 5, 0.9)
    interpolateString: 对两个字符串中出现的数值 的线性插值, 如: d3.interpolateString('px23', 'aa46')(0.5); // aa34.5
    interpolateArray: 对两个数组中同位的值进行线性插值, 如: d3.interpolateArray([10, 8], [60, 20, 36])(0.5); // [35, 14, 36]
    ...
     
     
    关键还是看插值函数。以下摘自 tween.js 中二次插值算法的实现:
        Quadratic: {
         // 从慢到快
            In: function (k) {
    
                return k * k;
    
            },
         // 从快到慢
            Out: function (k) {
    
                return k * (2 - k);
    
            },
          // 从慢到快再从快衰减到慢, 并且相对中心点对称
            InOut: function (k) {
    
                if ((k *= 2) < 1) {
                    return 0.5 * k * k;
                }
    
                return - 0.5 * (--k * (k - 2) - 1);
    
            }
    
        },

    不便上图, 简单对比一下吧

    function Qin(k) {
        return k * k;
    }
    function Qout(k) {
        return k * (2 - k);
    }
    function QInOut(k) {
        if ((k *= 2) < 1) {
            return 0.5 * k * k;
        }
        return - 0.5 * (--k * (k - 2) - 1);
    }
    
    var arr1 = [], arr2 = [], arr3 = [];
    for (var i = 0; i <=10; i++) {
      arr1.push(Qin(i / 10).toFixed(2))
      arr2.push(Qout(i / 10).toFixed(2))
      arr3.push(QInOut(i / 10).toFixed(2))
    }
    
    console.log('In :::', arr1);      // In :::  (11)  ["0.00", "0.01", "0.04", "0.09", "0.16", "0.25", "0.36", "0.49", "0.64", "0.81", "1.00"]
    console.log('Out :::', arr2);     // Out ::: (11)  ["0.00", "0.19", "0.36", "0.51", "0.64", "0.75", "0.84", "0.91", "0.96", "0.99", "1.00"]
    console.log('InOut :::', arr3);   // InOut ::: (11) ["0.00", "0.02", "0.08", "0.18", "0.32", "0.50", "0.68", "0.82", "0.92", "0.98", "1.00"]

    设想一下, 如果把

    Quadratic-in 的点连接起来, 会是一条抛物线 内凹
    Quadratic-out 的点连接起来,会是一条抛物线 外凸
    Quadratic-InOut 的点连接起来, 会是两条抛物线,在中点处平滑连接
    这条曲线的高度值变化正好反映运动的状态
  • 相关阅读:
    C#连接各种数据库的方法
    C#中MDI窗体的一些设置
    Winform子窗体刷新父窗体
    MDI窗体应用程序
    C# 窗体间传值方法大汇总
    mdi父窗体如何向子窗体发送数据
    DataGridView 清空原数据
    js call回调的this指向问题
    sass进阶 @if @else if @else @for循环
    sass的加减乘除
  • 原文地址:https://www.cnblogs.com/liuyingde/p/13786034.html
Copyright © 2020-2023  润新知