Skip to content

Instantly share code, notes, and snippets.

@hshoff
Created April 18, 2017 23:57
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hshoff/661e0e91bd8bd31a507e7ed42be479c5 to your computer and use it in GitHub Desktop.
Save hshoff/661e0e91bd8bd31a507e7ed42be479c5 to your computer and use it in GitHub Desktop.
@vx/brush sketch
import React from 'react';
export default function Brush({ brush }) {
const { start, end, dragging } = brush;
return (
<g className="vx-brush">
{start && dragging &&
<circle
cx={start.x}
cy={start.y}
r={3}
fill='blue'
/>
}
{end && dragging &&
<circle
cx={end.x}
cy={end.y}
r={3}
fill='red'
/>
}
{dragging && end &&
<rect
fill={'rgba(0,0,220,0.4)'}
x={end.x > start.x ? start.x : end.x}
y={end.y > start.y ? start.y : end.y}
width={end.x > start.x ? end.x - start.x : start.x - end.x}
height={end.y > start.y ? end.y - start.y : start.y - end.y}
/>
}
</g>
);
}
import React from 'react';
import withBrush from './withBrush';
import Brush from './Brush';
class BrushChart extends React.Component {
constructor() {
super();
this.handleMouseDown = this.handleMouseDown.bind(this);
this.handleMouseMove = this.handleMouseMove.bind(this);
this.handleMouseUp = this.handleMouseUp.bind(this);
}
handleMouseDown(event) {
event.persist();
const { brushStart } = this.props;
brushStart(this.svg, event);
}
handleMouseMove(event) {
event.persist();
const { brush, brushMove } = this.props;
if (brush.start && brush.dragging) brushMove(this.svg, event);
}
handleMouseUp(event) {
event.persist();
const { brush, brushEnd } = this.props;
if (brush.end) brushEnd(this.svg, event);
}
render() {
const { width, height, brush } = this.props;
return (
<svg
ref={(c) => { this.svg = c; }}
width={width}
height={height}
onMouseDown={this.handleMouseDown}
onMouseMove={this.handleMouseMove}
onMouseUp={this.handleMouseUp}
>
<Brush brush={brush} />
</svg>
);
}
}
export default addBrush(BrushChart);
import { compose, withState, withHandlers } from 'recompose';
export default compose(
withState('brush', 'updateBrush', {
start: undefined,
end: undefined,
dragging: false,
}),
withHandlers({
brushStart: ({ updateBrush }) => (node, event) => {
updateBrush((prevState) => ({
...prevState,
start: getCoordsFromEvent(node, event),
dragging: true,
end: undefined,
}))
},
brushMove: ({ updateBrush }) => (node, event) => {
updateBrush((prevState) => ({
...prevState,
end: getCoordsFromEvent(node, event),
}))
},
brushEnd: ({ updateBrush }) => (node, event) => {
updateBrush((prevState) => ({
...prevState,
dragging: false,
}))
},
})
);
function getCoordsFromEvent(node, event) {
if (!node) return;
const svg = node.ownerSVGElement || node;
if (svg.createSVGPoint) {
let point = svg.createSVGPoint();
point.x = event.clientX;
point.y = event.clientY;
point = point.matrixTransform(node.getScreenCTM().inverse());
return {x: point.x, y: point.y};
}
var rect = node.getBoundingClientRect();
return {
x: event.clientX - rect.left - node.clientLeft,
y: event.clientY - rect.top - node.clientTop
};
}
@hshoff
Copy link
Author

hshoff commented Apr 18, 2017

brush-sketch

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment