Created
May 30, 2021 16:07
-
-
Save lilbond/b397f29f168715c70c500f864d5324b8 to your computer and use it in GitHub Desktop.
Simple undo/redo sample with paper.js using mouse and keyboard events
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| var EventType = { | |
| mouseUp: 1, | |
| mouseDown: 2, | |
| undo: 3, | |
| redo: 4 | |
| } | |
| function Event(type, payload) { | |
| this.type = type; | |
| this.payload = payload; | |
| } | |
| var id = 0; | |
| function Handler() { | |
| this.undoStack = []; | |
| this.redoStack = []; | |
| this.paths = {}; | |
| this.context = { | |
| op: 'line', | |
| current: undefined | |
| } | |
| this.handle = function(event) { | |
| switch(event.type) { | |
| case EventType.mouseDown: | |
| if (this.context.op === 'line') { | |
| var newPath = new Path() | |
| newPath.strokeColor = 'black' | |
| newPath.add(event.payload.point); | |
| newPath.id = id++; | |
| this.undoStack.push({"type": 'addPath', 'id': newPath.id}); | |
| this.paths[newPath.id] = newPath; | |
| this.context.current = newPath.id; | |
| } | |
| break; | |
| case EventType.mouseUp: | |
| if (this.context.op === 'line') { | |
| var tempPath = this.paths[this.context.current]; | |
| tempPath.add(event.payload.point) | |
| } | |
| break; | |
| case EventType.undo: | |
| var op = this.undoStack.pop(); | |
| if (op && op.type === 'addPath') { | |
| var tempPath = this.paths[op.id]; | |
| var segments = tempPath.removeSegments(); | |
| delete this.paths[op.id]; | |
| this.redoStack.push({type:'path.removeSegments', segments: segments}) | |
| } | |
| break; | |
| case EventType.redo: | |
| var op = this.redoStack.pop(); | |
| if (op && op.type === 'path.removeSegments') { | |
| var tempPath = new Path(); | |
| tempPath.id = id++; | |
| tempPath.strokeColor = 'red'; | |
| tempPath.addSegments(op.segments); | |
| this.undoStack.push({"type": 'addPath', 'id': tempPath.id}); | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| } | |
| } | |
| var handler = new Handler(); | |
| function onMouseDown(event) { | |
| // The mouse was clicked, so let's put a newly created Path into | |
| // myPath, give it the color black and add the location as the | |
| // path's first segment. | |
| handler.handle(new Event(EventType.mouseDown, event)); | |
| } | |
| function onMouseUp(event) { | |
| // The mouse was released, so we add the new location as the end | |
| // segment of the line. | |
| handler.handle(new Event(EventType.mouseUp, event)); | |
| } | |
| var text = new PointText({ | |
| point: view.center, | |
| content: 'Click here to focus and then press some keys.', | |
| justification: 'center', | |
| fontSize: 15 | |
| }); | |
| function onKeyDown(event) { | |
| // When a key is pressed, set the content of the text item: | |
| text.content = 'The ' + event.key + ' key was pressed!'; | |
| if (event.key === 'u') { | |
| handler.handle(new Event(EventType.undo)); | |
| } | |
| if (event.key === 'r') { | |
| handler.handle(new Event(EventType.redo)); | |
| } | |
| } | |
| function onKeyUp(event) { | |
| // When a key is released, set the content of the text item: | |
| text.content = 'The ' + event.key + ' key was released!'; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment