summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
Diffstat (limited to 'web')
-rw-r--r--web/Tower of Hanoi Animation by Y. Daniel Liang.html762
-rw-r--r--web/bigai/canvas_layering.html116
-rw-r--r--web/bigai/myrender.py109
-rw-r--r--web/bigai/test.html52
-rw-r--r--web/canvas-transforms.html82
-rw-r--r--web/canvas_animation.html73
-rw-r--r--web/canvas_layering.html113
-rw-r--r--web/layers/CanvasStack-2v01.js207
-rw-r--r--web/layers/index.html13
-rw-r--r--web/layers/main.js15
-rw-r--r--web/learn_canvas/bar_canvas.html50
-rw-r--r--web/learn_canvas/basics/index.html11
-rw-r--r--web/learn_canvas/basics/main.js60
-rw-r--r--web/learn_canvas/canvas_btns/example.js121
-rw-r--r--web/learn_canvas/canvas_btns/index.html43
-rw-r--r--web/learn_canvas/canvas_btns/main.js11
-rw-r--r--web/learn_canvas/canvas_btns/style.css18
-rw-r--r--web/learn_canvas/canvas_btns/test.html77
-rw-r--r--web/learn_canvas/canvas_btns/test2.html47
-rw-r--r--web/multi_layers.html24
-rw-r--r--web/multi_layers/index.html11
-rw-r--r--web/multi_layers/main.js60
22 files changed, 2075 insertions, 0 deletions
diff --git a/web/Tower of Hanoi Animation by Y. Daniel Liang.html b/web/Tower of Hanoi Animation by Y. Daniel Liang.html
new file mode 100644
index 0000000..3014467
--- /dev/null
+++ b/web/Tower of Hanoi Animation by Y. Daniel Liang.html
@@ -0,0 +1,762 @@
+<!DOCTYPE html>
+<!-- saved from url=(0065)https://yongdanielliang.github.io/animation/web/TowerOfHanoi.html -->
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <title>Tower of Hanoi Animation by Y. Daniel Liang</title>
+
+
+ <link rel="stylesheet" href="./Tower of Hanoi Animation by Y. Daniel Liang_files/jquery-ui.css">
+ <script type="text/javascript" async="" src="./Tower of Hanoi Animation by Y. Daniel Liang_files/analytics.js"></script><script src="./Tower of Hanoi Animation by Y. Daniel Liang_files/jquery-latest.js"></script>
+<!-- <script src="jquery-1.10.2.js"></script>-->
+ <script src="./Tower of Hanoi Animation by Y. Daniel Liang_files/jquery-ui.js"></script>
+ <script type="text/javascript" src="./Tower of Hanoi Animation by Y. Daniel Liang_files/GetElementPosition.js"></script>
+ <link rel="stylesheet" type="text/css" href="./Tower of Hanoi Animation by Y. Daniel Liang_files/codecolor.css">
+ <link rel="stylesheet" type="text/css" href="./Tower of Hanoi Animation by Y. Daniel Liang_files/boxes.css">
+ <script src="./Tower of Hanoi Animation by Y. Daniel Liang_files/LinkedList.js"></script>
+ <script src="./Tower of Hanoi Animation by Y. Daniel Liang_files/Queue.js"></script>
+
+ <style>
+ .status {
+ color: chocolate;
+ }
+
+ .vbar {
+ background-color: chocolate;
+ /* opacity: 0.25;*/
+ position: absolute;
+ width: 3px;
+ height: 130px;
+ padding: 3px;
+ margin-top: 0px;
+ top: 89px;
+ left: 152px;
+ }
+
+ .hbar {
+ background-color: chocolate;
+ /* opacity: 0.25;*/
+ position: absolute;
+ width: 150px;
+ height: 3px;
+ padding: 3px;
+ margin-top: 0px;
+ top: 219px;
+ left: 50px;
+ }
+
+ .towerText {
+ position: absolute;
+ color: black;
+ font-family: monospace;
+ font-size: 14px;
+ font-weight: bold;
+ }
+
+ .disc {
+ position: absolute;
+ color: #EB0D1B;
+ font-family: monospace;
+ font-size: 14px;
+ font-weight: bold;
+ border: 1px solid black;
+ height: 20px;
+ width: 50px;
+ }
+
+ #highlight {
+ background-color:#37826C;
+ opacity: 0.25;
+ position:absolute;
+ width:318px;
+ height: 10px;
+ padding: 3px;
+ margin-top: 0px;
+ top: 89px;
+ left: 72px;
+ }
+
+ #explanation {
+ color: purple;
+ position:absolute;
+ width: 158px;
+ height: 40px;
+ padding: 3px;
+ margin-top:5px;
+ top: 75px;
+ left: 448px;
+ font-size: 90%;
+ font-family: Times New Roman;
+ }
+
+ #commandPrompt {
+ font-family: times; border: 0px solid gray; text-align: left;
+ position:absolute;
+ width: 217.515px;
+ height: 10px;
+ top: 90px;
+ left: 600px;
+ font-size: 80%;
+ }
+
+ #commandPromptHeader {
+ background-color: navy; color: white; font-size: 90%;
+ border-bottom: 0px solid gray; border-right: 0px solid gray;
+ text-align: center;
+ }
+
+ #commandPromptContent {
+ background-color: white;
+ color: black;
+ width: 212px;
+ height: 40px;
+ font-family: courier;
+ font-size: 80%;
+ font-weight: bold;
+ }
+
+ #startButton {
+ display:inline;
+ width: 150px;
+ height: 30px;
+ color:#fff;
+ font-size: 14px;
+ background: #3070a8;
+ border: none;
+ }
+ </style>
+
+ <script>
+ numberOfDiscs = 6;
+
+ $(function() {
+ var spinner = $("#spinner").spinner();
+ $("#spinner").spinner({value: 3, min: 1, max: numberOfDiscs});
+
+ $("#spinner").spinner("value", 3);
+
+ $("#disable").click(function() {
+ if (spinner.spinner("option", "disabled")) {
+ spinner.spinner("enable");
+ } else {
+ spinner.spinner("disable");
+ }
+ });
+ $("#destroy").click(function() {
+ if (spinner.spinner("instance")) {
+ spinner.spinner("destroy");
+ } else {
+ spinner.spinner();
+ }
+ });
+ $("#getvalue").click(function() {
+ jAlert(spinner.spinner("value"));
+ });
+ $("#setvalue").click(function() {
+ spinner.spinner("value", 5);
+ });
+
+ $("button").button();
+ });
+
+ n = 3; // The number of discs
+ color = [];
+ color[0] = "crimson";
+ color[1] = "cornflowerblue";
+ color[2] = "beige";
+ color[3] = "purple";
+ color[4] = "aqua";
+ color[5] = "darkorange";
+ color[6] = "goldenrod";
+ color[7] = "#37826C";
+
+ number1 = 8;
+ number2 = 7;
+ answer = 15;
+ result = true;
+
+ steps = 7;
+ animationSpeed = 500;
+ slowAnimationSpeed = 1500;
+ lineOffSet = 15;
+ highLight = [];
+ highLight[0] = new HighLight();
+ highLight[0].top = 95;
+ highLight[0].left = 62;
+ highLight[0].width = 318;
+
+ highLight[1] = new HighLight();
+ highLight[1].top = 109;
+ highLight[1].left = 60 + 20;
+ highLight[1].width = 417;
+
+ highLight[2] = new HighLight();
+ highLight[2].top = 125;
+ highLight[2].left = 60 + 20;
+ highLight[2].width = 457;
+
+ highLight[3] = new HighLight();
+ highLight[3].top = 169;
+ highLight[3].left = 60 + 20;
+ highLight[3].width = 304;
+
+ highLight[4] = new HighLight();
+ highLight[4].top = 198;
+ highLight[4].left = 60 + 20;
+ highLight[4].width = 385;
+ highLight[4].height = 25;
+
+ highLight[5] = new HighLight();
+ highLight[5].top = 243;
+ highLight[5].left = 60 + 20;
+ highLight[5].width = 232;
+
+ highLight[6] = new HighLight();
+ highLight[6].top = 273;
+ highLight[6].left = 60 + 20;
+ highLight[6].width = 435;
+ highLight[6].height = 38;
+
+ highLight[7] = new HighLight();
+ highLight[7].top = 314;
+ highLight[7].width = 6;
+ highLight[7].left = 62;
+
+ explanation = [];
+ explanation[0] = new Explanation();
+ explanation[0].innerHTML = "The program starts the execution from the main method.";
+ explanation[0].top = 95;
+ explanation[0].left = 548;
+
+ explanation[1] = new Explanation();
+ explanation[1].innerHTML = "The statement generates a random number " + number1 + " and assigns it to variable number1.";
+ explanation[1].top = 107;
+ explanation[1].left = 550;
+
+ explanation[2] = new Explanation();
+ explanation[2].innerHTML = "The statement assigns a random integer to number2.";
+ explanation[2].top = 137;
+ explanation[2].left = 570;
+
+ explanation[3] = new Explanation();
+ explanation[3].innerHTML = "The statement creates an object for performing console input and assigns the object to the reference variable named input.";
+ explanation[3].top = 157;
+ explanation[3].left = 430;
+ explanation[3].width = 470;
+
+ explanation[4] = new Explanation();
+ explanation[4].innerHTML = "The statement displays a prompting message for the user input.";
+ explanation[4].top = 190;
+ explanation[4].left = 480;
+ explanation[4].width = 160;
+
+ explanation[5] = new Explanation();
+ explanation[5].innerHTML = "The statement receives an input from the user.";
+ explanation[5].top = 225;
+ explanation[5].left = 325;
+ explanation[5].width = 205;
+
+ explanation[6] = new Explanation();
+ explanation[6].innerHTML = "The statement displays the result.";
+ explanation[6].top = 257;
+ explanation[6].left = 325;
+ explanation[6].width = 205;
+
+ explanation[7] = new Explanation();
+ explanation[7].innerHTML = "The main method exits. The program is finished.";
+ explanation[7].top = 320;
+ explanation[7].left = 128;
+
+ commandPrompt = [];
+ commandPrompt[0] = new CommandPrompt();
+ commandPrompt[0].innerHTML = "";
+ commandPrompt[0].top = 95;
+ commandPrompt[0].left = 700;
+ commandPrompt[0].isVisible = false;
+ commandPrompt[1] = new CommandPrompt();
+ commandPrompt[1].isVisible = false;
+ commandPrompt[2] = new CommandPrompt();
+ commandPrompt[2].isVisible = false;
+ commandPrompt[2].innerHTML = "Enter a number for radius: ";
+ commandPrompt[2].top = 161;
+ commandPrompt[2].left = 640;
+
+ commandPrompt[3] = new CommandPrompt();
+ commandPrompt[3].isVisible = false;
+
+ commandPrompt[4] = new CommandPrompt();
+ commandPrompt[4].isVisible = true;
+ commandPrompt[4].innerHTML = "What is " + number1 + " + " + number2 + "? ";
+ commandPrompt[4].top = 200;
+ commandPrompt[4].left = 640;
+
+ commandPrompt[5] = new CommandPrompt();
+ commandPrompt[5].isVisible = true;
+ commandPrompt[5].innerHTML = commandPrompt[4].innerHTML + answer;
+ commandPrompt[5].top = 232;
+ commandPrompt[5].left = 550;
+
+ commandPrompt[6] = new CommandPrompt();
+ commandPrompt[6].isVisible = true;
+ commandPrompt[6].innerHTML = commandPrompt[5].innerHTML + "\n" + number1 + " + " + number2 + " = " + answer + " is " + result;
+ commandPrompt[6].top = 232;
+ commandPrompt[6].left = 550;
+
+ commandPrompt[7] = new CommandPrompt();
+ commandPrompt[7].isVisible = false;
+ commandPrompt[7].innerHTML = commandPrompt[6].innerHTML + "";
+ commandPrompt[7].top = 329;
+ commandPrompt[7].left = 300;
+
+ currentLine = 0;
+
+ function init() {
+ posLoc = getElementPos(document.getElementById('program'));
+ x = posLoc.x;
+ y = posLoc.y;
+
+ $("#status").hide();
+ $("#v1").css("top", y + 90).css("left", x + 115 - 3 / 2);
+ $("#v2").css("top", y + 90).css("left", x + 305 - 3 / 2);
+ $("#v3").css("top", y + 90).css("left", x + 495 - 3 / 2);
+ $("#h1").css("top", y + 220).css("left", x + 40);
+ $("#h2").css("top", y + 220).css("left", x + 230);
+ $("#h3").css("top", y + 220).css("left", x + 420);
+ $("#t1").css("top", y + 230).css("left", x + 90);
+ $("#t2").css("top", y + 230).css("left", x + 280);
+ $("#t3").css("top", y + 230).css("left", x + 470);
+
+ offset = n * 20;
+ for (var i = 1; i <= n; i++) {
+ $("#d" + i).show();
+ $("#d" + i).css("top", y + 220 - (n + 1 - i) * 20)
+ .css("background-color", color[i])
+ .css("left", x + 40 + (8 - i) * 7)
+ .css("width", 150 - (8 - i) * 14);
+ }
+
+ for (var i = 7; i > n; i--) {
+ $("#d" + i).hide(); // css("display", "none");
+ }
+ }
+ </script>
+
+<!-- Global Site Tag (gtag.js) - Google Analytics -->
+<script async="" src="./Tower of Hanoi Animation by Y. Daniel Liang_files/js"></script>
+<script>
+ window.dataLayer = window.dataLayer || [];
+ function gtag(){dataLayer.push(arguments)};
+ gtag('js', new Date());
+ gtag('config', 'UA-89940905-27');
+</script>
+
+<script type="text/javascript" src="./Tower of Hanoi Animation by Y. Daniel Liang_files/logging.js"></script>
+<style type="text/css" id="videoTapeCtxM-style-node">#videoTapeCtxM{display:block;width:auto;text-align:center;border-top:1px solid grey;box-shadow:5px 5px 5px #555;background-color:white;}#videoTapeCtxM a{border:1px solid grey;border-top:none;display:block;color:blue;width:auto;cursor:hand;margin:0px;padding:0px 3px 0px 3px;}#videoTapeCtxM a:hover{background-color:#AAA;}</style></head>
+
+
+
+ <body onload="init()" onresize="draw()" style="font-family: times new roman;" chromeextension:video-tape="true">
+ <h3 style="text-align:center; font: bold">Tower of Hanoi <a href="https://yongdanielliang.github.io/animation/animation.html">Animation</a> by
+ <a href="https://yongdanielliang.github.io/">Y. Daniel Liang</a></h3>
+ <p style="alignment-adjust: central; text-align: center; max-wdith: 800px; margin-left: auto; margin-right: auto">
+ Usage: Click the Start button to move all the discs from Tower A to Tower B. Click the Reset button to reset to the initial state.
+ </p>
+
+ <div id="program" style="width: 610px; height: 250px; font-family: courier; font-size: 100.5%; margin: 0px auto; border: 1px solid #EB0D1B; text-align: left">
+
+ <div id="v1" class="vbar" style="top: 183.438px; left: 647.5px;"></div>
+ <div id="v2" class="vbar" style="top: 183.438px; left: 837.5px;"></div>
+ <div id="v3" class="vbar" style="top: 183.438px; left: 1027.5px;"></div>
+ <div id="h1" style="left: 574px; top: 313.438px;" class="hbar"></div>
+ <div id="h2" style="left: 764px; top: 313.438px;" class="hbar"></div>
+ <div id="h3" style="left: 954px; top: 313.438px;" class="hbar"></div>
+ <div id="t1" style="left: 624px; top: 323.438px;" class="towerText">Tower A</div>
+ <div id="t2" class="towerText" style="top: 323.438px; left: 814px;">Tower B</div>
+ <div id="t3" class="towerText" style="top: 323.438px; left: 1004px;">Tower C</div>
+ <div id="d1" class="disc" style="top: 253.438px; background-color: cornflowerblue; left: 623px; width: 52px;"></div>
+ <div id="d2" class="disc" style="top: 273.438px; background-color: beige; left: 616px; width: 66px;"></div>
+ <div id="d3" class="disc" style="top: 293.438px; background-color: rgb(128, 0, 128); left: 609px; width: 80px;"></div>
+ <div id="d4" class="disc" style="display: none;"></div>
+ <div id="d5" class="disc" style="display: none;"></div>
+ <div id="d6" class="disc" style="display: none;"></div>
+<!-- <div id = "d7" class = "disc"></div>
+ <div id = "d8" class = "disc"></div>-->
+
+
+ </div>
+ <div style="text-align: center; margin-top: 1em">
+ <span style="border: 0px solid #37826C; padding: 3px">
+ <label for="spinner" style="font-weight: bold">Discs:</label>
+ <span class="ui-spinner ui-widget ui-widget-content ui-corner-all"><input id="spinner" name="value" style="width: 25px;" class="ui-spinner-input" autocomplete="off" role="spinbutton" aria-valuemin="1" aria-valuemax="6" aria-valuenow="3"><a class="ui-spinner-button ui-spinner-up ui-corner-tr ui-button ui-widget ui-state-default ui-button-text-only" tabindex="-1" role="button"><span class="ui-button-text"><span class="ui-icon ui-icon-triangle-1-n">▲</span></span></a><a class="ui-spinner-button ui-spinner-down ui-corner-br ui-button ui-widget ui-state-default ui-button-text-only" tabindex="-1" role="button"><span class="ui-button-text"><span class="ui-icon ui-icon-triangle-1-s">▼</span></span></a></span>
+
+ <button id="start" type="button" class="button ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" onclick="start()" role="button"><span class="ui-button-text">Start</span></button>
+ <button id="reset" type="button" class="button ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only" onclick="reset()" role="button"><span class="ui-button-text">Reset</span></button>
+ </span>
+ </div>
+ <div style="text-align: center; margin-top: 1em">
+ <span id="status" style="background-color: chocolate; color: white; text-align: center; margin-left: auto; margin-right: auto; display: none;">The number of moves for 3 discs is 7</span>
+ </div>
+
+ <script type="text/javascript">
+
+ $("#nextButton").click(function() {
+ currentLine = currentLine + 1;
+ step();
+ });
+ $("#prevButton").click(function() {
+ currentLine = currentLine - 1;
+ step();
+ });
+
+ count = [];
+ $("#start").click(function() {
+ if (isStarted) {
+ jAlert("Click Reset and then Start");
+ return;
+ }
+ else {
+ isStarted = true;
+ }
+
+ n = $("#spinner").val();
+ count[0] = n;
+ count[1] = 0;
+ count[2] = 0;
+ moveDisks(n, 0, 1, 2);
+ $("#status").show();
+ $("#status").text("The number of moves for " +
+ n + " discs is " + queue.getSize());
+// tuple = queue.dequeue();
+// jAlert(tuple.n + ", " + tuple.fromTower + ", " + tuple.toTower);
+ animateMoves(queue);
+ });
+
+ function animateMoves(queue) {
+ d = 0;
+ if (!queue.isEmpty()) {
+ tuple = queue.dequeue();
+// jAlert(tuple.n + ", " + tuple.fromTower + ", " + tuple.toTower);
+
+ left1 = x + (40 + 150) * tuple.toTower + 40 + (8 - tuple.n) * 7;
+ top1 = y + 220 - (count[tuple.toTower] + 1) * 20;
+ count[tuple.fromTower]--;
+ count[tuple.toTower]++;
+// jAlert( "OVER " + tuple.n + ", " + tuple.fromTower + ", " + tuple.toTower);
+
+ $("#d" + tuple.n).animate({top: y + 40}, slowAnimationSpeed, function() {
+ $("#d" + tuple.n).animate({left: left1}, slowAnimationSpeed, function() {
+ $("#d" + tuple.n).animate({top: top1, left: left1}, slowAnimationSpeed, function() {
+ animateMoves(queue);
+ });
+ });
+ });
+
+// $("#d" + tuple.n).animate({top: top1, left: left1}, slowAnimationSpeed);
+// $("#flyingReturnValue").animate({top: value1Top + 40, left: value1Left}, slowAnimationSpeed);
+ d++;
+ }
+ }
+ isStarted = false;
+ $("#reset").click(function() {
+ isStarted = false;
+ n = 3;
+ $("#spinner").val(3);
+ queue = new Queue();
+ for (var i = 1; i <= 6; i++) {
+ $("#d" + i).stop();
+ }
+ init();
+ });
+
+ $("#spinner").click(function() {
+ jAlert("clicked");
+ n = $("#spinner").val();
+ init();
+ });
+
+ $(function() {
+ var temp = $("#spinner").spinner({
+ step: 1,
+ spin: function(event, ui) {
+ handleSpinnerValue(ui.value);
+ }
+ });
+ });
+
+ function handleSpinnerValue(txtValue)
+ {
+ if (isStarted) {
+ jAlert("Please click Reset before setting the disc numbers");
+ }
+ else {
+ n = txtValue;
+ init();
+ }
+ }
+
+ function fly(n, fromTower, toTower) {
+ left1 = x + (40 + 150) * toTower + 40 + (8 - n) * 7;
+ top1 = y + 220 - (count[toTower] + 1) * 20;
+ $("#d" + n).animate({top: y + 40}, slowAnimationSpeed);
+ $("#d" + n).animate({left: left1}, slowAnimationSpeed);
+ $("#d" + n).animate({top: top1, left: left1}, slowAnimationSpeed);
+// $("#flyingReturnValue").animate({top: value1Top + 40, left: value1Left}, slowAnimationSpeed);
+ count[fromTower]--;
+ count[toTower]++;
+ }
+
+ queue = new Queue();
+ function moveDisks(n, fromTower, toTower, auxTower) {
+ if (n == 1) { // Stopping condition
+// jAlert("Move disk " + n + " from " +
+// fromTower + " to " + toTower);
+ tuple = new Object();
+ tuple.n = n;
+ tuple.toTower = toTower;
+ tuple.fromTower = fromTower;
+ queue.enqueue(tuple);
+ // fly(n, fromTower, toTower);
+ }
+ else {
+ moveDisks(n - 1, fromTower, auxTower, toTower);
+ // fly(n, fromTower, toTower);
+ tuple = new Object();
+ tuple.n = n;
+ tuple.toTower = toTower;
+ tuple.fromTower = fromTower;
+ queue.enqueue(tuple);
+ moveDisks(n - 1, auxTower, toTower, fromTower);
+ }
+ }
+
+// Constructor for Tuple
+ function Tuple(n, fromTower, toTower) {
+ this.n = n;
+ this.toTower = toTower;
+ this.fromTower = fromTower;
+ }
+
+ function startOver() {
+ init();
+// document.getElementById('nextButton').style.display = 'none';
+// document.getElementById('startOverButton').style.display = 'none';
+// document.getElementById('prevButton').style.display = 'none';
+// document.getElementById('startButton').style.visibility = 'visible';
+// document.getElementById('startButton').style.display = 'inline';
+// document.getElementById('startButton').innerHTML = 'Restart Animation';
+
+// document.getElementById('explanation').style.visibility = 'hidden';
+// document.getElementById('highlight').style.visibility = 'hidden';
+// document.getElementById('commandPrompt').style.visibility = 'hidden';
+//// document.getElementById('explanation').style.visibility = 'hidden';
+// currentPromptContent = "";
+// currentLine = 0;
+// finished = false;
+// document.getElementById('memory').style.visibility = 'hidden';
+// document.getElementById('radius').style.visibility = 'hidden';
+// document.getElementById('area').style.visibility = 'hidden';
+ }
+
+ function step() {
+ pos = getElementPos(document.getElementById('line' + currentLine));
+// $("#explanation").animate({top: explanation[currentLine].top, left: explanation[currentLine].left,
+// width: explanation[currentLine].width}, animationSpeed);
+// $("#commandPrompt").animate({top: commandPrompt[currentLine].top, left: commandPrompt[currentLine].left}, animationSpeed);
+//
+ if (currentLine == 0) {
+ document.getElementById('prevButton').style.visibility = 'hidden';
+ document.getElementById('memory').style.visibility = 'hidden';
+ document.getElementById('flyingRadius').style.visibility = 'hidden';
+ document.getElementById('flyingRadius').innerHTML = '';
+ document.getElementById('value1').innerHTML = '';
+ document.getElementById('radius').style.visibility = 'hidden';
+ $("#explanation").animate({top: pos0.y - 30,
+ left: pos0.x + pos0.w + 20,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ $("#commandPrompt").animate({top: pos2.y + 15,
+ left: pos0.x + pos0.w + 15, }, 'fast');
+ document.getElementById('commandPrompt').style.visibility = 'hidden';
+ }
+ else if (currentLine == 1) {
+ document.getElementById('prevButton').style.visibility = 'visible';
+ document.getElementById('prevButton').style.display = 'inline';
+ number1 = Math.floor(Math.random() * 10);
+ explanation[1].innerHTML = "The statement generates a random number " + number1 + " and assigns it to variable number1.";
+ document.getElementById('memory').style.visibility = 'visible';
+ document.getElementById('flyingRadius').style.visibility = 'visible';
+ document.getElementById('flyingRadius').innerHTML = '';
+ document.getElementById('value1').innerHTML = '';
+ document.getElementById('radius').style.visibility = 'visible';
+//
+// document.getElementById('value1').style.visibility = 'visible';
+
+ posLoc1 = getElementPos(document.getElementById('loc1'));
+ $("#highlight").animate({top: highLight[currentLine].top, left: highLight[currentLine].left,
+ width: highLight[currentLine].width}, animationSpeed, function() {
+ $("#flyingRadius").css("top", posLoc1.y).css("left", posLoc1.x);
+ document.getElementById('flyingRadius').innerHTML = number1;
+ $("#flyingRadius").animate(
+ {top: value1Top - 50, left: value1Left}, slowAnimationSpeed);
+ });
+ document.getElementById('flyingArea').style.visibility = 'hidden';
+ document.getElementById('value2').innerHTML = '';
+ document.getElementById('area').style.visibility = 'hidden';
+ $("#explanation").animate({top: pos.y + 30,
+ left: variableLeft,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ }
+ else if (currentLine == 2) {
+ document.getElementById('flyingArea').innerHTML = '';
+ number2 = Math.floor(Math.random() * 10);
+ explanation[2].innerHTML = "The statement generates a random number " + number2 + " and assigns it to variable number2.";
+ commandPrompt[4].innerHTML = "What is " + number1 + " + " + number2 + "? ";
+ $("#explanation").animate({top: pos.y + 15,
+ left: variableLeft,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ document.getElementById('flyingArea').style.visibility = 'visible';
+ document.getElementById('value2').innerHTML = '';
+ document.getElementById('area').style.visibility = 'visible';
+//
+// document.getElementById('value1').style.visibility = 'visible';
+
+ posLoc2 = getElementPos(document.getElementById('loc2'));
+ $("#highlight").animate({top: highLight[currentLine].top, left: highLight[currentLine].left,
+ width: highLight[currentLine].width, height: highLight[currentLine].height}, animationSpeed, function() {
+ $("#flyingArea").css("top", posLoc2.y).css("left", posLoc2.x);
+ document.getElementById('flyingArea').innerHTML = number2;
+ $("#flyingArea").animate(
+ {top: value1Top - 30, left: value1Left}, slowAnimationSpeed);
+ });
+ }
+ else if (currentLine == 3) {
+ pos3 = getElementPos(document.getElementById('line' + currentLine));
+ $("#explanation").animate({top: pos3.y - 30,
+ left: variableLeft,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ }
+ else if (currentLine == 4) {
+ document.getElementById('flyingAnswer').style.visibility = 'hidden';
+ document.getElementById('flyingAnswer').innerHTML = '';
+ document.getElementById('value3').innerHTML = '';
+ document.getElementById('answer').style.visibility = 'hidden';
+ $("#explanation").animate({top: pos3.y - 20,
+ left: variableLeft,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ pos5 = getElementPos(document.getElementById('line5'));
+ pos7 = getElementPos(document.getElementById('line7'));
+ $("#commandPrompt").animate({top: pos7.y - 10,
+ left: pos5.x + pos5.w + 45, }, 'fast');
+ }
+ else if (currentLine == 5) {
+ document.getElementById('memory').style.visibility = 'visible';
+ document.getElementById('flyingAnswer').style.visibility = 'visible';
+ document.getElementById('flyingAnswer').innerHTML = '';
+ document.getElementById('value3').innerHTML = '';
+ document.getElementById('answer').style.visibility = 'visible';
+ document.getElementById('explanation').style.visibility = 'hidden';
+ answer = prompt("Here is your chance to enter an answer for " + number1 + " + " + number2 + "? ");
+ result = (answer == number1 + number2);
+ explanation[5].innerHTML = "The statement receives the input " + answer + " from the user.";
+ commandPrompt[5].innerHTML = commandPrompt[4].innerHTML + answer;
+ commandPrompt[6].innerHTML = commandPrompt[5].innerHTML + "\n" + number1 + " + " + number2 + " = " + answer + " is " + result;
+ commandPrompt[7].innerHTML = commandPrompt[6].innerHTML + "";
+ document.getElementById('explanation').style.visibility = 'visible';
+ $("#explanation").animate({top: pos.y - 10,
+ left: pos.x + pos.w + 20,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ pos5 = getElementPos(document.getElementById('line5'));
+ pos7 = getElementPos(document.getElementById('line7'));
+ $("#commandPrompt").animate({top: pos7.y - 10,
+ left: pos5.x + pos5.w + 45, }, 'fast');
+ posLoc3 = getElementPos(document.getElementById('loc3'));
+ $("#highlight").animate({top: highLight[currentLine].top, left: highLight[currentLine].left,
+ width: highLight[currentLine].width, height: highLight[currentLine].height}, animationSpeed, function() {
+ $("#flyingAnswer").css("top", posLoc3.y).css("left", posLoc3.x);
+ document.getElementById('flyingAnswer').innerHTML = answer;
+ $("#flyingAnswer").animate({top: value1Top + 55, left: value1Left}, slowAnimationSpeed);
+ });
+ }
+ else if (currentLine == 6) {
+ $("#explanation").animate({top: pos.y - 30,
+ left: pos.x + pos.w - 140,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ $("#commandPrompt").animate({top: pos7.y - 10,
+ left: pos5.x + pos5.w + 45, }, 'fast');
+ }
+ else if (currentLine == 7) {
+ $("#explanation").animate({top: pos.y - 5,
+ left: pos.x + pos.w + 40,
+ width: 200, height: explanation[currentLine].height}, 'fast');
+ $("#commandPrompt").animate({top: pos7.y - 10,
+ left: pos5.x + pos5.w + 45, }, 'fast');
+ document.getElementById('startButton').style.visibility = 'visible';
+ document.getElementById('startButton').style.display = 'inline';
+ document.getElementById('startButton').innerHTML = 'Restart Animation';
+ }
+ else {
+ $("#highlight").animate({top: highLight[currentLine].top, left: highLight[currentLine].left,
+ width: highLight[currentLine].width, height: highLight[currentLine].height}, animationSpeed);
+ }
+
+ if (currentLine == 5) {
+ document.getElementById('commandPrompt').style.visibility = 'visible';
+ }
+
+ if (commandPrompt[currentLine].isVisible) {
+ document.getElementById('commandPrompt').style.visibility = 'visible';
+ document.getElementById('commandPromptContent').innerHTML = commandPrompt[currentLine].innerHTML;
+ }
+ else {
+ document.getElementById('commandPrompt').style.visibility = 'hidden';
+ }
+
+// if (currentLine == 0) {
+// pos = getElementPos(document.getElementById('line0'));
+// }
+// else if (currentLine == 1) {
+// pos = getElementPos(document.getElementById('line1'));
+// }
+// else if (currentLine == 2) {
+// pos = getElementPos(document.getElementById('line2'));
+// }
+// else if (currentLine == 3) {
+// pos = getElementPos(document.getElementById('line3'));
+// }
+// else if (currentLine == 4) {
+// pos = getElementPos(document.getElementById('line4'));
+// }
+// else if (currentLine == 5) {
+// pos = getElementPos(document.getElementById('line5'));
+// }
+// else if (currentLine == 6) {
+// pos = getElementPos(document.getElementById('line6'));
+// }
+// else if (currentLine == 7) {
+// pos = getElementPos(document.getElementById('line7'));
+// }
+
+ document.getElementById('explanation').innerHTML = explanation[currentLine].innerHTML;
+ $("#highlight").animate({top: pos.y, left: pos.x, width: pos.w, height: pos.h}, animationSpeed);
+ if (currentLine == steps) {
+ document.getElementById('nextButton').style.visibility = 'hidden';
+ document.getElementById('prevButton').style.visibility = 'hidden';
+ document.getElementById('memory').style.visibility = 'hidden';
+ document.getElementById('radius').style.visibility = 'hidden';
+ document.getElementById('area').style.visibility = 'hidden';
+ document.getElementById('startButton').style.visibility = 'visible';
+ document.getElementById('startButton').innerHTML = 'Restart Animation';
+ document.getElementById('flyingRadius').style.visibility = 'hidden';
+ document.getElementById('flyingArea').style.visibility = 'hidden';
+ document.getElementById('flyingAnswer').style.visibility = 'hidden';
+ document.getElementById('answer').style.visibility = 'hidden';
+ document.getElementById('flyingRadius').innerHTML = '';
+ document.getElementById('flyingArea').innerHTML = '';
+ document.getElementById('flyingAnswer').innerHTML = '';
+ currentLine = 0;
+ document.getElementById('startOverButton').style.visibility = 'hidden';
+ document.getElementById('startOverButton').style.display = 'none';
+ }
+ }
+
+ </script>
+
+
+<div><div style="display: none; position: fixed; top: 30px; width: auto; max-width: 100%; text-align: center; left: 50%; transform: translateX(-50%); z-index: 99999999;"><div style="display: inline-block; font-size: 14px; font-weight: bold; border: 1px solid rgb(240, 195, 109); background-color: rgb(249, 237, 190); padding: 0px 10px; border-radius: 2px; box-shadow: rgba(0, 0, 0, 0.2) 0px 2px 4px;"></div></div></div></body></html> \ No newline at end of file
diff --git a/web/bigai/canvas_layering.html b/web/bigai/canvas_layering.html
new file mode 100644
index 0000000..669fdf9
--- /dev/null
+++ b/web/bigai/canvas_layering.html
@@ -0,0 +1,116 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="UTF-8"/>
+ <title>Canvas Layers Test</title>
+</head>
+<body>
+<section>
+ <!--<div id="canvasesdiv" style="position:relative; width:400px; height:300px">-->
+ <canvas id="layer1"
+ style="z-index: 1;
+ position:absolute;
+ left:0px;
+ top:0px;
+ border: 5px, solid;
+ "
+ height="200px" width="300">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+
+ <canvas id="layer2"
+ style="z-index: 2;
+ position:absolute;
+ left:100px;
+ top:0px;
+ border: 5px, solid;
+ "
+ height="50px" width="50">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+
+ <canvas id="layer3"
+ style="z-index: 3;
+ position:absolute;
+ left:0px;
+ top:0px;
+ border: 5px, solid;
+ "
+ height="100px" width="200">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+ <!--</div>-->
+
+ <script type="text/javascript">
+ var layer1; var ctx1;
+ var layer2; var ctx2;
+ var layer3; var ctx3;
+
+ var x = 400;
+ var y = 300;
+ var dx = 2;
+ var dy = 4;
+ var WIDTH = 400;
+ var HEIGHT = 300;
+ var city = new Image();
+
+ function init() {
+ city.src ="city.png";
+ layer1 = document.getElementById("layer1");
+ ctx1 = layer1.getContext("2d");
+ layer2 = document.getElementById("layer2");
+ ctx2 = layer2.getContext("2d");
+ layer3 = document.getElementById("layer3");
+ ctx3 = layer3.getContext("2d");
+ setInterval(drawAll, 20);
+ }
+
+ function drawAll() {
+ draw1();
+ draw2();
+ draw3();
+ }
+
+ function draw1() {
+ ctx1.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx1.fillStyle = "#FAF7F8";
+ ctx1.beginPath();
+ ctx1.rect(0, 0, WIDTH, HEIGHT);
+ ctx1.closePath();
+ ctx1.fill();
+ ctx1.fillStyle = "#444444";
+ ctx1.beginPath();
+ ctx1.arc(x, y, 10, 0, Math.PI*2, true);
+ ctx1.closePath();
+ ctx1.fill();
+
+ if (x + dx > WIDTH || x + dx < 0)
+ dx = -dx;
+ if (y + dy > HEIGHT || y + dy < 0)
+ dy = -dy;
+
+ x += dx;
+ y += dy;
+ }
+
+ function draw2() {
+ ctx2.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx2.drawImage(city, 0, 0);
+ }
+
+ function draw3() {
+ ctx3.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx3.fillStyle = "#444444";
+ ctx3.save();
+ ctx3.translate(200,200);
+ ctx3.rotate(x/20);
+ ctx3.fillRect(-15, -15, 30, 30);
+ ctx3.restore();
+ }
+
+ init();
+
+ </script>
+</section>
+</body>
+</html> \ No newline at end of file
diff --git a/web/bigai/myrender.py b/web/bigai/myrender.py
new file mode 100644
index 0000000..d49e69b
--- /dev/null
+++ b/web/bigai/myrender.py
@@ -0,0 +1,109 @@
+import gym
+from gym.envs.classic_control import rendering
+import math
+from pyglet.gl import *
+import pyglet
+
+class Attr(object):
+ def enable(self):
+ raise NotImplementedError
+ def disable(self):
+ pass
+
+
+class Color(Attr):
+ def __init__(self, vec4):
+ self.vec4 = vec4
+ def enable(self):
+ glColor4f(*self.vec4)
+p
+class Geom(object):
+ def __init__(self):
+ self._color=Color((0, 0, 0, 1.0))
+ self.attrs = [self._color]
+ def render(self):
+ for attr in reversed(self.attrs):
+ attr.enable()
+ self.render1()
+ for attr in self.attrs:
+ attr.disable()
+ def render1(self):
+ raise NotImplementedError
+ def add_attr(self, attr):
+ self.attrs.append(attr)
+ def set_color(self, r, g, b, alpha=1):
+ self._color.vec4 = (r, g, b, alpha)
+
+
+class FilledPolygon(Geom):
+ def __init__(self, v):
+ Geom.__init__(self)
+ self.v = v
+ def render1(self):
+ if len(self.v) == 4 : glBegin(GL_QUADS)
+ elif len(self.v) > 4 : glBegin(GL_POLYGON)
+ else: glBegin(GL_TRIANGLES)
+ for p in self.v:
+ glVertex3f(p[0], p[1],0) # draw each vertex
+ glEnd()
+
+ color = (self._color.vec4[0] * 0.5, self._color.vec4[1] * 0.5, self._color.vec4[2] * 0.5, self._color.vec4[3] * 0.5)
+ glColor4f(*color)
+ glBegin(GL_LINE_LOOP)
+ for p in self.v:
+ glVertex3f(p[0], p[1],0) # draw each vertex
+ glEnd()
+
+
+class MyEnv(gym.Env):
+ metadata = {
+ 'render.modes': ['human', 'rgb_array'],
+ 'videos.frames_per_second': 2
+ }
+
+ def __init__(self):
+ self.viewer = rendering.Viewer(800, 600)
+
+ # def render(self, mode='human', close=False):
+ # line1 = rendering.Line((100, 300), (500, 300))
+ # line2 = rendering.Line((100, 200), (500, 200))
+ # line1.set_color(0, 0, 0)
+ # line2.set_color(0, 0, 0)
+ # self.viewer.add_geom(line1)
+ # self.viewer.add_geom(line2)
+ # return self.viewer.render(return_rgb_array=mode == 'rgb_array')
+
+ def make_agent(self):
+ radius = 10
+ res = 30
+ WORLD_WIDTH = 10
+ visual_distance = 100
+ points = []
+ for i in range(res):
+ ang = 2*math.pi*i/res
+ points.append([math.cos(ang)*radius, math.sin(ang)*radius])
+ for i in range(9):
+ ang = 2 * math.pi * (i - 4) / res
+ points.append((math.cos(ang) * visual_distance + radius, math.sin(ang) * visual_distance))
+ return points
+
+
+ # def render(self, mode='human', close=False):
+ # circle = rendering.make_circle(30)
+ # circle_transform = rendering.Transform(translation=(100, 100))
+ # circle.add_attr(circle_transform)
+ # self.viewer.add_geom(circle)
+ # return self.viewer.render(return_rgb_array=mode == 'rgb_array')
+
+ def render(self, mode='human'):
+ agent_points = self.make_agent()
+ agent = FilledPolygon(agent_points)
+ trans = rendering.Transform(translation=(200, 200))
+ agent.add_attr(trans)
+ self.viewer.add_geom(agent)
+ return self.viewer.render(return_rgb_array=mode == 'rgb_array')
+
+if __name__ == '__main__':
+ env = MyEnv()
+ while True:
+ env.render()
diff --git a/web/bigai/test.html b/web/bigai/test.html
new file mode 100644
index 0000000..abc1d15
--- /dev/null
+++ b/web/bigai/test.html
@@ -0,0 +1,52 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+ <title></title>
+ <script language="javascript">
+ window.onload = function () {
+ var landscape_canvas = document.getElementById("landscape");
+ var ctx = landscape_canvas.getContext("2d");
+ ctx.fillStyle = "Blue";
+ <!--ctx.fillRect(0, 0, 800, 850);-->
+
+ //Cone
+ ctx.fillStyle = "#67ff30";
+ ctx.beginPath();
+ ctx.moveTo(150, 250);
+ ctx.lineTo(300, 20);
+ ctx.lineTo(450, 250);
+ ctx.lineTo(150, 250);
+ ctx.fill();
+ ctx.closePath();
+ ctx.fillStyle = "Brown";
+ ctx.beginPath();
+ ctx.moveTo(400, 250);
+ ctx.lineTo(450, 80);
+ ctx.lineTo(600, 250);
+ ctx.lineTo(400, 250);
+ ctx.fill();
+ ctx.closePath();
+ ctx.beginPath();
+ // get 2 canvas
+ <!--var landscape_canvas = document.getElementById("landscape1");-->
+ <!--var ctx = landscape_canvas.getContext("2d");-->
+ <!--ctx.fillStyle = "blue";-->
+ <!--ctx.fillRect(0, 0, 600, 450);-->
+ <!--ctx.beginPath();-->
+ <!--ctx.fillStyle = "black";-->
+ <!--ctx.moveTo(75, 25);-->
+ <!--ctx.quadraticCurveTo(25, 25, 25, 62.5);-->
+ <!--ctx.quadraticCurveTo(25, 100, 50, 100);-->
+ <!--ctx.quadraticCurveTo(50, 120, 30, 125);-->
+ <!--ctx.quadraticCurveTo(60, 120, 65, 100);-->
+ <!--ctx.quadraticCurveTo(125, 100, 125, 62.5);-->
+ <!--ctx.quadraticCurveTo(125, 25, 75, 25);-->
+ <!--ctx.stroke();-->
+ <!--ctx.beginPath();-->
+ }
+ </script>
+</head>
+<body>
+<canvas id="landscape" width="800" height="350"></canvas>
+<canvas id="landscape1" width="800" height="150"></canvas>
+</body>
+</html> \ No newline at end of file
diff --git a/web/canvas-transforms.html b/web/canvas-transforms.html
new file mode 100644
index 0000000..bfdbe80
--- /dev/null
+++ b/web/canvas-transforms.html
@@ -0,0 +1,82 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
+ <title>Canvas Rotation</title>
+ <style>
+ html{
+ background-color: #999;
+ }
+ #canvas{
+ background-color: #fff;
+ border: 1px solid #333;
+ width: 70%;
+ margin: 1rem auto;
+ display: block;
+ }
+ </style>
+</head>
+<body>
+ <canvas id="canvas"></canvas>
+ <script>
+ let canvas, ctx;
+
+ document.addEventListener('DOMContentLoaded', ()=>{
+ canvas = document.getElementById('canvas');
+ ctx = canvas.getContext('2d');
+ canvas.width = 600;
+ canvas.height = 800;
+ ctx.fillStyle = 'cornflowerblue';
+ ctx.strokeStyle = '#ccc';
+ ctx.lineWidth = 2;
+ ctx.textAlign = 'start';
+ ctx.font = 'normal 30px Arial';
+ drawGrid(100);
+
+ let x = 100;
+ let y = 100;
+ ctx.save(); //creates a save point
+ ctx.beginPath();
+ ctx.translate(200, 200);
+ ctx.fillText('translate', 10, 30);
+ ctx.fill();
+ ctx.closePath();
+ ctx.restore(); //go back to the last save point
+
+ ctx.save();
+ ctx.beginPath();
+ ctx.arc(0, 0, 10, 0, Math.PI*2);
+ ctx.rotate(Math.PI/4); //3.14 radians 180 deg
+ ctx.fillText('rotate', 300, 0);
+ ctx.fill();
+ ctx.closePath();
+ ctx.restore();
+
+ ctx.beginPath();
+ ctx.translate(100, 500);
+ ctx.scale(1, -1);
+ ctx.fillText('scale', x, y);
+ ctx.fill();
+ ctx.closePath();
+
+
+ });
+
+ function drawGrid(gap){
+ ctx.beginPath();
+ for(x=gap; x<canvas.width; x=x+gap){
+ ctx.moveTo(x, 0);
+ ctx.lineTo(x, canvas.height);
+ }
+ for(let y=gap; y<canvas.height; y=y+gap){
+ ctx.moveTo(0, y);
+ ctx.lineTo(canvas.height, y);
+ }
+ ctx.stroke();
+ ctx.closePath();
+ }
+ </script>
+</body>
+</html> \ No newline at end of file
diff --git a/web/canvas_animation.html b/web/canvas_animation.html
new file mode 100644
index 0000000..205f8fe
--- /dev/null
+++ b/web/canvas_animation.html
@@ -0,0 +1,73 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="UTF-8"/>
+ <title>Canvas Test</title>
+</head>
+<body>
+<section>
+ <div>
+ <canvas id="canvas" width="400" height="300">
+ This text is displayed if your browser
+ does not support HTML5 Canvas.
+ </canvas>
+ </div>
+
+ <script type="text/javascript">
+ var canvas;
+ var ctx;
+ var x = 200;
+ var y = 150;
+ var dx = 2;
+ var dy = 4;
+ var WIDTH = 200;
+ var HEIGHT = 150;
+
+ function circle(x,y,r) {
+ ctx.beginPath();
+ ctx.arc(x, y, r, 0, Math.PI*2, false);
+ ctx.fill();
+ }
+
+ function rect(x,y,w,h) {
+ ctx.beginPath();
+ ctx.rect(x,y,w,h);
+ ctx.closePath();
+ ctx.fill();
+ }
+
+
+ function clear() {
+ ctx.clearRect(0, 0, WIDTH, HEIGHT);
+ }
+
+ function init() {
+ canvas = document.getElementById("canvas");
+ ctx = canvas.getContext("2d");
+ return setInterval(draw, 100);
+ }
+
+
+ function draw() {
+ clear();
+ ctx.fillStyle = "#FAF7F8";
+ rect(0,0,WIDTH,HEIGHT);
+ ctx.fillStyle = "#444444";
+ circle(x, y, 20);
+
+ if (x + dx > WIDTH || x + dx < 0)
+ dx = -dx;
+ if (y + dy > HEIGHT || y + dy < 0)
+ dy = -dy;
+
+ x += dx;
+ y += dy;
+ }
+
+ init();
+
+ </script>
+
+</section>
+</body>
+</html> \ No newline at end of file
diff --git a/web/canvas_layering.html b/web/canvas_layering.html
new file mode 100644
index 0000000..6214009
--- /dev/null
+++ b/web/canvas_layering.html
@@ -0,0 +1,113 @@
+<!doctype html>
+<html>
+<head>
+ <meta charset="UTF-8"/>
+ <title>Canvas Layers Test</title>
+</head>
+<body>
+<section>
+ <div id="canvasesdiv" style="position:relative; width:400px; height:300px">
+ <canvas id="layer1"
+ style="z-index: 1;
+ position:absolute;
+ left:0px;
+ top:0px;
+ "
+ height="300px" width="400">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+
+ <canvas id="layer2"
+ style="z-index: 2;
+ position:absolute;
+ left:0px;
+ top:0px;
+ "
+ height="300px" width="400">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+
+ <canvas id="layer3"
+ style="z-index: 3;
+ position:absolute;
+ left:0px;
+ top:0px;
+ "
+ height="300px" width="400">
+ This text is displayed if your browser does not support HTML5 Canvas.
+ </canvas>
+ </div>
+
+ <script type="text/javascript">
+ var layer1; var ctx1;
+ var layer2; var ctx2;
+ var layer3; var ctx3;
+
+ var x = 400;
+ var y = 300;
+ var dx = 2;
+ var dy = 4;
+ var WIDTH = 400;
+ var HEIGHT = 300;
+ var city = new Image();
+
+ function init() {
+ city.src ="city.png";
+ layer1 = document.getElementById("layer1");
+ ctx1 = layer1.getContext("2d");
+ layer2 = document.getElementById("layer2");
+ ctx2 = layer2.getContext("2d");
+ layer3 = document.getElementById("layer3");
+ ctx3 = layer3.getContext("2d");
+ setInterval(drawAll, 20);
+ }
+
+ function drawAll() {
+ draw1();
+ draw2();
+ draw3();
+ }
+
+ function draw1() {
+ ctx1.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx1.fillStyle = "#FAF7F8";
+ ctx1.beginPath();
+ ctx1.rect(0, 0, WIDTH, HEIGHT);
+ ctx1.closePath();
+ ctx1.fill();
+ ctx1.fillStyle = "#444444";
+ ctx1.beginPath();
+ ctx1.arc(x, y, 10, 0, Math.PI*2, true);
+ ctx1.closePath();
+ ctx1.fill();
+
+ if (x + dx > WIDTH || x + dx < 0)
+ dx = -dx;
+ if (y + dy > HEIGHT || y + dy < 0)
+ dy = -dy;
+
+ x += dx;
+ y += dy;
+ }
+
+ function draw2() {
+ ctx2.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx2.drawImage(city, 0, 0);
+ }
+
+ function draw3() {
+ ctx3.clearRect(0, 0, WIDTH, HEIGHT);
+ ctx3.fillStyle = "#444444";
+ ctx3.save();
+ ctx3.translate(200,200);
+ ctx3.rotate(x/20);
+ ctx3.fillRect(-15, -15, 30, 30);
+ ctx3.restore();
+ }
+
+ init();
+
+ </script>
+</section>
+</body>
+</html> \ No newline at end of file
diff --git a/web/layers/CanvasStack-2v01.js b/web/layers/CanvasStack-2v01.js
new file mode 100644
index 0000000..1d8b328
--- /dev/null
+++ b/web/layers/CanvasStack-2v01.js
@@ -0,0 +1,207 @@
+/*=============================================================
+ Filename: CanvasStack-2v01.js
+ Rev: 2
+ By: A.R.Collins
+ Description: Utilities to create multiple transparent
+ canvas layers suitable for animation.
+ License: Released into the public domain
+ latest version at
+ <http://www/arc.id.au/CanvasLayers.html>
+
+ Date |Description |By
+ -------------------------------------------------------------
+ 30Oct09 Rev 1.00 First release ARC
+ 08Sep12 bugfix: test for emulator failed in IE9 ARC
+ 02Mar13 Re-write to use screen canvas as background ARC
+ 28Jul13 remove getOverlayCanvas (use getElementById)
+ Tidy for JSLint ARC
+ 20Jul14 Setup a resize handler for layers, required when
+ canvas size changes on window resize (width in %).
+ Dropped excanvas support ARC
+ 18Sep19 Re-factor to simplify ARC
+ 21Sep19 Convert to Classes etc ARC
+ 30Sep19 Added addResizeCallback method
+ Released as Rev 2v00 ARC
+ 01Jan20 Add Layer.dragObjects to match Cango Layer ARC
+ =============================================================*/
+
+var CanvasStack;
+
+(function()
+{
+ "use strict";
+
+ class Layer
+ {
+ constructor(canvasID, canvasElement)
+ {
+ this.id = canvasID;
+ this.cElem = canvasElement;
+ this.dragObjects = [];
+ }
+ }
+
+ CanvasStack = class{
+ constructor(cvsID, stackLimit){
+ const savThis = this;
+
+ function setResizeHandler(resizeLayers, timeout){
+ let timer_id = undefined;
+ window.addEventListener("resize", ()=>{
+ if(timer_id != undefined)
+ {
+ clearTimeout(timer_id);
+ timer_id = undefined;
+ }
+ timer_id = setTimeout(()=>{
+ timer_id = undefined;
+ resizeLayers();
+ savThis.bkgCanvas.resizeFns.forEach((currFn)=>currFn());
+ }, timeout);
+ });
+ }
+
+ function resizeLayers(){
+ const t = savThis.bkgCanvas.offsetTop + savThis.bkgCanvas.clientTop,
+ l = savThis.bkgCanvas.offsetLeft + savThis.bkgCanvas.clientLeft,
+ w = savThis.bkgCanvas.offsetWidth,
+ h = savThis.bkgCanvas.offsetHeight;
+
+ // check if canvas size changed when window resized, allow some rounding error in layout calcs
+ if ((Math.abs(w - savThis.rawWidth)/w < 0.01) && (Math.abs(h - savThis.rawHeight)/h < 0.01))
+ {
+ // canvas size didn't change so return
+ return;
+ }
+ // canvas has been resized so resize all the overlay canvases
+ for (let j=1; j<savThis.bkgCanvas.layers.length; j++) // bkg is layer[0]
+ {
+ let ovl = savThis.bkgCanvas.layers[j].cElem;
+ if (ovl) // may have been deleted so empty slot
+ {
+ ovl.style.top = t+'px';
+ ovl.style.left = l+'px';
+ ovl.style.width = w+'px';
+ ovl.style.height = h+'px';
+ ovl.width = w; // reset canvas attribute to pixel width
+ ovl.height = h;
+ }
+ }
+ }
+
+ // check if this is a context for an overlay
+ if (cvsID.indexOf("_ovl_") !== -1)
+ {
+ console.error("CanvasStack: canvas must be a background canvas not an overlay");
+ return {};
+ }
+
+ this.cId = cvsID;
+ this.stackLimit = stackLimit || 6;
+ this.bkgCanvas = document.getElementById(cvsID);
+ this.rawWidth = this.bkgCanvas.offsetWidth;
+ this.rawHeight = this.bkgCanvas.offsetHeight;
+ this.bkgCanvas.resizeFns = [];
+
+ if (!this.bkgCanvas.hasOwnProperty('layers'))
+ {
+ // create an array to hold all the overlay canvases for this canvas
+ this.bkgCanvas.layers = [];
+ // make a Layer object for the bkgCanvas
+ let bkgL = new Layer(this.cId, this.bkgCanvas); // bkgCanvas is always layer[0]
+ this.bkgCanvas.layers[0] = bkgL;
+ // make sure the overlay canvases always match the bkgCanvas size
+ setResizeHandler(resizeLayers, 250);
+ }
+ if (!this.bkgCanvas.hasOwnProperty('unique'))
+ {
+ this.bkgCanvas.unique = 0;
+ }
+ }
+
+ createLayer(){
+ const w = this.rawWidth,
+ h = this.rawHeight,
+ nLyrs = this.bkgCanvas.layers.length; // bkg is layer 0 so at least 1
+
+ // check background canvas is still there
+ if (!(this.bkgCanvas && this.bkgCanvas.layers))
+ {
+ console.log("CanvasStack: missing background canvas");
+ return;
+ }
+ if (this.bkgCanvas.layers.length >= this.stackLimit)
+ {
+ console.error("CanvasStack: too many layers");
+ return;
+ }
+ this.bkgCanvas.unique += 1; // a private static variable
+ const uniqueTag = this.bkgCanvas.unique.toString();
+ const ovlId = this.cId+"_ovl_"+uniqueTag;
+ const ovlHTML = "<canvas id='"+ovlId+"' style='position:absolute' width='"+w+"' height='"+h+"'></canvas>";
+ const topCvs = this.bkgCanvas.layers[nLyrs-1].cElem;
+ topCvs.insertAdjacentHTML('afterend', ovlHTML);
+ const newCvs = document.getElementById(ovlId);
+ newCvs.style.backgroundColor = "transparent";
+ newCvs.style.left = (this.bkgCanvas.offsetLeft+this.bkgCanvas.clientLeft)+'px';
+ newCvs.style.top = (this.bkgCanvas.offsetTop+this.bkgCanvas.clientTop)+'px';
+ // make it the same size as the background canvas
+ newCvs.style.width = this.bkgCanvas.offsetWidth+'px';
+ newCvs.style.height = this.bkgCanvas.offsetHeight+'px';
+ let newL = new Layer(ovlId, newCvs);
+ // save the ID in an array to facilitate removal
+ this.bkgCanvas.layers.push(newL);
+
+ return ovlId; // return the new canvas id
+ }
+
+ deleteLayer(ovlyId){
+ // check background canvas is still there
+ if (!(this.bkgCanvas && this.bkgCanvas.layers))
+ {
+ console.log("CanvasStack: missing background canvas");
+ return;
+ }
+ for (let i=1; i<this.bkgCanvas.layers.length; i++)
+ {
+ if (this.bkgCanvas.layers[i].id === ovlyId)
+ {
+ let ovlNode = this.bkgCanvas.layers[i].cElem;
+ if (ovlNode)
+ {
+ ovlNode.parentNode.removeChild(ovlNode);
+ }
+ // now delete layers array element
+ this.bkgCanvas.layers.splice(i,1); // delete the Layer object
+ }
+ }
+ }
+
+ deleteAllLayers(){
+ // check background canvas is still there
+ if (!(this.bkgCanvas && this.bkgCanvas.layers))
+ {
+ console.log("CanvasStack: missing background canvas");
+ return;
+ }
+ for (let i=this.bkgCanvas.layers.length-1; i>0; i--) // don't delete layers[0] its the bakg canavs
+ {
+ let ovlNode = this.bkgCanvas.layers[i].cElem;
+ if (ovlNode)
+ {
+ let orphan = ovlNode.parentNode.removeChild(ovlNode);
+ orphan = null;
+ }
+ // now delete layers array element
+ this.bkgCanvas.layers.splice(i,1);
+ }
+ // clear any resize callbacks, the layers are gone
+ this.bkgCanvas.resizeFns.length = 0; // remove any added handlers, leave the basic
+ }
+
+ addResizeCallback(callbackFn){
+ this.bkgCanvas.resizeFns.push(callbackFn);
+ }
+ };
+
+}());
diff --git a/web/layers/index.html b/web/layers/index.html
new file mode 100644
index 0000000..e30c96a
--- /dev/null
+++ b/web/layers/index.html
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
+ <title>Document</title>
+ <script src="CanvasStack-2v01.js"></script>
+
+</head>
+<body>
+ <canvas id="canvas"></canvas>
+ <script src="main.js"></script>
+</body>
+</html> \ No newline at end of file
diff --git a/web/layers/main.js b/web/layers/main.js
new file mode 100644
index 0000000..6bab236
--- /dev/null
+++ b/web/layers/main.js
@@ -0,0 +1,15 @@
+
+var canvas = document.getElementById("canvas");
+var ctx = canvas.getContext("2d");
+
+canvas.width = window.innerWidth;
+canvas.height = window.innerHeight;
+
+var stack = new CanvasStack();
+var layer1 = stack.createLayer();
+var ctx1 = document.getElementById(layer1).getContext("2d");
+
+ctx1.fillRect(0, 0, 100, 100);
+
+
+
diff --git a/web/learn_canvas/bar_canvas.html b/web/learn_canvas/bar_canvas.html
new file mode 100644
index 0000000..c2d7518
--- /dev/null
+++ b/web/learn_canvas/bar_canvas.html
@@ -0,0 +1,50 @@
+<html>
+<head>
+
+<script>
+ function draw() {
+ /* Accepting and seperating comma seperated values */
+ var n = document.getElementById("num").value;
+ var values = n.split(',');
+
+ var canvas = document.getElementById('myCanvas');
+ var ctx = canvas.getContext('2d');
+
+ var width = 40; //bar width
+ var X = 50; // first bar position
+ var base = 200;
+
+ for (var i =0; i<values.length; i++) {
+ ctx.fillStyle = '#008080';
+ var h = values[i];
+ ctx.fillRect(X,canvas.height - h,width,h);
+
+ X += width+15;
+ /* text to display Bar number */
+ ctx.fillStyle = '#4da6ff';
+ ctx.fillText('Bar '+i,X-50,canvas.height - h -10);
+ }
+ /* Text to display scale */
+ ctx.fillStyle = '#000000';
+ ctx.fillText('Scale X : '+canvas.width+' Y : '+canvas.height,800,10);
+
+ }
+ function reset(){
+ var canvas = document.getElementById('myCanvas');
+ var ctx = canvas.getContext('2d');
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
+ }
+</script>
+</head>
+<body align="center">
+
+
+ Enter the values seperated by a comma<br>
+ <input type="text" name="number" id="num"><br>
+ <input type="button" value="submit" name="submit" onclick="draw()">
+ <input type="button" value="Clear" name="Clear" onclick="reset()"><br><br>
+ <canvas id="myCanvas" width="900" height="500" style="border:1px solid #c3c3c3;">
+ </canvas>
+
+</body>
+</html>
diff --git a/web/learn_canvas/basics/index.html b/web/learn_canvas/basics/index.html
new file mode 100644
index 0000000..3c0cfb8
--- /dev/null
+++ b/web/learn_canvas/basics/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Title</title>
+</head>
+<body>
+ <canvas id="canvas"></canvas>
+</body>
+<script src="main.js"></script>
+</html> \ No newline at end of file
diff --git a/web/learn_canvas/basics/main.js b/web/learn_canvas/basics/main.js
new file mode 100644
index 0000000..5aa6458
--- /dev/null
+++ b/web/learn_canvas/basics/main.js
@@ -0,0 +1,60 @@
+let canvas = document.getElementById("canvas");
+let ctx = canvas.getContext("2d");
+
+var win_height = window.innerHeight;
+var win_width = window.innerWidth;
+
+canvas.height = win_height;
+canvas.width = win_width;
+console.log(canvas.width, canvas.height);
+
+canvas.style.background = "#bbf";
+
+
+class Circle {
+ constructor(context, xpos, ypos, radius, color) {
+ this.context = context;
+ this.xpos = xpos;
+ this.ypos = ypos;
+ this.radius = radius;
+ this.color = color;
+ }
+ draw() {
+ this.context.beginPath();
+ this.context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI*2, this.color);
+ this.context.strokeStyle = "grey";
+ this.context.lineWidth = 15;
+ this.context.fillStyle = this.color;
+ this.context.fill();
+ this.context.stroke();
+ this.context.closePath();
+ }
+ clickCircle(xmouse, ymouse) {
+ const distance = Math.sqrt((xmouse - this.xpos) * (xmouse - this.xpos) + (ymouse - this.ypos) * (ymouse - this.ypos));
+ if (distance <= this.radius) {
+ return true;
+ }
+ return false;
+ }
+ changeColor (newColor) {
+ this.color = newColor;
+ this.draw();
+ }
+}
+
+
+let circle = new Circle(ctx, 200, 200, 100, "blue");
+circle.draw(ctx);
+canvas.addEventListener("click", (event) => {
+// console.log(event);
+// console.log("clicked canvas");
+ const rect = canvas.getBoundingClientRect();
+ const x = event.clientX - rect.left;
+ const y = event.clientY - rect.top;
+ if (circle.clickCircle(x, y)) {
+ circle.changeColor("red");
+ } else {
+ circle.changeColor("blue");
+ }
+// console.log(rect);
+});
diff --git a/web/learn_canvas/canvas_btns/example.js b/web/learn_canvas/canvas_btns/example.js
new file mode 100644
index 0000000..0722613
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/example.js
@@ -0,0 +1,121 @@
+var canvas = document.getElementById('canvas'),
+ context = canvas.getContext('2d'),
+ rubberbandDiv = document.getElementById('rubberbandDiv'),
+ resetButton = document.getElementById('resetButton'),
+ image = new Image(),
+ mousedown = {},
+ rubberbandRectangle = {},
+ dragging = false;
+
+// Functions..........................................................
+
+function rubberbandStart(x, y) {
+ mousedown.x = x;
+ mousedown.y = y;
+
+ rubberbandRectangle.left = mousedown.x;
+ rubberbandRectangle.top = mousedown.y;
+
+ moveRubberbandDiv();
+ showRubberbandDiv();
+
+ dragging = true;
+}
+
+function rubberbandStretch(x, y) {
+ rubberbandRectangle.left = x < mousedown.x ? x : mousedown.x;
+ rubberbandRectangle.top = y < mousedown.y ? y : mousedown.y;
+
+ rubberbandRectangle.width = Math.abs(x - mousedown.x),
+ rubberbandRectangle.height = Math.abs(y - mousedown.y);
+
+ moveRubberbandDiv();
+ resizeRubberbandDiv();
+}
+
+function rubberbandEnd() {
+ var bbox = canvas.getBoundingClientRect();
+
+ try {
+ context.drawImage(canvas,
+ rubberbandRectangle.left - bbox.left,
+ rubberbandRectangle.top - bbox.top,
+ rubberbandRectangle.width,
+ rubberbandRectangle.height,
+ 0, 0, canvas.width, canvas.height);
+ }
+ catch (e) {
+ // Suppress error message when mouse is released
+ // outside the canvas
+ }
+
+ resetRubberbandRectangle();
+
+ rubberbandDiv.style.width = 0;
+ rubberbandDiv.style.height = 0;
+
+ hideRubberbandDiv();
+
+ dragging = false;
+}
+
+function moveRubberbandDiv() {
+ rubberbandDiv.style.top = rubberbandRectangle.top + 'px';
+ rubberbandDiv.style.left = rubberbandRectangle.left + 'px';
+}
+
+function resizeRubberbandDiv() {
+ rubberbandDiv.style.width = rubberbandRectangle.width + 'px';
+ rubberbandDiv.style.height = rubberbandRectangle.height + 'px';
+}
+
+function showRubberbandDiv() {
+ rubberbandDiv.style.display = 'inline';
+}
+
+function hideRubberbandDiv() {
+ rubberbandDiv.style.display = 'none';
+}
+
+function resetRubberbandRectangle() {
+ rubberbandRectangle = { top: 0, left: 0, width: 0, height: 0 };
+}
+
+// Event handlers.....................................................
+
+canvas.onmousedown = function (e) {
+ var x = e.clientX,
+ y = e.clientY;
+
+ e.preventDefault();
+ rubberbandStart(x, y);
+};
+
+window.onmousemove = function (e) {
+ var x = e.clientX,
+ y = e.clientY;
+
+ e.preventDefault();
+ if (dragging) {
+ rubberbandStretch(x, y);
+ }
+};
+
+window.onmouseup = function (e) {
+ e.preventDefault();
+ rubberbandEnd();
+};
+
+image.onload = function () {
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
+};
+
+resetButton.onclick = function(e) {
+ context.clearRect(0, 0, context.canvas.width,
+ context.canvas.height);
+ context.drawImage(image, 0, 0, canvas.width, canvas.height);
+};
+
+// Initialization.....................................................
+
+image.src = 'curved-road.png'; \ No newline at end of file
diff --git a/web/learn_canvas/canvas_btns/index.html b/web/learn_canvas/canvas_btns/index.html
new file mode 100644
index 0000000..9509727
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/index.html
@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Title</title>
+ <style>
+ #container
+ {
+ height: 400px;
+ position: relative;
+ width: 400px;
+ }
+ <!--#viewport-->
+ <!--{-->
+ <!--height: 100%;-->
+ <!--width: 100%;-->
+ <!--}-->
+ #controls
+ {
+ top: 0;
+ left: 0;
+ position: absolute;
+ width: 100%;
+ }
+ </style>
+</head>
+<body>
+
+<!--<div id="container">-->
+ <!--<canvas id="viewport">-->
+ <!--</canvas>-->
+ <!--<menu id="controls">-->
+ <!--<button onclick="copy()">belief</button>-->
+ <!--<button onclick="cut()">intents</button>-->
+ <!--</menu>-->
+<!--</div>-->
+<canvas id="viewport" style="z-index:1"></canvas>
+<input type="button" style="z-index:2; position:absolute; top:100; left:100" value="test"/>
+
+</body>
+<script src="main.js"></script>
+
+</html> \ No newline at end of file
diff --git a/web/learn_canvas/canvas_btns/main.js b/web/learn_canvas/canvas_btns/main.js
new file mode 100644
index 0000000..be07ddb
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/main.js
@@ -0,0 +1,11 @@
+let canvas = document.getElementById("viewport");
+let ctx = canvas.getContext("2d");
+
+//var win_height = 600;
+//var win_width = 800;
+
+canvas.height = 600;
+canvas.width = 800;
+console.log(canvas.width, canvas.height);
+
+canvas.style.background = "#bbf"; \ No newline at end of file
diff --git a/web/learn_canvas/canvas_btns/style.css b/web/learn_canvas/canvas_btns/style.css
new file mode 100644
index 0000000..c9b2bbf
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/style.css
@@ -0,0 +1,18 @@
+#container
+{
+ height: 400px;
+ position: relative;
+ width: 400px;
+}
+#viewport
+{
+ height: 100%;
+ width: 100%;
+}
+#controls
+{
+ bottom: 0;
+ left: 0;
+ position: absolute;
+ width: 100%;
+} \ No newline at end of file
diff --git a/web/learn_canvas/canvas_btns/test.html b/web/learn_canvas/canvas_btns/test.html
new file mode 100644
index 0000000..9de2318
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/test.html
@@ -0,0 +1,77 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Bouncing Balls</title>
+
+ <style>
+ body {
+ background: #dddddd;
+ }
+
+ #canvas {
+ margin-left: 10px;
+ margin-top: 10px;
+ background: #ffffff;
+ border: thin solid #aaaaaa;
+ }
+
+ #glasspane {
+ position: absolute;
+ left: 50px;
+ top: 50px;
+ padding: 0px 20px 10px 10px;
+ background: rgba(0, 0, 0, 0.3);
+ border: thin solid rgba(0, 0, 0, 0.6);
+ color:# #eeeeee;
+ font-family: Droid Sans, Arial, Helvetica, sans-serif;
+ font-size: 12px;
+ cursor: pointer;
+ -webkit-box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
+ -moz-box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
+ box-shadow: rgba(0,0,0,0.5) 5px 5px 20px;
+ }
+
+ #glasspane h2 {
+ font-weight: normal;
+ }
+
+ #glasspane .title {
+ font-size: 2em;
+ color:# rgba(255, 255, 0, 0.8);
+ }
+
+ #glasspane a:hover {
+ color:# yellow;
+ }
+
+ #glasspane a {
+ text-decoration: none;
+ color:# #cccccc;
+ font-size: 3.5em;
+ }
+
+ #glasspane p {
+ margin: 10px;
+ color:# rgba(65, 65, 220, 1.0);
+ font-size: 12pt;
+ font-family: Palatino, Arial, Helvetica, sans-serif;
+ }
+ </style>
+ </head>
+
+ <body>
+ <div id='glasspane'>
+ <h2 class='title'>Bouncing Balls</h2>
+
+ <p>One hundred balls bouncing</p>
+
+ <a id='startButton'>Start</a>
+ </div>
+
+ <canvas id='canvas' width='750' height='500'>
+ Canvas not supported
+ </canvas>
+
+ <script src='example.js'></script>
+ </body>
+</html>
diff --git a/web/learn_canvas/canvas_btns/test2.html b/web/learn_canvas/canvas_btns/test2.html
new file mode 100644
index 0000000..b456738
--- /dev/null
+++ b/web/learn_canvas/canvas_btns/test2.html
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Rubber bands with layered elements</title>
+
+ <style>
+ body {
+ background: rgba(100, 145, 250, 0.3);
+ }
+
+ #canvas {
+ margin-left: 20px;
+ margin-right: 0;
+ margin-bottom: 20px;
+ border: thin solid #aaaaaa;
+ cursor: crosshair;
+ padding: 0;
+ }
+
+ #controls {
+ margin: 20px 0px 20px 20px;
+ }
+
+ #rubberbandDiv {
+ position: absolute;
+ border: 3px solid blue;
+ cursor: crosshair;
+ display: none;
+ }
+
+ </style>
+ </head>
+
+ <body>
+ <div id='controls'>
+ <input type='button' id='resetButton' value='Reset'/>
+ </div>
+
+ <div id='rubberbandDiv'></div>
+
+ <canvas id='canvas' width='800' height='520'>
+ Canvas not supported
+ </canvas>
+
+ <script src='example.js'></script>
+ </body>
+</html> \ No newline at end of file
diff --git a/web/multi_layers.html b/web/multi_layers.html
new file mode 100644
index 0000000..1311a77
--- /dev/null
+++ b/web/multi_layers.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Title</title>
+ <style>
+ #layer1 {
+ border: 10px, solid;
+
+ }
+ </style>
+</head>
+
+<body>
+
+<div style="position: relative;">
+ <canvas id="layer1" width="200" height="200"
+ style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
+ <canvas id="layer2" width="100" height="100"
+ style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
+</div>
+
+</body>
+</html> \ No newline at end of file
diff --git a/web/multi_layers/index.html b/web/multi_layers/index.html
new file mode 100644
index 0000000..3c0cfb8
--- /dev/null
+++ b/web/multi_layers/index.html
@@ -0,0 +1,11 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="UTF-8">
+ <title>Title</title>
+</head>
+<body>
+ <canvas id="canvas"></canvas>
+</body>
+<script src="main.js"></script>
+</html> \ No newline at end of file
diff --git a/web/multi_layers/main.js b/web/multi_layers/main.js
new file mode 100644
index 0000000..5aa6458
--- /dev/null
+++ b/web/multi_layers/main.js
@@ -0,0 +1,60 @@
+let canvas = document.getElementById("canvas");
+let ctx = canvas.getContext("2d");
+
+var win_height = window.innerHeight;
+var win_width = window.innerWidth;
+
+canvas.height = win_height;
+canvas.width = win_width;
+console.log(canvas.width, canvas.height);
+
+canvas.style.background = "#bbf";
+
+
+class Circle {
+ constructor(context, xpos, ypos, radius, color) {
+ this.context = context;
+ this.xpos = xpos;
+ this.ypos = ypos;
+ this.radius = radius;
+ this.color = color;
+ }
+ draw() {
+ this.context.beginPath();
+ this.context.arc(this.xpos, this.ypos, this.radius, 0, Math.PI*2, this.color);
+ this.context.strokeStyle = "grey";
+ this.context.lineWidth = 15;
+ this.context.fillStyle = this.color;
+ this.context.fill();
+ this.context.stroke();
+ this.context.closePath();
+ }
+ clickCircle(xmouse, ymouse) {
+ const distance = Math.sqrt((xmouse - this.xpos) * (xmouse - this.xpos) + (ymouse - this.ypos) * (ymouse - this.ypos));
+ if (distance <= this.radius) {
+ return true;
+ }
+ return false;
+ }
+ changeColor (newColor) {
+ this.color = newColor;
+ this.draw();
+ }
+}
+
+
+let circle = new Circle(ctx, 200, 200, 100, "blue");
+circle.draw(ctx);
+canvas.addEventListener("click", (event) => {
+// console.log(event);
+// console.log("clicked canvas");
+ const rect = canvas.getBoundingClientRect();
+ const x = event.clientX - rect.left;
+ const y = event.clientY - rect.top;
+ if (circle.clickCircle(x, y)) {
+ circle.changeColor("red");
+ } else {
+ circle.changeColor("blue");
+ }
+// console.log(rect);
+});