Skip to content

Instantly share code, notes, and snippets.

@sullyj3
Created August 17, 2019 06:27
Show Gist options
  • Save sullyj3/939133639247aa9c44a2267693a88e5b to your computer and use it in GitHub Desktop.
Save sullyj3/939133639247aa9c44a2267693a88e5b to your computer and use it in GitHub Desktop.
/**
* Observable version of the above
*/
function drawRectsObservable() {
// implement this function!
const svg = document.getElementById("drawRects")!,
mousedown = Observable.fromEvent<MouseEvent>(svg, 'mousedown'),
mousemove = Observable.fromEvent<MouseEvent>(svg, 'mousemove'),
mouseup = Observable.fromEvent<MouseEvent>(svg, 'mouseup'),
svgBounds = svg.getBoundingClientRect(),
svgLeft = svgBounds.left,
svgTop = svgBounds.top,
mouseLocToPoint = ({clientX, clientY}: any) => ({x:clientX, y:clientY}),
svgBoxCoords = ({x, y}: Point) => ({x: x-svgLeft, y: y-svgTop});
interface RectGeometry {
rectLeft: number
rectTop: number
rectWidth: number
rectHeight: number
};
const setRectGeometry = (rect: Elem, geom: RectGeometry) => {
const {rectLeft, rectTop, rectWidth, rectHeight} = geom;
rect
.attr('x', String(rectLeft))
.attr('y', String(rectTop))
.attr('width', String(rectWidth))
.attr('height', String(rectHeight));
};
mousedown
.map(svgBoxCoords)
.flatMap(({x, y}) => {
const [x0, y0] = [x, y];
const rect = new Elem(svg, 'rect');
const initialGeom = {
rectLeft: x0,
rectTop: y0,
rectWidth: 5,
rectHeight: 5
};
setRectGeometry(rect, initialGeom);
return mousemove
.map(mouseLocToPoint)
.map(svgBoxCoords)
.map(({x, y}) => ({
geom: {
rectLeft: Math.min(x, x0),
rectTop: Math.min(y, y0),
rectWidth: Math.abs(x0 - x),
rectHeight: Math.abs(y0 - y),
},
rect
})).takeUntil(mouseup);
})
.subscribe(({rect, geom}) =>
setRectGeometry(rect, geom));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment