diff --git a/assets/Keyboard Test.png b/assets/Keyboard Test.png
new file mode 100644
index 0000000..5389e57
Binary files /dev/null and b/assets/Keyboard Test.png differ
diff --git a/assets/Mouse Test.png b/assets/Mouse Test.png
new file mode 100644
index 0000000..70b7b62
Binary files /dev/null and b/assets/Mouse Test.png differ
diff --git a/assets/keyboard.png b/assets/keyboard.png
deleted file mode 100644
index 1ee5664..0000000
Binary files a/assets/keyboard.png and /dev/null differ
diff --git a/bio/index.html b/bio/index.html
index 4096399..8a9d740 100644
--- a/bio/index.html
+++ b/bio/index.html
@@ -9,7 +9,7 @@
-
+
diff --git a/click/index.html b/click/index.html
index b4f2fc0..277dba1 100644
--- a/click/index.html
+++ b/click/index.html
@@ -6,7 +6,7 @@
Click Test
-
+
diff --git a/cool/index.html b/cool/index.html
new file mode 100644
index 0000000..8dcd107
--- /dev/null
+++ b/cool/index.html
@@ -0,0 +1,13 @@
+
+
+
+
+
+ Cool
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/cool/script.js b/cool/script.js
new file mode 100644
index 0000000..75f4730
--- /dev/null
+++ b/cool/script.js
@@ -0,0 +1,207 @@
+var background_color = "#fafafa";
+var canvas = document.getElementById("canvas");
+var renderer = new THREE.WebGLRenderer( { canvas: canvas } );
+var scene = new THREE.Scene();
+scene.background = new THREE.Color(0xffffff);
+var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
+var win_width = 0, win_height = 0;
+function update_size() {
+ if (window.innerWidth != win_width || window.innerHeight != win_height) {
+ win_width = window.innerWidth;
+ win_height = window.innerHeight;
+ renderer.setPixelRatio(window.devicePixelRatio || 1);
+ renderer.setSize(win_width, win_height);
+ camera.aspect = win_width / win_height;
+ camera.updateProjectionMatrix();
+ }
+}
+update_size();
+
+var clock = new THREE.Clock();
+var delta_time = 1/60.0;
+var elapsed_time = 0;
+
+var geometry = new THREE.Geometry();
+var radius = 10;
+var depth_step = 10;
+var num_rings = 100;
+var num_segments = 24;
+
+var outer_h = Math.max($("#outer").height(), 10000) - 1200;
+var content_h = Math.max($("#content").height(), 10000);
+var content_h2 = $("#content").height() + 9200;
+
+var base_colors = [];
+var colors = [];
+var num_colors = num_rings * num_segments * 2;
+for (var c = 0; c < num_colors; c++) {
+ base_colors[c] = new THREE.Color(Math.random(), Math.random(), Math.random());
+ colors[c] = base_colors[c].clone();
+}
+
+function lerp(res, color1, color2, t) {
+ res.r = (1-t)*color1.r + t*color2.r;
+ res.g = (1-t)*color1.g + t*color2.g;
+ res.b = (1-t)*color1.b + t*color2.b;
+}
+
+function update_colors(delta, progress) {
+ var bias = 1;
+ var bg = new THREE.Color(background_color);
+ var h1 = content_h - 6000;
+ var h2 = content_h + 400;
+ if (progress < h1) {
+ bias = 0;
+ } else if (progress < h2) {
+ bias = (progress - h1) / (h2 - h1);
+ }
+ //if (s > content_h) {
+ // if (s > content_h + 1000) {
+ // color = new THREE.Color(1, 1, 1);
+ // } else {
+ // var q = (s - content_h) / 1000;
+ // //color = new THREE.Color(r + (1-r) * q, g + (1-g) * q, b + (1-b) * q);
+ // color = new THREE.Color();
+ // color.setHSL(0, 0.5, q * 0.6 + 0.4);
+ // }
+ //} else {
+ // var q = (content_h-s) / content_h;
+ // color = new THREE.Color();
+ // color.setHSL(q, 0.5, 0.4);
+ //}
+ for (var c = 0; c < num_colors; c++) {
+ var hsl = base_colors[c].getHSL();
+ var h = hsl.h;
+ h = (h + delta * (1+c/100)) % 1;
+ base_colors[c].setHSL(h, hsl.s, hsl.l);
+ lerp(colors[c], bg, base_colors[c], bias);
+ }
+}
+update_colors(0, 0);
+
+var verts = [];
+var speeds = [];
+var phases = [];
+function init_verts() {
+ var x = 0, y = 0, z = 0;
+ var dz = -depth_step / num_segments;
+ for (var r = 0; r < num_rings; r++) {
+ for (var s = 0; s < num_segments; s++) {
+ var angle = Math.PI * 2 * (s / num_segments);
+ var x = Math.cos(angle) * radius;
+ var y = Math.sin(angle) * radius;
+ verts.push(new THREE.Vector3(x, y, z));
+ speeds.push(Math.random());
+ phases.push(Math.random());
+ z += dz;
+ }
+ }
+}
+init_verts();
+function update_verts(t) {
+ var d = num_rings * 0.4;
+ var v = 0;
+ for (var r = 0; r < num_rings; r++) {
+ for (var s = 0; s < num_segments; s++) {
+ if (r > d) {
+ var p = 0.5 + 0.5 * Math.sin(t*speeds[v] + phases[v])
+ var q = (r-d)/d * 1.1;
+ var rad = (1-p * q) * radius;
+ var angle = Math.PI * 2 * (s / num_segments);
+ var x = Math.cos(angle) * rad;
+ var y = Math.sin(angle) * rad;
+ var vert = verts[v];
+ vert.x = x;
+ vert.y = y;
+ }
+ v++;
+ }
+ }
+}
+update_verts(0);
+
+function mkgeometry(geometry) {
+ var fi = 0;
+ var f = 0;
+ var vi = 0;
+ var v = 0;
+ var x = 0, y = 0, z = 0;
+ var dz = -depth_step / num_segments;
+ var c = 0;
+ for (var r = 0; r < num_rings; r++) {
+ for (var s = 0; s < num_segments; s++) {
+ var vert1 = verts[vi];
+ var vert2 = vi - 1 >= 0 ? verts[vi - 1] : verts[0];
+ var vert3 = vi - num_segments >= 0 ? verts[vi - num_segments] : verts[0];
+ var vert4 = vi - num_segments - 1 >= 0 ? verts[vi - num_segments - 1] : verts[0];
+ vi++;
+
+ geometry.vertices[v++] = vert1;
+ geometry.vertices[v++] = vert2;
+ geometry.vertices[v++] = vert4;
+ geometry.faces[f++] = new THREE.Face3(fi, fi+1, fi+2, null, colors[c++]);
+ fi += 3;
+ geometry.vertices[v++] = vert1;
+ geometry.vertices[v++] = vert4;
+ geometry.vertices[v++] = vert3;
+ geometry.faces[f++] = new THREE.Face3(fi, fi+1, fi+2, null, colors[c++]);
+ fi += 3;
+ old_x = x;
+ old_y = y;
+ old_z = z;
+ z += dz;
+ }
+ }
+ geometry.verticesNeedUpdate = true;
+ geometry.colorsNeedUpdate = true;
+ geometry.elementsNeedUpdate = true;
+}
+mkgeometry(geometry);
+var material = new THREE.MeshBasicMaterial({ vertexColors: THREE.VertexColors, color: background_color });
+material.depthFunc = THREE.AlwaysDepth;
+var mesh = new THREE.Mesh(geometry, material);
+scene.add(mesh);
+
+var s = 0;
+var total_s = 0;
+var first_time = true;
+var animate = function () {
+ //console.log("updating background");
+ update_size();
+ delta_time = clock.getDelta();
+ elapsed_time = clock.elapsedTime;
+
+ var win = $(window);
+ var prev_s = s;
+ s = $(window).scrollTop();
+ var ds = Math.abs(s - prev_s);
+ camera.position.z = -s/outer_h*(num_rings * depth_step);
+ //var color;
+ //color = new THREE.Color("#efefef");
+ //if (s > content_h) {
+ // if (s > content_h + 1000) {
+ // color = new THREE.Color(1, 1, 1);
+ // } else {
+ // var q = (s - content_h) / 1000;
+ // //color = new THREE.Color(r + (1-r) * q, g + (1-g) * q, b + (1-b) * q);
+ // color = new THREE.Color();
+ // color.setHSL(0, 0.5, q * 0.6 + 0.4);
+ // }
+ //} else {
+ // var q = (content_h-s) / content_h;
+ // color = new THREE.Color();
+ // color.setHSL(q, 0.5, 0.4);
+ //}
+ //material.color = color;
+ if (ds > 0 || first_time) {
+ total_s += ds * 0.01;
+ update_colors(ds * 0.00001, s);
+ update_verts(total_s);
+ mkgeometry(mesh.geometry);
+ first_time = false;
+ }
+ renderer.render(scene, camera);
+ requestAnimationFrame( animate );
+};
+animate();
+//setInterval(animate, 500); // backup as sometimes requestAnimationFrame doesn't trigger in Firefox
diff --git a/index.html b/index.html
index e1f67fc..98b098f 100644
--- a/index.html
+++ b/index.html
@@ -5,6 +5,10 @@
zyq's Tools
+
+
+
+
@@ -18,34 +22,16 @@
This is a website for future tools. The source code can be found on my GitHub!
Clicking "Test It" will open the tool in the current tab.
More tools will come in the future.
-
MOTD: "To the mind that is still, the whole universe surrenders." - Lao Tzu
-
+
+
+
+
-
-
-