Skip to content

Instantly share code, notes, and snippets.

@whizkydee
Created October 24, 2018 14:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whizkydee/36a4a7df79e37d292492400476ea4b54 to your computer and use it in GitHub Desktop.
Save whizkydee/36a4a7df79e37d292492400476ea4b54 to your computer and use it in GitHub Desktop.
WIP to write SVG data to Canvas
import React from 'react';
import Store from '../store';
import EventBus from '../eventBus';
import Selection from './selection';
import { getShapeRect } from '../utils';
import { renderToStaticMarkup } from 'react-dom/server.browser';
export default class WhiteBoard extends React.Component {
constructor() {
super();
Store.subscribe(() => {
this.setState({ data: Store.data });
});
this.state = {
data: Store.data,
svgData: '<svg></svg>'
};
this.pressed = false;
}
canvasRef = React.createRef();
componentDidMount() {
document.addEventListener('mousedown', this.mouseDown.bind(this));
document.addEventListener('mousemove', this.mouseMove.bind(this));
document.addEventListener('mouseup', this.mouseUp.bind(this));
document.addEventListener('keydown', this.keyDown.bind(this));
window.addEventListener('resize', this.onResize.bind(this));
this.onResize();
this.setState({ data: Store.data });
}
onResize() {
this.rect = this.canvasRef.current.getBoundingClientRect();
}
mousePos(e) {
let round = 2;
return {
x: round * Math.round(e.clientX / round) - this.rect.left,
y: round * Math.round(e.clientY / round) - this.rect.top
};
}
_insideRect(rect, point) {
return (
point.x > rect.left &&
point.x < rect.right &&
point.y > rect.top &&
point.y < rect.bottom
);
}
mouseDown(e) {
if (this._insideRect(this.rect, { x: e.clientX, y: e.clientY })) {
this.pressed = true;
EventBus.emit(EventBus.START_PATH, this.mousePos(e));
}
}
mouseMove(e) {
if (this.pressed) {
EventBus.emit(EventBus.MOVE_PATH, this.mousePos(e));
}
}
mouseUp(e) {
this.pressed = false;
EventBus.emit(EventBus.END_PATH, this.mousePos(e));
this.writeSVGToCanvas(this.state.svgData);
}
preventContextMenu = event => {
event.preventDefault();
return false;
};
keyDown(e) {
switch (e.keyCode) {
case 27: // escape
EventBus.emit(EventBus.UNDO);
break;
case 82: // KeyR
EventBus.emit(EventBus.REDO);
break;
default: // do nothing.
}
}
onMove(shape) {
return move => {
EventBus.emit(EventBus.MOVE, { shape, move });
};
}
createFakeSVG(shapes, current, selection) {
console.log('Hello from fake svg');
const svgData = renderToStaticMarkup(
<svg>
{shapes}
{current}
{selection}
</svg>
);
this.setState({ svgData });
}
writeSVGToCanvas(data) {
data = encodeURIComponent(data);
const ctx = this.canvasRef.current.getContext('2d');
const img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = 'data:image/svg+xml,' + data;
}
renderStuff() {
const data = this.state.data;
let selection = null;
const shapes = data.shapes.map((shape, i) => {
if (shape.selected) {
selection = (
<Selection rect={getShapeRect(shape)} move={this.onMove(shape)} />
);
}
return <shape.class key={i} path={shape.path} color={shape.color} />;
});
let current = null;
if (data.mouseTracker && data.mouseTracker.class) {
current = (
<data.mouseTracker.class
color={data.mouseTracker.color}
path={data.mouseTracker.path}
/>
);
}
this.createFakeSVG(shapes, current, selection);
}
render() {
return (
<canvas
id="whiteBoard"
ref={this.canvasRef}
width={this.props.width}
height={this.props.height}
onContextMenu={this.preventContextMenu}
/>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment