Doodle3D-Core/src/reducer/d3/tools/twistReducer.js

95 lines
2.3 KiB
JavaScript

import update from 'react-addons-update';
import { Utils } from '@doodle3d/cal';
import * as actions from '../../../actions/index.js';
import * as d3Tools from '../../../constants/d3Tools';
import { SHAPE_TYPE_PROPERTIES } from '../../../constants/shapeTypeProperties.js';
// import createDebug from 'debug';
// const debug = createDebug('d3d:reducer:twist');
const CHANGE_FACTOR = 0.002;
const maxTwist = 1;
export default function twistReducer(state, action) {
// if (action.log !== false) debug(action.type);
switch (action.category) {
case actions.CAT_SELECTION:
return initTwist(state);
default:
break;
}
switch (action.type) {
case actions.D3_CHANGE_TOOL:
return initTwist(state);
case actions.TWIST_START:
case actions.TWIST_END:
state = update(state, {
d3: {
twist: {
active: { $set: action.type === actions.TWIST_START }
}
}
});
return state;
case actions.TWIST:
const delta = action.delta.x * 1 * CHANGE_FACTOR;
state = update(state, {
d3: {
twist: {
rotation: { $set: state.d3.twist.rotation + delta }
}
}
});
for (const selectionData of state.selection.objects) {
const shapeData = state.objectsById[selectionData.id];
if (!SHAPE_TYPE_PROPERTIES[shapeData.type].tools[d3Tools.TWIST]) continue;
const twist = Utils.MathExtended.clamb(shapeData.twist + delta, -maxTwist, maxTwist);
// debug(UID, ': twist: ', shapeData.twist, '>', twist);
state = update(state, {
objectsById: {
[shapeData.UID]: { twist: { $set: twist } }
}
});
}
return state;
default:
return state;
}
}
function initTwist(state) {
const twist = getInitialTwist(state);
return update(state, {
d3: {
twist: {
rotation: { $set: twist },
active: { $set: false }
}
}
});
}
function getInitialTwist(state) {
const selectedObjects = state.selection.objects.map(({ id }) => state.objectsById[id]);
let twist;
if (selectedObjects.length === 0) {
twist = 0;
} else if (selectedObjects.length === 1) {
// one shape selected: use shape's twist
const [selectedObject] = selectedObjects;
twist = selectedObject.twist;
} else {
twist = 0;
}
return twist;
}