Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions x-pack/plugins/canvas/public/state/actions/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ function getBareElement(el, includeId = false) {

export const elementLayer = createAction('elementLayer');

export const setPosition = createAction('setPosition', (elementId, pageId, position) => ({
pageId,
elementId,
position,
export const setMultiplePositions = createAction('setMultiplePosition', repositionedElements => ({
repositionedElements,
}));

export const flushContext = createAction('flushContext');
Expand Down
69 changes: 37 additions & 32 deletions x-pack/plugins/canvas/public/state/middleware/aeroelastic.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
import { shallowEqual } from 'recompose';
import { aeroelastic as aero } from '../../lib/aeroelastic_kibana';
import { matrixToAngle } from '../../lib/aeroelastic/matrix';
import { identity } from '../../lib/aeroelastic/functional';
import {
addElement,
removeElements,
duplicateElement,
elementLayer,
setPosition,
setMultiplePositions,
fetchAllRenderables,
} from '../actions/elements';
import { restoreHistory } from '../actions/history';
Expand Down Expand Up @@ -65,40 +66,44 @@ const elementToShape = (element, i) => {
};
};

const updateGlobalPositions = (setPosition, { shapes, gestureEnd }, elems) => {
shapes.forEach((shape, i) => {
const elemPos = elems[i] && elems[i].position;
if (elemPos && gestureEnd) {
// get existing position information from element
const oldProps = {
left: elemPos.left,
top: elemPos.top,
width: elemPos.width,
height: elemPos.height,
angle: Math.round(elemPos.angle),
};

// cast shape into element-like object to compare
const newProps = {
left: shape.transformMatrix[12] - shape.a,
top: shape.transformMatrix[13] - shape.b,
width: shape.a * 2,
height: shape.b * 2,
angle: Math.round(matrixToAngle(shape.transformMatrix)),
};

if (1 / newProps.angle === -Infinity) newProps.angle = 0; // recompose.shallowEqual discerns between 0 and -0

if (!shallowEqual(oldProps, newProps)) setPosition(shape.id, newProps);
}
});
const updateGlobalPositions = (setMultiplePositions, { shapes, gestureEnd }, elems) => {
const repositionings = shapes
.map((shape, i) => {
const elemPos = elems[i] && elems[i].position;
if (elemPos && gestureEnd) {
// get existing position information from element
const oldProps = {
left: elemPos.left,
top: elemPos.top,
width: elemPos.width,
height: elemPos.height,
angle: Math.round(elemPos.angle),
};

// cast shape into element-like object to compare
const newProps = {
left: shape.transformMatrix[12] - shape.a,
top: shape.transformMatrix[13] - shape.b,
width: shape.a * 2,
height: shape.b * 2,
angle: Math.round(matrixToAngle(shape.transformMatrix)),
};

if (1 / newProps.angle === -Infinity) newProps.angle = 0; // recompose.shallowEqual discerns between 0 and -0

return shallowEqual(oldProps, newProps)
? null
: { position: newProps, elementId: shape.id };
}
})
.filter(identity);
if (repositionings.length) setMultiplePositions(repositionings);
};

const id = element => element.id;

export const aeroelastic = ({ dispatch, getState }) => {
// When aeroelastic updates an element, we need to dispatch actions to notify redux of the changes
// dispatch(setPosition({ ... }));

const onChangeCallback = ({ state }) => {
const nextScene = state.currentScene;
Expand All @@ -111,7 +116,7 @@ export const aeroelastic = ({ dispatch, getState }) => {
const selectedElement = getSelectedElement(getState());

updateGlobalPositions(
(elementId, position) => dispatch(setPosition(elementId, page, position)),
positions => dispatch(setMultiplePositions(positions.map(p => ({ ...p, pageId: page })))),
nextScene,
elements
);
Expand Down Expand Up @@ -223,7 +228,7 @@ export const aeroelastic = ({ dispatch, getState }) => {
case addElement.toString():
case duplicateElement.toString():
case elementLayer.toString():
case setPosition.toString():
case setMultiplePositions.toString():
const page = getSelectedPage(getState());
const elements = getElements(getState(), page);

Expand All @@ -232,7 +237,7 @@ export const aeroelastic = ({ dispatch, getState }) => {
prevPage !== page || !shallowEqual(prevElements.map(id), elements.map(id));
if (shouldResetState) populateWithElements(page);

if (action.type !== setPosition.toString()) unselectShape(prevPage);
if (action.type !== setMultiplePositions.toString()) unselectShape(prevPage);

break;
}
Expand Down
10 changes: 6 additions & 4 deletions x-pack/plugins/canvas/public/state/reducers/elements.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,12 @@ export const elementsReducer = handleActions(
const { filter, pageId, elementId } = payload;
return assignElementProperties(workpadState, pageId, elementId, { filter });
},
[actions.setPosition]: (workpadState, { payload }) => {
const { position, pageId, elementId } = payload;
return assignElementProperties(workpadState, pageId, elementId, { position });
},
[actions.setMultiplePositions]: (workpadState, { payload }) =>
payload.repositionedElements.reduce(
(previousWorkpadState, { position, pageId, elementId }) =>
assignElementProperties(previousWorkpadState, pageId, elementId, { position }),
workpadState
),
[actions.elementLayer]: (workpadState, { payload: { pageId, elementId, movement } }) => {
return moveElementLayer(workpadState, pageId, elementId, movement);
},
Expand Down