Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Add Undo and Redo functionality #26

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion css/activity.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,12 @@

#main-toolbar #clear-button {
background-image: url(../icons/clear-button.svg);
}
}

#main-toolbar #undo-button {
background-image: url(../icons/undo-button.svg);
}

#main-toolbar #redo-button {
background-image: url(../icons/redo-button.svg);
}
16 changes: 16 additions & 0 deletions icons/redo-button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions icons/undo-button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
<button class="toolbutton" id="activity-button" title="My Activity"></button>
<button class="toolbutton" id="new-button" title="New"></button>
<button class="toolbutton" id="clear-button" title="Clear Canvas"></button>
<button class="toolbutton" id="undo-button" title="Undo"></button>
<button class="toolbutton" id="redo-button" title="Redo"></button>
<button class="toolbutton pull-right" id="stop-button" title="Stop"></button>
</div>

Expand Down
95 changes: 88 additions & 7 deletions js/activity.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ define(function (require) {
this.nlabels = [];
this.shape = 0;

// Undo/Redo variables
this.strokes = [];
this.undoneStrokes = [];
this.currentStroke = null;

// Image sources
this.Star = "images/star.svg";
this.Dot = "images/dot.svg";
Expand Down Expand Up @@ -207,11 +212,12 @@ define(function (require) {
y: target.y - evt.stageY,
};

// Initialize drawing variables
self.color = self.colors[self.index++ % self.colors.length];
self.stroke = (Math.random() * 30 + 10) | 0;
self.oldPt = new createjs.Point(self.stage.mouseX, self.stage.mouseY);
self.oldMidPt = self.oldPt;
// Initialize a new stroke
self.currentStroke = {
color: self.color,
strokeSize: self.stroke,
segments: [],
};

evt.onMouseMove = function (ev) {
target.x = ev.stageX + offset.x;
Expand All @@ -233,16 +239,37 @@ define(function (require) {
self.oldMidPt.y
);

// Record this segment of the stroke
self.currentStroke.segments.push({
start: { x: self.oldMidPt.x, y: self.oldMidPt.y },
control: { x: self.oldPt.x, y: self.oldPt.y },
end: { x: midPt.x, y: midPt.y },
});

self.oldPt.x = self.stage.mouseX;
self.oldPt.y = self.stage.mouseY;
self.oldMidPt.x = midPt.x;
self.oldMidPt.y = midPt.y;
};

evt.onMouseUp = function () {
// Finalize the current stroke
if (self.currentStroke && self.currentStroke.segments.length > 0) {
self.strokes.push(self.currentStroke);
self.currentStroke = null;
// Clear the redo stack since a new stroke is drawn
self.undoneStrokes = [];
}
};
};

target.onMouseOver = function () {
target.scaleX = target.scaleY = target.scale * 1.2;
self.update = true;
self.color = self.colors[self.index++ % self.colors.length];
self.stroke = (Math.random() * 30 + 10) | 0;
self.oldPt = new createjs.Point(self.stage.mouseX, self.stage.mouseY);
self.oldMidPt = self.oldPt;
};

target.onMouseOut = function () {
Expand Down Expand Up @@ -297,6 +324,10 @@ define(function (require) {
this.midPt = this.oldPt;
this.oldMidPt = this.oldPt;
this.update = true;

// Clear the stroke history
this.strokes = [];
this.undoneStrokes = [];
};

DrawingApp.prototype.setupEventListeners = function () {
Expand All @@ -319,8 +350,58 @@ define(function (require) {
clearButton.addEventListener("click", function () {
self.clearCanvas();
});

// Undo button
var undoButton = document.getElementById("undo-button");
undoButton.addEventListener("click", function () {
self.undo();
});

// Redo button
var redoButton = document.getElementById("redo-button");
redoButton.addEventListener("click", function () {
self.redo();
});
};

// Undo the last stroke
DrawingApp.prototype.undo = function () {
if (this.strokes.length > 0) {
var lastStroke = this.strokes.pop();
this.undoneStrokes.push(lastStroke);
this.redrawStrokes();
}
};

// Redo the last undone stroke
DrawingApp.prototype.redo = function () {
if (this.undoneStrokes.length > 0) {
var stroke = this.undoneStrokes.pop();
this.strokes.push(stroke);
this.redrawStrokes();
}
};

// Export the DrawingApp class
return DrawingApp;
// Redraw all strokes from the history
DrawingApp.prototype.redrawStrokes = function () {
// Clear the drawingCanvas
this.drawingCanvas.graphics.clear();

// Redraw each stroke
for (var i = 0; i < this.strokes.length; i++) {
var s = this.strokes[i];
this.drawingCanvas.graphics
.setStrokeStyle(s.strokeSize, "round", "round")
.beginStroke(s.color);

for (var j = 0; j < s.segments.length; j++) {
var seg = s.segments[j];
this.drawingCanvas.graphics
.moveTo(seg.start.x, seg.start.y)
.curveTo(seg.control.x, seg.control.y, seg.end.x, seg.end.y);
}
}

this.update = true;
};
});