Redux

Modifying particles with Redux

by IPWright83

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.7.2/redux.js"></script>
<svg width="960" height="500"></svg>

JavaScript

const nodes = 200;
const width = 960;
const height = 500;

const initState = {};
d3.range(nodes).forEach((d, i) => initState[i] = { xloc: 0, yloc: 0, xvel: 0, yvel: 0 });

const x = d3.scaleLinear().domain([-5, 5]).range([0, width]);
const y = d3.scaleLinear().domain([-5, 5]).range([0, height]);

const circle = d3.select("svg")
								 .selectAll("circle")
                 .data(Object.values(initState)).enter()
                 .append("circle")
                 .attr("cx", 10)
                 .attr("cy", 10)
                 .attr("r", 1);
                 
const reducer = (state = initState, action) => {
	switch(action.type) {
  	case "VELOCITY": {
      const payload = action.payload;
    	const index = payload.i;
      const datum = state[index];
      const newDatum = { 
      	xloc: datum.xloc + datum.xvel,
        yloc: datum.yloc + datum.yvel,
        xvel: datum.xvel + payload.vx,
        yvel: datum.yvel + payload.vy,
      };
      
    	return { 
      	...state, 
        [index]: newDatum 
      };
    }
   	default: return state;
  }
};

const store = Redux.createStore(reducer);
store.subscribe(() => {
	 const data = Object.values(store.getState());
   
	 d3.select("svg")
   	 .selectAll("circle")
     .data(data)
     .attr("transform", function(d) { return "translate(" + x(d.xloc) + "," + y(d.yloc) + ")"; })
     .attr("r", function(d) { return Math.min(1 + 1000 * Math.abs(d.xvel * d.yvel), 10); });
});

d3.timer(function() {
	const data = Object.values(store.getState());
  data.forEach(function(d, i) {
  	const vx = 0.04 * (Math.random() - .5) - 0.05 * d.xvel - 0.0005 * d.xloc;
    const vy = 0.04 * (Math.random() - .5) - 0.05 * d.yvel - 0.0005 * d.yloc;
    const payload = { i, vx, vy };
    store.dispatch({ type: "VELOCITY", payload })
  })
});;