adding the animation directory
This commit is contained in:
483
animations/lists/creation/creation.js
Normal file
483
animations/lists/creation/creation.js
Normal file
@@ -0,0 +1,483 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the stack nodes.
|
||||
var rect2 = new Konva.Rect({
|
||||
x: 870,
|
||||
y: 420,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 310,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
// the rectangle which contains the list.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 1050,
|
||||
y: 420,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 500,
|
||||
height: 310,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// create a function to draw stack nodes
|
||||
function drawStackNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
// name of the pointer
|
||||
var text1 = new Konva.Text({
|
||||
x: x - 50,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "node_index_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text1);
|
||||
}
|
||||
|
||||
// create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 40,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x + 40,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 80,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 15,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+80, y+25, x+150, y+25],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
visible: false,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1605,
|
||||
y: 475,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_null);
|
||||
|
||||
var text_stack = new Konva.Text({
|
||||
x: 895,
|
||||
y: 380,
|
||||
text: "Stack",
|
||||
id: "node_text_stack",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_stack);
|
||||
|
||||
var text_heap = new Konva.Text({
|
||||
x: 1255,
|
||||
y: 380,
|
||||
text: "Heap",
|
||||
id: "node_text_heap",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_heap);
|
||||
|
||||
var rect_console = new Konva.Rect({
|
||||
x: 150,
|
||||
y: 400,
|
||||
id:"console_rect",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 400,
|
||||
height: 200,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_console);
|
||||
|
||||
var consoleLabel = new Konva.Text({
|
||||
x: 280,
|
||||
y: 635,
|
||||
id:"console_label",
|
||||
text: "Console",
|
||||
fontSize: 28,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
});
|
||||
|
||||
var consoleText = new Konva.Text({
|
||||
x: 140,
|
||||
y: 400,
|
||||
id:"console_text",
|
||||
text: "",
|
||||
fontSize: 28,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#581845',
|
||||
});
|
||||
layer.add(consoleLabel);
|
||||
layer.add(consoleText);
|
||||
|
||||
var message=["$",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
""];
|
||||
|
||||
function updateMessage(msg,i) {
|
||||
stage.find('#text_msg'+i).text(msg);
|
||||
}
|
||||
|
||||
function makeText(x,y,str,id) {
|
||||
let text = new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'text_'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 400,
|
||||
padding: 20,
|
||||
// align: 'center',
|
||||
});
|
||||
layer.add(text);
|
||||
}
|
||||
|
||||
// draw that $ sign, which is a command line prompt.
|
||||
makeText(155,420,message[0],'msg0');
|
||||
|
||||
var arrow_p = new Konva.Arrow({
|
||||
points: [1100, 605, 1100, 535],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_p',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// the node code rectangle.
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 150,
|
||||
y: 30,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 400,
|
||||
height: 160,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
|
||||
var nodeLabel = new Konva.Text({
|
||||
x: 280,
|
||||
y: 235,
|
||||
id:"node_label",
|
||||
text: "Node Definition",
|
||||
fontSize: 28,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
});
|
||||
|
||||
layer.add(nodeLabel);
|
||||
layer.add(rect1);
|
||||
|
||||
// the main code rectangle.
|
||||
var rect_list = new Konva.Rect({
|
||||
x: 850,
|
||||
y: 30,
|
||||
id:"code_rec_list",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 650,
|
||||
height: 300,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_list);
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 650,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code=[
|
||||
"0. template <class T>",
|
||||
"1. class Node {",
|
||||
"2. public:",
|
||||
"3. \t\t\t T value;",
|
||||
"4. \t\t\t Node* next;",
|
||||
"5. }",
|
||||
];
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
let t=makeCode(160,30+(i*20),code[i],i+1);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
var code_list=[
|
||||
"0. int main() {",
|
||||
"1. \t\t\t Node<int>* head;",
|
||||
"2. \t\t\t head = new Node<int>;",
|
||||
"3. \t\t\t head->value = 6;",
|
||||
"4. \t\t\t head->next = NULL;",
|
||||
"5. \t\t\t Node<int>* q = new Node<int>;",
|
||||
"6. \t\t\t q->value = 8;",
|
||||
"7. \t\t\t q->next = NULL;",
|
||||
"8. \t\t\t head->next = q;",
|
||||
"9. \t\t\t cout << \"1st value: \" << head->value << endl;",
|
||||
"10. \t\t\tcout << \"2nd value: \" << head->next->value << endl;",
|
||||
"11. }",
|
||||
];
|
||||
|
||||
function makeBold_list(id){
|
||||
for(let i=1; i<=code_list.length; i++){
|
||||
if(i!=id){
|
||||
// regarding the parentheses, we must add the two numbers first.
|
||||
stage.find('#line'+(i+100)).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+(i+100)).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code_list.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
// here we add 100 so as to differentiate from the code array.
|
||||
let t=makeCode(860,30+(i*20),code_list[i],i+1+100);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
// draw the image
|
||||
layer.draw();
|
||||
stage.add(layer);
|
||||
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [910, 535, 1030, 485, 1075, 485],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
var arrow2 = new Konva.Arrow({
|
||||
points: [910, 585, 1030, 635, 1235, 585],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow2",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
layer.draw();
|
||||
|
||||
var targetPts = [1160, 485, 1200, 435, 1600, 485];
|
||||
// create the animation
|
||||
var tween = new Konva.Tween({
|
||||
node: arrow2,
|
||||
points: targetPts,
|
||||
duration: 2, // animation duration in seconds
|
||||
easing: Konva.Easings.Linear
|
||||
});
|
||||
|
||||
|
||||
var pc=1;
|
||||
// creating the list.
|
||||
function nextstep() {
|
||||
if(pc == 1){
|
||||
makeBold_list(pc);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 2){
|
||||
makeBold_list(pc);
|
||||
drawStackNode(870, 500, 'head', 1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 3){
|
||||
makeBold_list(pc);
|
||||
drawListNode(1080, 460, '?', 1);
|
||||
layer.add(arrow1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 4){
|
||||
makeBold_list(pc);
|
||||
stage.find('#list_node_text_1').text('6');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 5){
|
||||
makeBold_list(pc);
|
||||
stage.find('#list_arrow_1').points(targetPts);
|
||||
stage.find('#list_arrow_1').visible('true');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 6){
|
||||
makeBold_list(pc);
|
||||
drawStackNode(870, 550, 'q', 2);
|
||||
drawListNode(1240, 560, '?', 2);
|
||||
layer.add(arrow2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 7){
|
||||
makeBold_list(pc);
|
||||
stage.find('#list_node_text_2').text('8');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 8){
|
||||
makeBold_list(pc);
|
||||
targetPts = [1310, 585, 1350, 600, 1600, 485];
|
||||
stage.find('#list_arrow_2').points(targetPts);
|
||||
stage.find('#list_arrow_2').visible('true');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 9){
|
||||
makeBold_list(pc);
|
||||
targetPts = [1160, 485, 1200, 555, 1240, 585];
|
||||
stage.find('#list_arrow_1').points(targetPts);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 10){
|
||||
makeBold_list(pc);
|
||||
updateMessage("$ 1st value: 6",0);
|
||||
makeText(155,440,message[1],'msg1');
|
||||
updateMessage("$",1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 11){
|
||||
makeBold_list(pc);
|
||||
updateMessage("$ 2nd value: 8",1);
|
||||
makeText(155,460,message[2],'msg2');
|
||||
updateMessage("$",2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 12){
|
||||
makeBold_list(pc);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 13){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
20
animations/lists/creation/index.html
Normal file
20
animations/lists/creation/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List creation</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List creation</h1>
|
||||
<p>This animation shows how we implement and create a list. Click the "next step" button to run the animation. </p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="creation.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="nextstep()" style="position: absolute; top: 110px; left: 10px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
431
animations/lists/erase/erase.js
Normal file
431
animations/lists/erase/erase.js
Normal file
@@ -0,0 +1,431 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
var count=0;
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the vector.
|
||||
var rect2 = new Konva.Rect({
|
||||
x: 70,
|
||||
y: 360,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 560,
|
||||
height: 250,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
// the rectangle which contains the list.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 850,
|
||||
y: 360,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 900,
|
||||
height: 250,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// Create a function to draw vector nodes
|
||||
function drawVecNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
var text1 = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 60,
|
||||
text: id - 1,
|
||||
id: "node_index_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text1);
|
||||
}
|
||||
|
||||
drawVecNode(100, 460, '7', 1);
|
||||
drawVecNode(200, 460, '5', 2);
|
||||
drawVecNode(300, 460, '8', 3);
|
||||
drawVecNode(400, 460, '1', 4);
|
||||
drawVecNode(500, 460, '9', 5);
|
||||
|
||||
// Create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x+100,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 20,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+110, y+25, x+150, y+25],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
drawListNode(900, 460, '7', 1);
|
||||
drawListNode(1050, 460, '5', 2);
|
||||
drawListNode(1200, 460, '8', 3);
|
||||
drawListNode(1350, 460, '1', 4);
|
||||
drawListNode(1500, 460, '9', 4);
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1655,
|
||||
y: 475,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_null);
|
||||
|
||||
var text_index = new Konva.Text({
|
||||
x: 220,
|
||||
y: 550,
|
||||
text: "index",
|
||||
id: "vec_index",
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
// the code rectangle.
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 70,
|
||||
y: 60,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 550,
|
||||
height: 180,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1)
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 550,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code=[
|
||||
"0. void erase_from_vector(unsigned int i, vector<int>& v) {",
|
||||
"1. \t\t\t for (int index = i; index < v.size()-1; index++) {",
|
||||
"2. \t\t\t \t\t\t v[index] = v[index+1];",
|
||||
"3. \t\t\t }",
|
||||
"4. \t\t\t v.pop_back();",
|
||||
"5. }",
|
||||
];
|
||||
|
||||
function makeBold(id){
|
||||
for(let i=1; i<=code.length; i++){
|
||||
if(i!=id){
|
||||
stage.find('#line'+i).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+id).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
let t=makeCode(80,60+(i*20),code[i],i+1);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
// draw the image
|
||||
layer.draw();
|
||||
stage.add(layer);
|
||||
|
||||
var pc=1;
|
||||
// erase 5 from this vector.
|
||||
function vec_erase_nextstep() {
|
||||
if(pc == 1){
|
||||
makeBold(pc);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 2){
|
||||
makeBold(pc);
|
||||
layer.add(text_index);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 3){
|
||||
makeBold(pc);
|
||||
// highlight the one we are going to erase.
|
||||
stage.find('#node_rec_2').fill('#f4d03f');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 4){
|
||||
stage.find('#node_text_2').text('8');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 5){
|
||||
makeBold(4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 6){
|
||||
makeBold(2);
|
||||
// increment x by 100.
|
||||
text_index.x(text_index.getX()+100);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 7){
|
||||
makeBold(3);
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_3').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_2').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 8){
|
||||
stage.find('#node_text_3').text('1');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 9){
|
||||
makeBold(4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 10){
|
||||
makeBold(2);
|
||||
// increment x by 100.
|
||||
text_index.x(text_index.getX()+100);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 11){
|
||||
makeBold(3);
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_4').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_3').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 12){
|
||||
stage.find('#node_text_4').text('9');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 13){
|
||||
makeBold(4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 14){
|
||||
makeBold(2);
|
||||
// increment x by 100.
|
||||
text_index.x(text_index.getX()+100);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 15){
|
||||
makeBold(4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 16){
|
||||
makeBold(5);
|
||||
text_index.destroy();
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_5').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_4').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 17){
|
||||
var shape = stage.find('#node_rec_5');
|
||||
// let this object disappear in 2 seconds.
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_rec_5').destroy();
|
||||
shape = stage.find('#node_text_5');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_text_5').destroy();
|
||||
shape = stage.find('#node_index_5');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_index_5').destroy();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 18){
|
||||
makeBold(6);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 19){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}
|
||||
}
|
||||
|
||||
var targetPoints = [1010, 485, 1100, 585, 1200, 485];
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [1010, 485, 1030, 485, 1050, 485],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
layer.add(arrow1);
|
||||
layer.draw();
|
||||
var arrow2 = stage.find('#arrow1');
|
||||
|
||||
// Create the animation
|
||||
var tween = new Konva.Tween({
|
||||
node: arrow2,
|
||||
points: targetPoints,
|
||||
duration: 2, // animation duration in seconds
|
||||
easing: Konva.Easings.Linear
|
||||
});
|
||||
|
||||
var pc2=1;
|
||||
// erase 5 from this list.
|
||||
function list_erase_nextstep() {
|
||||
if(pc2 == 1){
|
||||
stage.find('#list_arrow_1').destroy();
|
||||
// start the animation
|
||||
tween.play();
|
||||
//layer.add(arrow1);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 2){
|
||||
var shape = stage.find('#list_arrow_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_rec_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_pointer_rec_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_text_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 3){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
21
animations/lists/erase/index.html
Normal file
21
animations/lists/erase/index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List vs Vector: erase operation</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List vs Vector: erase operation</h1>
|
||||
<p>This animation shows why erasing an element in a vector is more expensive than in a list. Click the "next step" button to run the animation. <b>Note:</b> in this animation, we assume we are going to erase the element which has the value 5.</p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="erase.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="vec_erase_nextstep()" style="position: absolute; top: 500px; left: 100px;">next step</button>
|
||||
<button onclick="list_erase_nextstep()" style="position: absolute; top: 500px; left: 900px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
20
animations/lists/insert/index.html
Normal file
20
animations/lists/insert/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List: insert operation</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List: insert operation</h1>
|
||||
<p>This animation shows the insert operation in List. Click the "next step" button to run the animation. <b>Note:</b> in this animation, we will insert a node in between 5 and 8, and we assume the new node's value (i.e., x) is 4.</p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="insert.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="list_insert_nextstep()" style="position: absolute; top: 110px; left: 10px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
359
animations/lists/insert/insert.js
Normal file
359
animations/lists/insert/insert.js
Normal file
@@ -0,0 +1,359 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the list.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 250,
|
||||
y: 360,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 900,
|
||||
height: 300,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// Create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x+100,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 20,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
// value
|
||||
var text = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+110, y+25, x+150, y+25],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
drawListNode(300, 460, '7', 1);
|
||||
drawListNode(450, 460, '5', 2);
|
||||
drawListNode(600, 460, '8', 3);
|
||||
drawListNode(750, 460, '1', 4);
|
||||
drawListNode(900, 460, '9', 4);
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1055,
|
||||
y: 475,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_null);
|
||||
|
||||
var text_itr = new Konva.Text({
|
||||
x: 235,
|
||||
y: 640,
|
||||
text: "itr",
|
||||
id: 'vec_itr_1',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var itr_arrow = new Konva.Arrow({
|
||||
points: [250, 625, 250, 555],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'itr_arrow_1',
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
var pts = itr_arrow.points();
|
||||
|
||||
var text_itr2 = new Konva.Text({
|
||||
x: 235,
|
||||
y: 640,
|
||||
text: "itr2",
|
||||
id: 'vec_itr_2',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var itr2_arrow = new Konva.Arrow({
|
||||
points: [250, 625, 250, 555],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'itr_arrow_2',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
var pts2 = itr2_arrow.points();
|
||||
|
||||
var text_p = new Konva.Text({
|
||||
x: 495,
|
||||
y: 610,
|
||||
text: "p",
|
||||
id: 'itr_p',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var arrow_p = new Konva.Arrow({
|
||||
points: [500, 605, 500, 535],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_p',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
layer.add(text_p);
|
||||
layer.add(arrow_p);
|
||||
|
||||
// for pointer q
|
||||
var text_q = new Konva.Text({
|
||||
x: 645,
|
||||
y: 710,
|
||||
text: "q",
|
||||
id: 'itr_q',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var arrow_q = new Konva.Arrow({
|
||||
points: [650, 705, 650, 635],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_q',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// the code rectangle.
|
||||
var rect_list = new Konva.Rect({
|
||||
x: 250,
|
||||
y: 60,
|
||||
id:"code_rec_list",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 650,
|
||||
height: 250,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_list);
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 750,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code_list=[
|
||||
"0. Node<T> * q = new Node<T>; \t\t\t \t\t\t // create a new node",
|
||||
"1. q->value = x; \t\t\t \t\t\t \t\t\t \t\t\t // store x in this node",
|
||||
"2. q->next = p->next; \t\t\t \t\t\t // make its successor be the current successor of p",
|
||||
"3. p->next = q; \t\t\t \t\t\t \t\t\t \t\t\t // make p's successor be this new node",
|
||||
];
|
||||
|
||||
function makeBold_list(id){
|
||||
for(let i=1; i<=code_list.length; i++){
|
||||
if(i!=id){
|
||||
// regarding the parentheses, we must add the two numbers first.
|
||||
stage.find('#line'+(i+100)).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+(i+100)).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code_list.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
// here we add 100 so as to differentiate from the code array.
|
||||
let t=makeCode(260,60+(i*20),code_list[i],i+1+100);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
function increment_itr1() {
|
||||
text_itr.x(text_itr.getX()+100);
|
||||
pts[0] = pts[0] + 100;
|
||||
pts[2] = pts[2] + 100;
|
||||
itr_arrow.points(pts);
|
||||
}
|
||||
|
||||
function increment_itr2() {
|
||||
text_itr2.x(text_itr2.getX()+100);
|
||||
pts2[0] = pts2[0] + 100;
|
||||
pts2[2] = pts2[2] + 100;
|
||||
itr2_arrow.points(pts2);
|
||||
}
|
||||
|
||||
// draw the image
|
||||
layer.draw();
|
||||
stage.add(layer);
|
||||
|
||||
var targetPoints = [1010, 485, 1100, 585, 1200, 485];
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [1010, 485, 1030, 485, 1050, 485],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
layer.add(arrow1);
|
||||
layer.draw();
|
||||
var arrow2 = stage.find('#arrow1');
|
||||
|
||||
// Create the animation
|
||||
var tween = new Konva.Tween({
|
||||
node: arrow2,
|
||||
points: targetPoints,
|
||||
duration: 2, // animation duration in seconds
|
||||
easing: Konva.Easings.Linear
|
||||
});
|
||||
|
||||
var pts_p = arrow_p.points();
|
||||
function increment_p() {
|
||||
text_p.x(text_p.getX()+160);
|
||||
pts_p[0] = pts_p[0] + 160;
|
||||
pts_p[2] = pts_p[2] + 160;
|
||||
itr2_arrow.points(pts_p);
|
||||
}
|
||||
|
||||
var pc2=1;
|
||||
// erase 5 from this list.
|
||||
function list_insert_nextstep() {
|
||||
if(pc2 == 1){
|
||||
makeBold_list(1);
|
||||
drawListNode(600, 560, '?', 6);
|
||||
layer.add(text_q);
|
||||
layer.add(arrow_q);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 2){
|
||||
makeBold_list(2);
|
||||
stage.find('#list_node_text_6').text('4');
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 3){
|
||||
makeBold_list(3);
|
||||
targetPoints = [720, 585, 700, 550, 600, 485];
|
||||
stage.find('#list_arrow_6').points(targetPoints);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 4){
|
||||
makeBold_list(4);
|
||||
targetPoints = [560, 485, 565, 530, 600, 585];
|
||||
stage.find('#list_arrow_2').points(targetPoints);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 5){
|
||||
makeBold_list(-1);
|
||||
var shape = stage.find('#arrow_p');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#arrow_q');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#itr_p');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#itr_q');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 6){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
21
animations/lists/iterator/index.html
Normal file
21
animations/lists/iterator/index.html
Normal file
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List vs Vector: erase operation, using iterators</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List vs Vector: erase operation, using iterators</h1>
|
||||
<p>This animation shows why erasing an element in a vector is more expensive than in a list. Click the "next step" button to run the animation. <b>Note:</b> in this animation, we assume we are going to erase the element which has the value 5.</p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="iterator.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="vec_erase_nextstep()" style="position: absolute; top: 500px; left: 100px;">next step</button>
|
||||
<button onclick="list_erase_nextstep()" style="position: absolute; top: 500px; left: 900px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
597
animations/lists/iterator/iterator.js
Normal file
597
animations/lists/iterator/iterator.js
Normal file
@@ -0,0 +1,597 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the vector.
|
||||
var rect2 = new Konva.Rect({
|
||||
x: 70,
|
||||
y: 360,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 650,
|
||||
height: 350,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
// the rectangle which contains the list.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 850,
|
||||
y: 360,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 900,
|
||||
height: 300,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// Create a function to draw vector nodes
|
||||
function drawVecNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
var text1 = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 60,
|
||||
text: id - 1,
|
||||
id: "node_index_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text1);
|
||||
}
|
||||
|
||||
drawVecNode(100, 460, '7', 1);
|
||||
drawVecNode(200, 460, '5', 2);
|
||||
drawVecNode(300, 460, '8', 3);
|
||||
drawVecNode(400, 460, '1', 4);
|
||||
drawVecNode(500, 460, '9', 5);
|
||||
|
||||
// Create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x+100,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 20,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+110, y+25, x+150, y+25],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
drawListNode(900, 460, '7', 1);
|
||||
drawListNode(1050, 460, '5', 2);
|
||||
drawListNode(1200, 460, '8', 3);
|
||||
drawListNode(1350, 460, '1', 4);
|
||||
drawListNode(1500, 460, '9', 4);
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1655,
|
||||
y: 475,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_null);
|
||||
|
||||
var text_itr = new Konva.Text({
|
||||
x: 235,
|
||||
y: 640,
|
||||
text: "itr",
|
||||
id: 'vec_itr_1',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var itr_arrow = new Konva.Arrow({
|
||||
points: [250, 625, 250, 555],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'itr_arrow_1',
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
var pts = itr_arrow.points();
|
||||
|
||||
var text_itr2 = new Konva.Text({
|
||||
x: 235,
|
||||
y: 640,
|
||||
text: "itr2",
|
||||
id: 'vec_itr_2',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var itr2_arrow = new Konva.Arrow({
|
||||
points: [250, 625, 250, 555],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'itr_arrow_2',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
var pts2 = itr2_arrow.points();
|
||||
|
||||
var text_p = new Konva.Text({
|
||||
x: 1100,
|
||||
y: 610,
|
||||
text: "p",
|
||||
id: 'list_itr_p',
|
||||
fontSize: 26,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#17202a'
|
||||
});
|
||||
|
||||
var arrow_p = new Konva.Arrow({
|
||||
points: [1100, 605, 1100, 535],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_p',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// the code rectangle.
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 70,
|
||||
y: 60,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 650,
|
||||
height: 250,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
// the code rectangle.
|
||||
var rect_list = new Konva.Rect({
|
||||
x: 850,
|
||||
y: 60,
|
||||
id:"code_rec_list",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 650,
|
||||
height: 250,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_list);
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 650,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code=[
|
||||
"0. void erase_from_vector(vector<int>::iterator itr, vector<int>& v) {",
|
||||
"1. \t\t\t vector<int>::iterator itr2 = itr;",
|
||||
"2. \t\t\t itr2++;",
|
||||
"3. \t\t\t while (itr2 != v.end()) {",
|
||||
"4. \t\t\t \t\t\t *itr = *itr2;",
|
||||
"5. \t\t\t \t\t\t itr++;",
|
||||
"6. \t\t\t \t\t\t itr2++;",
|
||||
"7. \t\t\t }",
|
||||
"8. \t\t\t v.pop_back();",
|
||||
"9. }",
|
||||
];
|
||||
|
||||
function makeBold(id){
|
||||
for(let i=1; i<=code.length; i++){
|
||||
if(i!=id){
|
||||
stage.find('#line'+i).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+id).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
let t=makeCode(80,60+(i*20),code[i],i+1);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
var code_list=[
|
||||
"0. std::list<int> s;",
|
||||
"1. std::list<int>::iterator p; // code initializing p is omitted",
|
||||
"2. p = s.erase(p);",
|
||||
];
|
||||
|
||||
function makeBold_list(id){
|
||||
for(let i=1; i<=code_list.length; i++){
|
||||
if(i!=id){
|
||||
// regarding the parentheses, we must add the two numbers first.
|
||||
stage.find('#line'+(i+100)).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+(i+100)).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code_list.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
// here we add 100 so as to differentiate from the code array.
|
||||
let t=makeCode(860,60+(i*20),code_list[i],i+1+100);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
function increment_itr1() {
|
||||
text_itr.x(text_itr.getX()+100);
|
||||
pts[0] = pts[0] + 100;
|
||||
pts[2] = pts[2] + 100;
|
||||
itr_arrow.points(pts);
|
||||
}
|
||||
|
||||
function increment_itr2() {
|
||||
text_itr2.x(text_itr2.getX()+100);
|
||||
pts2[0] = pts2[0] + 100;
|
||||
pts2[2] = pts2[2] + 100;
|
||||
itr2_arrow.points(pts2);
|
||||
}
|
||||
|
||||
// draw the image
|
||||
layer.draw();
|
||||
stage.add(layer);
|
||||
|
||||
var pc=1;
|
||||
// erase 5 from this vector.
|
||||
function vec_erase_nextstep() {
|
||||
if(pc == 1){
|
||||
makeBold(pc);
|
||||
layer.add(text_itr);
|
||||
layer.add(itr_arrow);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 2){
|
||||
makeBold(pc);
|
||||
layer.add(text_itr2);
|
||||
layer.add(itr2_arrow);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 3){
|
||||
makeBold(pc);
|
||||
increment_itr2();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 4){
|
||||
makeBold(4);
|
||||
// highlight the one we are going to erase.
|
||||
stage.find('#node_rec_2').fill('#f4d03f');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 5){
|
||||
makeBold(5);
|
||||
stage.find('#node_text_2').text('8');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 6){
|
||||
makeBold(6);
|
||||
increment_itr1();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 7){
|
||||
makeBold(7);
|
||||
increment_itr2();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 8){
|
||||
makeBold(8);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 9){
|
||||
makeBold(4);
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_3').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_2').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 10){
|
||||
makeBold(5);
|
||||
stage.find('#node_text_3').text('1');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 11){
|
||||
makeBold(6);
|
||||
increment_itr1();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 12){
|
||||
makeBold(7);
|
||||
increment_itr2();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 13){
|
||||
makeBold(8);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 14){
|
||||
makeBold(4);
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_4').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_3').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 15){
|
||||
makeBold(5);
|
||||
stage.find('#node_text_4').text('9');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 16){
|
||||
makeBold(6);
|
||||
increment_itr1();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 17){
|
||||
makeBold(7);
|
||||
increment_itr2();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 18){
|
||||
makeBold(8);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 19){
|
||||
makeBold(4);
|
||||
// highlight the one we are going to update.
|
||||
stage.find('#node_rec_5').fill('#f4d03f');
|
||||
// and restore the previous one.
|
||||
stage.find('#node_rec_4').fill('#ddd');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 20){
|
||||
makeBold(8);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 21){
|
||||
makeBold(9);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 22){
|
||||
var shape = stage.find('#node_rec_5');
|
||||
// let this object disappear in 2 seconds.
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_rec_5').destroy();
|
||||
shape = stage.find('#node_text_5');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_text_5').destroy();
|
||||
shape = stage.find('#node_index_5');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
//stage.find('#node_index_5').destroy();
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 23){
|
||||
makeBold(10);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 24){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}
|
||||
}
|
||||
|
||||
var targetPoints = [1010, 485, 1100, 585, 1200, 485];
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [1010, 485, 1030, 485, 1050, 485],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
layer.add(arrow1);
|
||||
layer.draw();
|
||||
var arrow2 = stage.find('#arrow1');
|
||||
|
||||
// Create the animation
|
||||
var tween = new Konva.Tween({
|
||||
node: arrow2,
|
||||
points: targetPoints,
|
||||
duration: 2, // animation duration in seconds
|
||||
easing: Konva.Easings.Linear
|
||||
});
|
||||
|
||||
var pts_p = arrow_p.points();
|
||||
function increment_p() {
|
||||
text_p.x(text_p.getX()+160);
|
||||
pts_p[0] = pts_p[0] + 160;
|
||||
pts_p[2] = pts_p[2] + 160;
|
||||
itr2_arrow.points(pts_p);
|
||||
}
|
||||
|
||||
var pc2=1;
|
||||
// erase 5 from this list.
|
||||
function list_erase_nextstep() {
|
||||
if(pc2 == 1){
|
||||
makeBold_list(1);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 2){
|
||||
makeBold_list(2);
|
||||
layer.add(text_p);
|
||||
layer.add(arrow_p);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 3){
|
||||
makeBold_list(3);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 4){
|
||||
stage.find('#list_arrow_1').destroy();
|
||||
// start the animation
|
||||
tween.play();
|
||||
//layer.add(arrow1);
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}else if(pc2 == 5){
|
||||
makeBold_list(-1);
|
||||
var shape = stage.find('#list_arrow_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_rec_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_pointer_rec_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#list_node_text_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
increment_p();
|
||||
layer.draw();
|
||||
}else if(pc2 == 6){
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc2=pc2+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
20
animations/lists/push_back/index.html
Normal file
20
animations/lists/push_back/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List push_back</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List push_back</h1>
|
||||
<p>This animation shows how the push_back() method works in List. Click the "next step" button to run the animation. <b>Note:</b> In this animation, we assume value is 4. </p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="push_back.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="nextstep()" style="position: absolute; top: 110px; left: 10px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
588
animations/lists/push_back/push_back.js
Normal file
588
animations/lists/push_back/push_back.js
Normal file
@@ -0,0 +1,588 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the list, which is also the heap rectangle.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 1350,
|
||||
y: 220,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 300,
|
||||
height: 535,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// create a function to draw stack nodes
|
||||
function drawStackNode(x, y, label, id, value){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
// name of the pointer
|
||||
var text1 = new Konva.Text({
|
||||
x: x - 50,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "node_index_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text1);
|
||||
|
||||
// content
|
||||
var text2 = new Konva.Text({
|
||||
x: x + 25,
|
||||
y: y + 20,
|
||||
text: value,
|
||||
id: "node_content_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text2);
|
||||
}
|
||||
|
||||
// create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 20,
|
||||
height: 30,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x + 20,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 40,
|
||||
height: 30,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 5,
|
||||
y: y + 5,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+40, y+15, x+80, y+15],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
visible: false,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
drawListNode(1360, 230, '7', 1);
|
||||
drawListNode(1450, 280, '5', 2);
|
||||
drawListNode(1400, 330, '8', 3);
|
||||
drawListNode(1450, 380, '1', 4);
|
||||
stage.find('#list_arrow_1').visible('true');
|
||||
stage.find('#list_arrow_2').visible('true');
|
||||
stage.find('#list_arrow_3').visible('true');
|
||||
stage.find('#list_arrow_4').visible('true');
|
||||
|
||||
var targetPts = [1400, 245, 1420, 255, 1450, 295];
|
||||
stage.find('#list_arrow_1').points(targetPts);
|
||||
targetPts = [1490, 295, 1450, 318, 1370, 326, 1400, 345];
|
||||
stage.find('#list_arrow_2').points(targetPts);
|
||||
targetPts = [1440, 345, 1420, 378, 1450, 395];
|
||||
stage.find('#list_arrow_3').points(targetPts);
|
||||
targetPts = [1490, 395, 1475, 420, 1450, 558, 1682, 600];
|
||||
stage.find('#list_arrow_4').points(targetPts);
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1685,
|
||||
y: 575,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
//layer.add(text_null);
|
||||
|
||||
var text_stack = new Konva.Text({
|
||||
x: 295,
|
||||
y: 380,
|
||||
text: "Stack",
|
||||
id: "node_text_stack",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_stack);
|
||||
|
||||
var text_heap = new Konva.Text({
|
||||
x: 855,
|
||||
y: 380,
|
||||
text: "Heap",
|
||||
id: "node_text_heap",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_heap);
|
||||
|
||||
var arrow_p = new Konva.Arrow({
|
||||
points: [1100, 605, 1100, 535],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_p',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// the node code rectangle.
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 10,
|
||||
y: 30,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 220,
|
||||
height: 160,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
|
||||
var nodeLabel = new Konva.Text({
|
||||
x: 25,
|
||||
y: 235,
|
||||
id:"node_label",
|
||||
text: "Node Definition",
|
||||
fontSize: 28,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
});
|
||||
|
||||
layer.add(nodeLabel);
|
||||
layer.add(rect1);
|
||||
|
||||
function makeCodeBox(x, y){
|
||||
// the main code rectangle.
|
||||
var rect_list = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"code_rec_list",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 500,
|
||||
height: 230,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_list);
|
||||
}
|
||||
makeCodeBox(280, 30);
|
||||
makeCodeBox(280, 280);
|
||||
makeCodeBox(280, 530);
|
||||
makeCodeBox(800, 30);
|
||||
makeCodeBox(800, 280);
|
||||
makeCodeBox(800, 530);
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 480,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code=[
|
||||
"0. template <class T>",
|
||||
"1. class Node {",
|
||||
"2. public:",
|
||||
"3. \t\t\t T value;",
|
||||
"4. \t\t\t Node* next;",
|
||||
"5. }",
|
||||
];
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
let t=makeCode(10,30+(i*20),code[i],i+1);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
var code_list=[
|
||||
"0. void push_back(Node<T>* & head, const T& value) {",
|
||||
"1. \t\t\t if(head == NULL) {",
|
||||
"2. \t\t\t \t\t\t Node<T>* tmp = new Node<T>;",
|
||||
"3. \t\t\t \t\t\t tmp->value = value;",
|
||||
"4. \t\t\t \t\t\t tmp->next = NULL;",
|
||||
"5. \t\t\t \t\t\t head = tmp;",
|
||||
"6. \t\t\t } else {",
|
||||
"7. \t\t\t \t\t\t push_back(head->next, value);",
|
||||
"8. \t\t\t }",
|
||||
"9. }",
|
||||
];
|
||||
|
||||
function makeBold_list(id, box){
|
||||
for(let i=1; i<=code_list.length; i++){
|
||||
if(i!=id){
|
||||
// regarding the parentheses, we must add the two numbers first.
|
||||
stage.find('#line'+(i+100*box)).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+(i+100*box)).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function makeCodeinBox(x,y,box){
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code_list.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
// here we add 100 so as to differentiate from the code array.
|
||||
let t=makeCode(x,y+(i*20),code_list[i],i+1+100*box);
|
||||
layer.add(t);
|
||||
}
|
||||
}
|
||||
makeCodeinBox(290,30,1);
|
||||
makeCodeinBox(290,280,2);
|
||||
makeCodeinBox(290,530,3);
|
||||
makeCodeinBox(810,30,4);
|
||||
makeCodeinBox(810,280,5);
|
||||
makeCodeinBox(810,530,6);
|
||||
|
||||
// draw the image
|
||||
drawStackNode(1685, 575, '', 0, 'NULL');
|
||||
drawStackNode(1370, 50, 'head', 1, ' ');
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [1420, 75, 1320, 135, 1355, 245],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow_1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
var arrow2 = new Konva.Arrow({
|
||||
points: [1450, 145, 1335, 190, 1340, 455, 1485, 494],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow_2",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// arrow 1 represents head
|
||||
layer.add(arrow1);
|
||||
|
||||
layer.draw();
|
||||
|
||||
var pc=1;
|
||||
// creating the list.
|
||||
function nextstep() {
|
||||
if(pc == 1){
|
||||
makeBold_list(pc, 1);
|
||||
stage.find('#node_rec_1').fill('plum');
|
||||
//drawStackNode(270, 550, 'value', 2, '4');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 2){
|
||||
makeBold_list(pc, 1);
|
||||
// the node we push front is called node 0.
|
||||
//drawListNode(600, 560, '?', 0);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 3){
|
||||
makeBold_list(7, 1);
|
||||
//stage.find('#list_node_text_0').text('4');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 4){
|
||||
makeBold_list(8, 1);
|
||||
//targetPts = [680, 585, 565, 645, 460, 545, 495, 485];
|
||||
//stage.find('#list_arrow_0').points(targetPts);
|
||||
//stage.find('#list_arrow_0').visible('true');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 5){
|
||||
makeBold_list(1, 2);
|
||||
//targetPts = [1420, 75, 1320, 135, 1450, 295];
|
||||
//stage.find('#arrow_1').points(targetPts);
|
||||
stage.find('#list_node_rec_1').fill('yellow');
|
||||
stage.find('#list_node_pointer_rec_1').fill('yellow');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 6){
|
||||
makeBold_list(2, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 7){
|
||||
makeBold_list(7, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 8){
|
||||
makeBold_list(8, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 9){
|
||||
makeBold_list(1, 3);
|
||||
stage.find('#list_node_rec_2').fill('orange');
|
||||
stage.find('#list_node_pointer_rec_2').fill('orange');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 10){
|
||||
makeBold_list(2, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 11){
|
||||
makeBold_list(7, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 12){
|
||||
makeBold_list(8, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 13){
|
||||
makeBold_list(1, 4);
|
||||
stage.find('#list_node_rec_3').fill('aqua');
|
||||
stage.find('#list_node_pointer_rec_3').fill('aqua');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 14){
|
||||
makeBold_list(2, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 15){
|
||||
makeBold_list(7, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 16){
|
||||
makeBold_list(8, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 17){
|
||||
makeBold_list(1, 5);
|
||||
stage.find('#list_node_rec_4').fill('pink');
|
||||
stage.find('#list_node_pointer_rec_4').fill('pink');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 18){
|
||||
makeBold_list(2, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 19){
|
||||
makeBold_list(7, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 20){
|
||||
makeBold_list(8, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 21){
|
||||
makeBold_list(1, 6);
|
||||
stage.find('#node_rec_0').fill('yellowgreen');
|
||||
//stage.find('#list_node_pointer_rec_5').fill('yellowgreen');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 22){
|
||||
makeBold_list(2, 6);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 23){
|
||||
makeBold_list(3, 6);
|
||||
drawStackNode(1400, 120, 'tmp', 2, ' ');
|
||||
// arrow 2 represents tmp
|
||||
layer.add(arrow2);
|
||||
drawListNode(1490, 480, '?', 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 24){
|
||||
makeBold_list(4, 6);
|
||||
// setting tmp's value
|
||||
stage.find('#list_node_text_5').text('4');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 25){
|
||||
makeBold_list(5, 6);
|
||||
targetPts = [1530, 495, 1540, 530, 1682, 600];
|
||||
// setting tmp's next to NULL
|
||||
stage.find('#list_arrow_5').points(targetPts);
|
||||
stage.find('#list_arrow_5').visible('true');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 26){
|
||||
makeBold_list(6, 6);
|
||||
// let current head point to the same location as tmp points to.
|
||||
targetPts = [1490, 395, 1475, 420, 1450, 458, 1492, 495];
|
||||
stage.find('#list_arrow_4').points(targetPts);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 27){
|
||||
makeBold_list(7, 6);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 28){
|
||||
// tmp goes out of scope
|
||||
var shape = stage.find('#arrow_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#node_rec_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#node_index_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
makeBold_list(10, 6);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 29){
|
||||
makeBold_list(-1, 6);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 30){
|
||||
makeBold_list(9, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 31){
|
||||
makeBold_list(10, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 32){
|
||||
makeBold_list(-1, 5);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 33){
|
||||
makeBold_list(9, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 34){
|
||||
makeBold_list(10, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 35){
|
||||
makeBold_list(-1, 4);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 36){
|
||||
makeBold_list(9, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 37){
|
||||
makeBold_list(10, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 38){
|
||||
makeBold_list(-1, 3);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 39){
|
||||
makeBold_list(9, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 40){
|
||||
makeBold_list(10, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 41){
|
||||
makeBold_list(-1, 2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 42){
|
||||
makeBold_list(9, 1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 43){
|
||||
makeBold_list(10, 1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 44){
|
||||
makeBold_list(-1, 1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 45){
|
||||
makeBold_list(2, 3);
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
20
animations/lists/push_front/index.html
Normal file
20
animations/lists/push_front/index.html
Normal file
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>List push_front</title>
|
||||
<script src="../../konva.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>List push_front</h1>
|
||||
<p>This animation shows how the push_front() method works in List. Click the "next step" button to run the animation. <b>Note:</b> In this animation, we only consider the general case where the list is not empty. Also, we assume value is 4. </p>
|
||||
|
||||
<div id="container"></div>
|
||||
<script src="push_front.js"></script>
|
||||
|
||||
<!-- we must include the javascript first, and then have this button definition which calls a function defined in the javascript -->
|
||||
<button onclick="nextstep()" style="position: absolute; top: 110px; left: 10px;">next step</button>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
408
animations/lists/push_front/push_front.js
Normal file
408
animations/lists/push_front/push_front.js
Normal file
@@ -0,0 +1,408 @@
|
||||
// Author: Jidong Xiao
|
||||
// first we need to create a stage
|
||||
var stage = new Konva.Stage({
|
||||
container: 'container', // id of container <div>
|
||||
width: 2000,
|
||||
height: 1000
|
||||
});
|
||||
|
||||
// then create layer
|
||||
var layer = new Konva.Layer();
|
||||
|
||||
// add the layer to the stage
|
||||
stage.add(layer);
|
||||
|
||||
// the rectangle which contains the stack nodes.
|
||||
var rect2 = new Konva.Rect({
|
||||
x: 270,
|
||||
y: 420,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 310,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
// the rectangle which contains the list.
|
||||
var rect3 = new Konva.Rect({
|
||||
x: 450,
|
||||
y: 420,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 900,
|
||||
height: 310,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect3);
|
||||
|
||||
// create a function to draw stack nodes
|
||||
function drawStackNode(x, y, label, id, value){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 100,
|
||||
height: 50,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
// name of the pointer
|
||||
var text1 = new Konva.Text({
|
||||
x: x - 50,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "node_index_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text1);
|
||||
|
||||
// content
|
||||
var text2 = new Konva.Text({
|
||||
x: x + 45,
|
||||
y: y + 20,
|
||||
text: value,
|
||||
id: "node_content_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text2);
|
||||
}
|
||||
|
||||
// create a function to draw list nodes
|
||||
function drawListNode(x, y, label, id){
|
||||
// the rectangle represents list nodes.
|
||||
let rect1 = new Konva.Rect({
|
||||
x: x,
|
||||
y: y,
|
||||
id:"list_node_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 40,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect1);
|
||||
|
||||
let rect2 = new Konva.Rect({
|
||||
x: x + 40,
|
||||
y: y,
|
||||
id:"list_node_pointer_rec_" + id,
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 80,
|
||||
height: 50,
|
||||
});
|
||||
layer.add(rect2);
|
||||
|
||||
var text = new Konva.Text({
|
||||
x: x + 15,
|
||||
y: y + 20,
|
||||
text: label,
|
||||
id: "list_node_text_" + id,
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text);
|
||||
|
||||
var arrow = new Konva.Arrow({
|
||||
points: [x+80, y+25, x+150, y+25],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "list_arrow_" + id,
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
visible: false,
|
||||
});
|
||||
layer.add(arrow);
|
||||
}
|
||||
|
||||
drawListNode(500, 460, '7', 1);
|
||||
drawListNode(650, 460, '5', 2);
|
||||
drawListNode(800, 460, '8', 3);
|
||||
drawListNode(950, 460, '1', 4);
|
||||
drawListNode(1100, 460, '9', 5);
|
||||
stage.find('#list_arrow_1').visible('true');
|
||||
stage.find('#list_arrow_2').visible('true');
|
||||
stage.find('#list_arrow_3').visible('true');
|
||||
stage.find('#list_arrow_4').visible('true');
|
||||
stage.find('#list_arrow_5').visible('true');
|
||||
|
||||
var targetPts = [1175, 485, 1250, 535, 1400, 585];
|
||||
|
||||
stage.find('#list_arrow_5').points(targetPts);
|
||||
|
||||
var text_null = new Konva.Text({
|
||||
x: 1405,
|
||||
y: 575,
|
||||
text: "NULL",
|
||||
id: "node_text_null",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_null);
|
||||
|
||||
var text_stack = new Konva.Text({
|
||||
x: 295,
|
||||
y: 380,
|
||||
text: "Stack",
|
||||
id: "node_text_stack",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_stack);
|
||||
|
||||
var text_heap = new Konva.Text({
|
||||
x: 855,
|
||||
y: 380,
|
||||
text: "Heap",
|
||||
id: "node_text_heap",
|
||||
fontSize: 20,
|
||||
fontFamily: 'Calibri',
|
||||
fill: 'black'
|
||||
});
|
||||
layer.add(text_heap);
|
||||
|
||||
var arrow_p = new Konva.Arrow({
|
||||
points: [1100, 605, 1100, 535],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: 'arrow_p',
|
||||
fill: 'yellow',
|
||||
stroke: 'yellow',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
// the node code rectangle.
|
||||
var rect1 = new Konva.Rect({
|
||||
x: 150,
|
||||
y: 30,
|
||||
id:"code_rec1",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 400,
|
||||
height: 160,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
|
||||
var nodeLabel = new Konva.Text({
|
||||
x: 280,
|
||||
y: 235,
|
||||
id:"node_label",
|
||||
text: "Node Definition",
|
||||
fontSize: 28,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
});
|
||||
|
||||
layer.add(nodeLabel);
|
||||
layer.add(rect1);
|
||||
|
||||
// the main code rectangle.
|
||||
var rect_list = new Konva.Rect({
|
||||
x: 850,
|
||||
y: 30,
|
||||
id:"code_rec_list",
|
||||
stroke: '#555',
|
||||
strokeWidth: 5,
|
||||
fill: '#ddd',
|
||||
width: 600,
|
||||
height: 160,
|
||||
shadowColor: 'black',
|
||||
shadowBlur: 10,
|
||||
shadowOffsetX: 10,
|
||||
shadowOffsetY: 10,
|
||||
shadowOpacity: 0.2,
|
||||
cornerRadius: 10,
|
||||
});
|
||||
layer.add(rect_list);
|
||||
|
||||
function makeCode(x,y,str,id) {
|
||||
return new Konva.Text({
|
||||
x: x,
|
||||
y: y,
|
||||
text: str,
|
||||
id: 'line'+id,
|
||||
fontSize: 18,
|
||||
fontFamily: 'Calibri',
|
||||
fill: '#000000',
|
||||
width: 650,
|
||||
padding: 20,
|
||||
});
|
||||
}
|
||||
|
||||
var code=[
|
||||
"0. template <class T>",
|
||||
"1. class Node {",
|
||||
"2. public:",
|
||||
"3. \t\t\t T value;",
|
||||
"4. \t\t\t Node* next;",
|
||||
"5. }",
|
||||
];
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
let t=makeCode(160,30+(i*20),code[i],i+1);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
var code_list=[
|
||||
"0. void push_front(Node<T>* & head, const T& value) {",
|
||||
"1. \t\t\t Node<T>* tmp = new Node<T>;",
|
||||
"2. \t\t\t tmp->value = value;",
|
||||
"3. \t\t\t tmp->next = head;",
|
||||
"4. \t\t\t head = tmp;",
|
||||
"5. }",
|
||||
];
|
||||
|
||||
function makeBold_list(id){
|
||||
for(let i=1; i<=code_list.length; i++){
|
||||
if(i!=id){
|
||||
// regarding the parentheses, we must add the two numbers first.
|
||||
stage.find('#line'+(i+100)).fontStyle('normal');
|
||||
}else{
|
||||
stage.find('#line'+(i+100)).fontStyle('bold');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write the code fragment into the code box.
|
||||
for (let i=0;i<code_list.length;i++){
|
||||
// the array starts from index 0, but we want ids to be counted from index 1.
|
||||
// here we add 100 so as to differentiate from the code array.
|
||||
let t=makeCode(860,30+(i*20),code_list[i],i+1+100);
|
||||
layer.add(t);
|
||||
}
|
||||
|
||||
// draw the image
|
||||
layer.draw();
|
||||
|
||||
var arrow1 = new Konva.Arrow({
|
||||
points: [310, 535, 430, 485, 495, 485],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow_1",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
var arrow2 = new Konva.Arrow({
|
||||
points: [310, 630, 430, 655, 595, 585],
|
||||
tension: 0.5,
|
||||
pointerLength: 10,
|
||||
pointerWidth: 10,
|
||||
id: "arrow_2",
|
||||
fill: 'green',
|
||||
stroke: 'green',
|
||||
strokeWidth: 5,
|
||||
});
|
||||
|
||||
var pc=1;
|
||||
// creating the list.
|
||||
function nextstep() {
|
||||
if(pc == 1){
|
||||
makeBold_list(pc);
|
||||
drawStackNode(270, 500, 'head', 1, ' ');
|
||||
drawStackNode(270, 550, 'value', 2, '4');
|
||||
// arrow 1 represents head
|
||||
layer.add(arrow1);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 2){
|
||||
makeBold_list(pc);
|
||||
drawStackNode(270, 600, 'tmp', 3, ' ');
|
||||
// the node we push front is called node 0.
|
||||
drawListNode(600, 560, '?', 0);
|
||||
// arrow 2 represents tmp
|
||||
layer.add(arrow2);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 3){
|
||||
makeBold_list(pc);
|
||||
stage.find('#list_node_text_0').text('4');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 4){
|
||||
makeBold_list(pc);
|
||||
targetPts = [680, 585, 565, 645, 460, 545, 495, 485];
|
||||
stage.find('#list_arrow_0').points(targetPts);
|
||||
stage.find('#list_arrow_0').visible('true');
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 5){
|
||||
makeBold_list(pc);
|
||||
targetPts = [310, 535, 400, 515, 595, 585];
|
||||
stage.find('#arrow_1').points(targetPts);
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 6){
|
||||
makeBold_list(pc);
|
||||
var shape = stage.find('#arrow_2');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#node_rec_3');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
shape = stage.find('#node_index_3');
|
||||
shape.to({
|
||||
opacity: 0,
|
||||
duration: 2,
|
||||
});
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}else if(pc == 7){
|
||||
makeBold_list(pc);
|
||||
alert("End of animation! Refresh the page if you want to re-run the animation.");
|
||||
layer.draw();
|
||||
pc=pc+1;
|
||||
}
|
||||
}
|
||||
|
||||
/* vim: set ts=4: */
|
||||
Reference in New Issue
Block a user