diff options
Diffstat (limited to '')
-rw-r--r-- | docs/js/ValueMap.js | 139 | ||||
-rw-r--r-- | docs/js/grown.js | 79 |
2 files changed, 218 insertions, 0 deletions
diff --git a/docs/js/ValueMap.js b/docs/js/ValueMap.js new file mode 100644 index 000000000..31ddba27e --- /dev/null +++ b/docs/js/ValueMap.js @@ -0,0 +1,139 @@ + +const g_DistanceBetweenSquares = 0;//.01; +const g_Colors = [ + "#0000FF", + "#00FF00", + "#FF0000", + "#FF00FF", + "#00FFFF", + "#FFFF00", + "#000000", + "#9BADFF" +] + +class ValueMap { + constructor() { + this.values = new Uint8Array(4 * 4); + this.sizeX = 4; + this.sizeZ = 4; + this.reset(); + } + + + reset() { + this.sizeX = 4; + this.sizeZ = 4; + this.values = new Uint8Array(this.sizeX * this.sizeZ); + + for (let x = 0; x < this.sizeX; x++) + { + for (let z = 0; z < this.sizeZ; z++) + { + this.values[x + this.sizeZ * z] = Math.floor(Math.random() * 8); + } + } + } + + + chooseRandomNumber() { + let numArguments = arguments.length; + return arguments[Math.floor(Math.random() * arguments.length)]; + } + + + smooth() { + let sizeZ = this.sizeZ - 2; + let sizeX = this.sizeX - 2; + let cache = new Uint8Array((this.sizeX - 2) * (this.sizeZ - 2)); + for (let z = 0; z < sizeZ; z++) + { + for (let x = 0; x < sizeX; x++) + { + let val = this.values[x + 1 + (z + 1) * this.sizeX]; + let above = this.values[x + 1 + z * this.sizeX]; + let below = this.values[x + 1 + (z + 2) * this.sizeX]; + let left = this.values[x + (z + 1) * this.sizeX]; + let right = this.values[x + 2 + (z + 1) * this.sizeX]; + + if ((left == right) && (above == below)) + { + if (Math.random() < 0.5) + { + val = left; + } + else + { + val = below; + } + } + else + { + if (left == right) + { + val = left; + } + if (above == below) + { + val = above; + } + } + cache[x + z * sizeX] = val; + } + } + this.values = cache; + this.sizeX -= 2; + this.sizeZ -= 2; + } + + + zoom() { + let lowStepX = (this.sizeX - 1) * 2; + let lowStepZ = (this.sizeZ - 1) * 2; + let cache = new Uint8Array(lowStepX * lowStepZ); + for (let z = 0; z < this.sizeZ - 1; z++) + { + let idx = (z * 2) * lowStepX; + let PrevZ0 = this.values[z * this.sizeX]; + let PrevZ1 = this.values[(z + 1) * this.sizeX]; + + for (let x = 0; x < this.sizeX - 1; x++) + { + let ValX1Z0 = this.values[x + 1 + z * this.sizeX]; + let ValX1Z1 = this.values[x + 1 + (z + 1) * this.sizeX]; + cache[idx] = PrevZ0; + cache[idx + lowStepX] = this.chooseRandomNumber(PrevZ0, PrevZ1); + cache[idx + 1] = this.chooseRandomNumber(PrevZ0, ValX1Z0); + cache[idx + 1 + lowStepX] = this.chooseRandomNumber(PrevZ0, ValX1Z0, PrevZ1, ValX1Z1); + idx += 2; + PrevZ0 = ValX1Z0; + PrevZ1 = ValX1Z1; + } + } + this.values = cache; + this.sizeX = lowStepX; + this.sizeZ = lowStepZ; + } + + + visualize(context, canvas) { + context.clearRect(0, 0, canvas.width, canvas.height); + const squareSizeX = canvas.width / (this.sizeX - 1) - g_DistanceBetweenSquares; + const squareSizeY = canvas.height / (this.sizeZ - 1) - g_DistanceBetweenSquares; + for (let x = 0; x < this.sizeX - 1; x++) + { + for (let y = 0; y < this.sizeZ - 1; y++) + { + let renderX = canvas.width / (this.sizeX - 1) * x + g_DistanceBetweenSquares; + let renderY = canvas.height / (this.sizeZ - 1) * y + g_DistanceBetweenSquares; + context.fillStyle = g_Colors[this.values[x + y * this.sizeZ]]; + context.fillRect(renderX, renderY, squareSizeX, squareSizeY); + } + } + + context.save(); + context.globalCompositeOperation = 'difference'; + context.fillStyle = 'white'; + context.fillText("Size: " + (this.sizeX - 1) + "x" + (this.sizeZ - 1), 5, 10); + context.restore(); + } +} diff --git a/docs/js/grown.js b/docs/js/grown.js new file mode 100644 index 000000000..1658ce21c --- /dev/null +++ b/docs/js/grown.js @@ -0,0 +1,79 @@ + +let g_Canvas = null; +let g_Context = null; +let g_ValueMap = null; + + + + +function init() { + g_Canvas = document.getElementById("stage"); + g_Context = g_Canvas.getContext("2d"); + g_ValueMap = new ValueMap(); + g_ValueMap.visualize(g_Context, g_Canvas); +} + + + +function btnZoom(btn) { + g_ValueMap.zoom(); + g_ValueMap.visualize(g_Context, g_Canvas); + if ( + (g_ValueMap.sizeX * 2 - 1 > 600) || + (g_ValueMap.sizeZ * 2 - 1 > 600) + ) { + btn.disabled = true; + } +} + + + +function btnSmooth() { + g_ValueMap.smooth(); + g_ValueMap.visualize(g_Context, g_Canvas); +} + + +function btnReset() { + g_ValueMap.reset(); + g_ValueMap.visualize(g_Context, g_Canvas); + + document.getElementById("grownZoomButton").disabled = false; +} + + +function btnAutomatic(target) { + target.disabled = true; + document.getElementById("grownZoomButton").disabled = true; + + // Reset the valuemap. We don't want to continue on a 500x500 map. + g_ValueMap.reset(); + g_ValueMap.visualize(g_Context, g_Canvas); + + const animationTimeBetween = 350; + let zoom = () => { g_ValueMap.zoom() }; + let smooth = () => { g_ValueMap.smooth() }; + let actions = []; + + for (let i = 0; i < 6; i++) actions.push(zoom); // First zoom 6 times + for (let i = 0; i < 3; i++) actions.push(smooth); // Then smooth 3 times + for (let i = 0; i < 2; i++) actions.push(zoom); // Zoom 2 times + for (let i = 0; i < 2; i++) actions.push(smooth); // And finally smooth 2 more times. + + let update = () => { + if (actions[0] == null) { + target.disabled = false; + return; + } + + actions[0].call(); + g_ValueMap.visualize(g_Context, g_Canvas); + + actions.splice(0, 1); + setTimeout(update, animationTimeBetween); + }; + setTimeout(update, animationTimeBetween + 500); +} + + +window.onload = init; |