question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Interpolator function

See original GitHub issue

I am trying to animate an SVG path element’s d attribute using d3.interpolate. It looks like react-motion only supports numerical values at the moment, and it also looks like there isn’t a way to set a custom interpolator function. Any plants to fix either of these?

Issue Analytics

  • State:open
  • Created 8 years ago
  • Comments:22 (5 by maintainers)

github_iconTop GitHub Comments

6reactions
tannerlinsleycommented, Mar 7, 2017

I was able to work up a prototype abstraction of <Motion /> to work with d3-interpolators. By no means is it optimized, but it’s a pretty cool start. It works by mapping non-numeric value changes to auto-incrementing integers, then it coerces those integers back to a percentage between the old and new value. Then it applies the d3-interpolator of choice behind the scenes, defaulting to the standard auto interpolator.

I would love to get some feedback on this, as it seems like this could be a start to supporting non-numeric values.

Right now I’m using it to interpolate colors, paths, and strings in d3.

(Update to support interrupted updates)

import React from 'react'
import { Motion, spring } from 'react-motion'
import { interpolate } from 'd3-interpolate'

export default React.createClass({
  oldValues: {},
  newInters: {},
  currentStepValues: {},
  stepValues: {},
  stepInterpolators: {},
  render () {
    const {
      style,
      children,
      ...rest
    } = this.props

    const MagicSpring = (value, config) => {
      if (typeof value !== 'number') {
        return {
          value,
          config,
          interpolator: (config && config.interpolator) ? config.interpolator : interpolate
        }
      }
      return spring(value, config)
    }

    const resolvedStyle = style(MagicSpring)
    for (let key in resolvedStyle) {
      if (
        // If key is a non-numeric interpolation
        resolvedStyle[key] &&
        resolvedStyle[key].interpolator
      ) {
        // Make sure the steps start at 0
        this.currentStepValues[key] = this.currentStepValues[key] || 0
        if (
          // And the value has changed
          typeof this.newInters[key] === 'undefined' ||
          resolvedStyle[key].value !== this.newInters[key].value
        ) {
          // Save the new value
          this.newInters[key] = resolvedStyle[key]

          // Increment the stepInterValue for this key by 1
          this.stepValues[key] = this.currentStepValues[key] + 1

          // Set up the new interpolator
          this.stepInterpolators[key] = this.newInters[key].interpolator(
            this.oldValues[key],
            this.newInters[key].value
          )
        }
        // Return the spring with the destination stepValue and spring config
        resolvedStyle[key] = spring(this.stepValues[key], this.newInters[key].config)
        // console.log(resolvedStyle[key])
      }
    }

    return (
      <Motion
        {...rest}
        style={resolvedStyle}
      >
        {values => {
          const newValues = {}
          for (let key in values) {
            if (this.stepValues[key]) {
              // Save the currentStepValue
              this.currentStepValues[key] = values[key]
              // Figure the percentage
              let percentage = this.currentStepValues[key] - this.stepValues[key] + 1
              // Save the current value and replace the value in the interpolated object
              this.oldValues[key] = newValues[key] = this.stepInterpolators[key](percentage)
            }
          }
          return children({
            ...values,
            ...newValues
          })
        }}
      </Motion>
    )
  }
})

mar-07-2017 16-50-48

1reaction
tannerlinsleycommented, Mar 7, 2017

This would be great to have. I think I would lean way more towards an interpolate key for spring options.

I would also wager that most people would love to be able to just drop in compatible interpolators as plugins at a higher level and have them work out of the box. D3 has tons of interpolators available, we could honestly just make an i/o to utilize them.

As easy as it would be to provide the interpolator per spring config, it would be so much cooler if we were able to handle interpolators automagically. Imagine utilizing a similar algorithm as https://github.com/d3/d3-interpolate#interpolate, using d3 interpolate itself haha!

Thoughts? This is a large weakness of React-Motion that is talked about most often. If we could nail this, I think you could have a lot of people considering its usage in many other scenarios.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Interpolation - Wikipedia
In the mathematical field of numerical analysis, interpolation is a type of estimation, a method of constructing (finding) new data points based on...
Read more >
Interpolation Function - an overview | ScienceDirect Topics
A spatial interpolation, or blending function is assumed for the purpose of relating the quantity of interest within the element in terms of...
Read more >
Linear interpolation calculator
Online calculator for linear interpolation and extrapolation. Given two (x, y) pairs and an additional x or y, compute the missing value.
Read more >
Interpolation methods - Paul Bourke
Linear interpolation results in discontinuities at each point. Often a smoother interpolating function is desirable, perhaps the simplest is cosine ...
Read more >
Interpolator (Java SE 10 & JDK 10 ) - Oracle Help Center
Before calculating the interpolated value, the fraction is altered according to the function defined in curve() . Parameters: startValue - the first data...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found