From 5d61f0d575cdf8dc64c314a7425bcc12f7ca92e2 Mon Sep 17 00:00:00 2001 From: Andrew McNutt Date: Fri, 8 Sep 2017 15:26:37 -0700 Subject: [PATCH] Allow users to inject custom interpolators --- index.js | 2 +- src/array.js | 5 ++-- src/object.js | 4 +-- src/value.js | 42 ++++++++++++++++++++------- test/custom-interpolators-test.js | 47 +++++++++++++++++++++++++++++++ 5 files changed, 84 insertions(+), 16 deletions(-) create mode 100644 test/custom-interpolators-test.js diff --git a/index.js b/index.js index f1d1687..2d62147 100644 --- a/index.js +++ b/index.js @@ -1,4 +1,4 @@ -export {default as interpolate} from "./src/value"; +export {default as interpolate, customInterpolate} from "./src/value"; export {default as interpolateArray} from "./src/array"; export {default as interpolateBasis} from "./src/basis"; export {default as interpolateBasisClosed} from "./src/basisClosed"; diff --git a/src/array.js b/src/array.js index 2d4e4cc..d467de5 100644 --- a/src/array.js +++ b/src/array.js @@ -1,6 +1,6 @@ -import value from "./value"; +import interpolate from "./value"; -export default function(a, b) { +export default function(a, b, value = interpolate) { var nb = b ? b.length : 0, na = a ? Math.min(nb, a.length) : 0, x = new Array(na), @@ -9,7 +9,6 @@ export default function(a, b) { for (i = 0; i < na; ++i) x[i] = value(a[i], b[i]); for (; i < nb; ++i) c[i] = b[i]; - return function(t) { for (i = 0; i < na; ++i) c[i] = x[i](t); return c; diff --git a/src/object.js b/src/object.js index 42cd4a2..a21c062 100644 --- a/src/object.js +++ b/src/object.js @@ -1,6 +1,6 @@ -import value from "./value"; +import interpolate from "./value"; -export default function(a, b) { +export default function(a, b, value = interpolate) { var i = {}, c = {}, k; diff --git a/src/value.js b/src/value.js index 9d5888c..a858fdd 100644 --- a/src/value.js +++ b/src/value.js @@ -7,14 +7,36 @@ import object from "./object"; import string from "./string"; import constant from "./constant"; -export default function(a, b) { - var t = typeof b, c; - return b == null || t === "boolean" ? constant(b) - : (t === "number" ? number - : t === "string" ? ((c = color(b)) ? (b = c, rgb) : string) - : b instanceof color ? rgb - : b instanceof Date ? date - : Array.isArray(b) ? array - : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object - : number)(a, b); +const defaultInterpolators = { + rgb, + array, + date, + number, + object, + string, + constant +}; + +export function customInterpolate(interpolators) { + var rgb = interpolators.rgb || defaultInterpolators.rgb; + var array = interpolators.array || defaultInterpolators.array; + var date = interpolators.date || defaultInterpolators.date; + var number = interpolators.number || defaultInterpolators.number; + var object = interpolators.object || defaultInterpolators.object; + var string = interpolators.string || defaultInterpolators.string; + var constant = interpolators.constant || defaultInterpolators.constant; + + return function interpolate(a, b) { + var t = typeof b, c; + return b == null || t === "boolean" ? constant(b) + : (t === "number" ? number + : t === "string" ? ((c = color(b)) ? (b = c, rgb) : string) + : b instanceof color ? rgb + : b instanceof Date ? date + : Array.isArray(b) ? array + : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object + : number)(a, b, interpolate); + } } + +export default customInterpolate({}); diff --git a/test/custom-interpolators-test.js b/test/custom-interpolators-test.js new file mode 100644 index 0000000..fc8a0e9 --- /dev/null +++ b/test/custom-interpolators-test.js @@ -0,0 +1,47 @@ +var tape = require("tape"), + hcl = require('../').interpolateHcl, + color = require("d3-color"), + customInterpolate = require("../").customInterpolate; + +tape("customInterpolate(interpolators) uses a custom interpolator to ignore some object keys", function(test) { + var ignore = {color: true}; + var ignoreKeyObjectInterpolator = function(a, b, value) { + var i = {}, + c = {}, + k; + + if (a === null || typeof a !== "object") a = {}; + if (b === null || typeof b !== "object") b = {}; + + for (k in b) { + if (k in a && !(k in ignore)) { + i[k] = value(a[k], b[k]); + } else { + c[k] = b[k]; + } + } + + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; + } + + var interpolate = customInterpolate({object: ignoreKeyObjectInterpolator}); + var i = interpolate({color: "red", x: 1, y: 2}, {color: "red", x: 3, y: 2}); + test.deepEqual(i(0.5), {color: "red", x: 2, y: 2}); + + test.end(); +}); + +tape("customInterpolate(interpolators) swaps color interpolators", function(test) { + var interpolate = customInterpolate({rgb: hcl}); + var i = interpolate(color.hcl(10, 50, 50), color.hcl(350, 50, 50)); + test.equal(i(0.0), "rgb(196, 79, 106)"); + test.equal(i(0.2), "rgb(196, 79, 112)"); + test.equal(i(0.4), "rgb(195, 79, 118)"); + test.equal(i(0.6), "rgb(193, 79, 124)"); + test.equal(i(0.8), "rgb(191, 80, 129)"); + test.equal(i(1.0), "rgb(189, 81, 135)"); + test.end(); +});