fabric-whiteboard
This is a whiteboard react component base on fabricjs. A star will be grateful!
ScreenShots
Features
- Freely drag the palette.
- Arrow,Square,Ellipse,Line,DotLine,Select,Erase,RayPen modes support.
- Text input mode support
- Get|Set all objects in json
- Pick color of brush
- Change thickness of brushsss
- Event of single object like new、move、scale、delete、modify
- Operations of single object like new、move、scale、delete、modify
- Animations
- support custom toolbar outside of whiteboard
Instal
$ npm install fabric-whiteboard # or $ yarn add fabric-whiteboard
Usage
.App .toolbar .toolbar-button
pen: '{"mode":"pen","obj":{"type":"path","version":"3.6.3","originX":"left","originY":"top","left":183,"top":548,"width":176,"height":24,"fill":null,"stroke":"#f44336","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"round","strokeDashOffset":0,"strokeLineJoin":"round","strokeMiterLimit":10,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"path":[["M",184,548.998],["Q",184,549,184,549.5],["Q",184,550,184,551],["Q",184,552,184,553],["Q",184,554,184,554.5],["Q",184,555,184,556],["Q",184,557,184.5,557.5],["Q",185,558,185,558.5],["Q",185,559,185.5,559],["Q",186,559,186,559.5],["Q",186,560,186,560.5],["Q",186,561,186.5,561],["Q",187,561,187.5,561.5],["Q",188,562,188.5,562],["Q",189,562,189.5,562],["Q",190,562,191.5,562],["Q",193,562,194.5,562.5],["Q",196,563,201,564],["Q",206,565,208.5,565],["Q",211,565,220,566],["Q",229,567,230.5,567],["Q",232,567,237,567],["Q",242,567,246.5,567],["Q",251,567,252.5,567],["Q",254,567,256.5,567],["Q",259,567,260.5,567],["Q",262,567,263.5,567],["Q",265,567,269,567],["Q",273,567,273.5,567],["Q",274,567,277,566],["Q",280,565,281,564.5],["Q",282,564,282.5,563.5],["Q",283,563,283.5,562.5],["Q",284,562,284,561],["Q",284,560,284.5,560],["Q",285,560,285,559.5],["Q",285,559,285,558.5],["Q",285,558,285,557.5],["Q",285,557,285,556.5],["Q",285,556,285,555.5],["Q",285,555,285,553.5],["Q",285,552,284.5,551.5],["Q",284,551,283.5,551],["Q",283,551,282.5,551],["Q",282,551,282,550.5],["Q",282,550,281.5,550],["Q",281,550,280.5,550],["Q",280,550,279.5,550],["Q",279,550,278.5,550],["Q",278,550,277.5,550],["Q",277,550,276.5,550.5],["Q",276,551,275.5,552.5],["Q",275,554,275,554.5],["Q",275,555,274.5,555.5],["Q",274,556,274,557],["Q",274,558,274,559],["Q",274,560,274,560.5],["Q",274,561,274,561.5],["Q",274,562,274,562.5],["Q",274,563,274,564],["Q",274,565,274.5,565.5],["Q",275,566,276,567],["Q",277,568,278,568.5],["Q",279,569,279.5,569.5],["Q",280,570,281,570],["Q",282,570,283,570.5],["Q",284,571,285,571],["Q",286,571,287,571.5],["Q",288,572,288.5,572],["Q",289,572,291,572.5],["Q",293,573,294,573],["Q",295,573,300,573],["Q",305,573,307.5,573],["Q",310,573,313,573],["Q",316,573,325.5,571],["Q",335,569,341,568.5],["Q",347,568,351.5,567.5],["Q",356,567,357.5,567],["Q",359,567,359,566.5],["Q",359,566,359.5,566],["L",360.002,566]]}}' line: '{"mode":"line","obj":{"type":"line","version":"3.6.3","originX":"left","originY":"top","left":87,"top":62,"width":150,"height":0,"fill":"rgb(0,0,0)","stroke":"#f44336","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"x1":-75,"x2":75,"y1":0,"y2":0}}' dotLine: '{"mode":"dotline","obj":{"type":"line","version":"3.6.3","originX":"left","originY":"top","left":82,"top":107,"width":156,"height":0,"fill":"rgb(0,0,0)","stroke":"#9c27b0","strokeWidth":2,"strokeDashArray":[3,2],"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"x1":-78,"x2":78,"y1":0,"y2":0}}' arrow: '{"mode":"arrow","obj":{"type":"path","version":"3.6.3","originX":"left","originY":"top","left":305,"top":38,"width":97,"height":93,"fill":"rgba(255,255,255,0)","stroke":"#2196f3","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"path":[["M",306,39],["L",403,132],["M",395.0511896518709,115.85018842062],["L",403,132],["L",386.52995922141145,124.73792338572292]]}}' text: '{"mode":"text","obj":{"type":"textbox","version":"3.6.3","originX":"left","originY":"top","left":211,"top":203,"width":150,"height":27.12,"fill":"#f44336","stroke":null,"strokeWidth":1,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"text":"adsfadsf","fontSize":24,"fontWeight":"normal","fontFamily":"Times New Roman","fontStyle":"normal","lineHeight":1.16,"underline":false,"overline":false,"linethrough":false,"textAlign":"left","textBackgroundColor":"","charSpacing":0,"minWidth":20,"splitByGrapheme":false,"styles":{}}}' rectangle: '{"mode":"rectangle","obj":{"type":"path","version":"3.6.3","originX":"left","originY":"top","left":319,"top":206,"width":141,"height":109,"fill":"rgba(255, 255, 255, 0)","stroke":"#2196f3","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"path":[["M",319,206],["L",460,206],["L",460,315],["L",319,315],["L",319,206],["z"]]}}' triangle: '{"mode":"triangle","obj":{"type":"triangle","version":"3.6.3","originX":"left","originY":"top","left":120,"top":286,"width":83.85,"height":75,"fill":"rgba(255,255,255,0)","stroke":"#2196f3","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0}}' circle: '{"mode":"circle","obj":{"type":"circle","version":"3.6.3","originX":"left","originY":"top","left":172,"top":439,"width":89.81,"height":89.81,"fill":"rgba(255, 255, 255, 0)","stroke":"#2196f3","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"radius":44.90267252625394,"startAngle":0,"endAngle":6.283185307179586}}' ellipse: '{"mode":"ellipse","obj":{"type":"ellipse","version":"3.6.3","originX":"center","originY":"center","left":328,"top":392,"width":142,"height":98,"fill":"rgba(255, 255, 255, 0)","stroke":"#2196f3","strokeWidth":2,"strokeDashArray":null,"strokeLineCap":"butt","strokeDashOffset":0,"strokeLineJoin":"miter","strokeMiterLimit":4,"scaleX":1,"scaleY":1,"angle":0,"flipX":false,"flipY":false,"opacity":1,"shadow":null,"visible":true,"clipTo":null,"backgroundColor":"","fillRule":"nonzero","paintFirst":"fill","globalCompositeOperation":"source-over","transformMatrix":null,"skewX":0,"skewY":0,"rx":71,"ry":49}}'
{ superprops thisstate = mode: 'select' width: '600px' height: '600px' brushColor: '#f44336' brushThickness: 2 thisrefLeft = undefined thisrefRight = undefined thiscalcBoundsSize = thiscalcBoundsSize thishandleBoundsSizeChange = thishandleBoundsSizeChange thishandleOnModeClick = thishandleOnModeClick thishandleOnBrushColorChange = thishandleOnBrushColorChange thishandleOnBrushThicknessChange = thishandleOnBrushThicknessChange thishandleOnObjectAdded = thishandleOnObjectAdded thishandleOnObjectsModified = thishandleOnObjectsModified thishandleOnObjectsRemoved = thishandleOnObjectsRemoved thishandleOnSelectionCreated = thishandleOnSelectionCreated thishandleOnSelectionUpdated = thishandleOnSelectionUpdated thishandleOnSelectionCleared = thishandleOnSelectionCleared } { this window } { window } { const mode width height brushColor brushThickness = thisstate return <div className="App" id="App"> <div className="whiteboard" id="whiteboard"> <WhiteBoard ref= { thisrefLeft = ref } width=width height=height showToolbar=true enableToolbar=true showBoard=true mode=mode onModeClick=thishandleOnModeClick brushColor=brushColor brushColors= '#f44336' '#e91e63' '#9c27b0' '#673ab7' '#3f51b5' '#2196f3' brushThickness=brushThickness onBrushColorChange=thishandleOnBrushColorChange onBrushThicknessChange=thishandleOnBrushThicknessChange onObjectAdded=thishandleOnObjectAdded onObjectsModified=thishandleOnObjectsModified onObjectsRemoved=thishandleOnObjectsRemoved onSelectionCreated=thishandleOnSelectionCreated onSelectionUpdated=thishandleOnSelectionUpdated onSelectionCleared=thishandleOnSelectionCleared /> <WhiteBoard ref= { thisrefRight = ref } width=width height=height showToolbar=true enableToolbar=false showBoard=true mode=mode brushColor=brushColor brushColors= '#f44336' '#e91e63' '#9c27b0' '#673ab7' '#3f51b5' '#2196f3' brushThickness=brushThickness /> </div> <div className="toolbar" id="toolbar"> <button className="toolbar-button" onClick= { const jsonData = console const domTextarea = document if domTextarea domTextareavalue = JSON } > Get </button> <textarea id="toolbar-textarea"></textarea> <button className="toolbar-button" onClick= { const domTextarea = document if domTextarea && domTextareavalue && domTextareavalue !== '' } > Set </button> <button className="toolbar-button" onClick= { } > Clear </button> </div> <div className="toolbar"> <button className="toolbar-button" onClick= { } > Add Pen </button> <button className="toolbar-button" onClick= { } > Add Line </button> <button className="toolbar-button" onClick= { } > Add DotLine </button> <button className="toolbar-button" onClick= { } > Add Arrow </button> <button className="toolbar-button" onClick= { } > Add Text </button> <button className="toolbar-button" onClick= { } > Add Rectangle </button> <button className="toolbar-button" onClick= { } > Add Triangle </button> <button className="toolbar-button" onClick= { } > Add Circle </button> <button className="toolbar-button" onClick= { } > Add Ellipse </button> </div> </div> } { return const domApp = document const domToolbar = document const domAppStyle = window const domToolbarStyle = window this } { this } { this } { this } { this } { } { } { } { } { } { }