percolation
This commit is contained in:
19 files changed
+10570
-6
No files matched your search
@@ -0,0 +1 @@
|
||||
.idea/
|
||||
+13
-6
@@ -222,6 +222,19 @@
|
||||
</p>
|
||||
|
||||
<div class="card-grid reveal" style="transition-delay:0.15s">
|
||||
<a class="card" href="projects/cellular_automata/index.html">
|
||||
<span class="card-date">23 Jul 2023</span>
|
||||
<span class="card-title">Game of Life</span>
|
||||
<span class="card-desc">After previously implementing game of life in p5.js, I implemented a generic
|
||||
simulator, for more obsquere automata.</span>
|
||||
<span class="card-arrow">→</span>
|
||||
</a>
|
||||
<a class="card" href="projects/percolation/index.html">
|
||||
<span class="card-date">2 Feb 2022</span>
|
||||
<span class="card-title">Percolation</span>
|
||||
<span class="card-desc">A small demonstration to show liquid percolating through a medium as more cracks appear - and at what p value this happens.</span>
|
||||
<span class="card-arrow">→</span>
|
||||
</a>
|
||||
<a class="card" href="projects/cubic_bezier_curve/index.html">
|
||||
<span class="card-date">1 Oct 2021</span>
|
||||
<span class="card-title">Drawing Bézier curves</span>
|
||||
@@ -254,12 +267,6 @@
|
||||
3Blue1Brown.</span>
|
||||
<span class="card-arrow">→</span>
|
||||
</a>
|
||||
<a class="card" href="projects/game_of_life.html">
|
||||
<span class="card-date">2 May 2018</span>
|
||||
<span class="card-title">Game of Life</span>
|
||||
<span class="card-desc">A JS implementation of Conway's classic. Still fascinating.</span>
|
||||
<span class="card-arrow">→</span>
|
||||
</a>
|
||||
<a class="card" href="projects/pi_approximation.html">
|
||||
<span class="card-date">18 Mar 2018</span>
|
||||
<span class="card-title">Calculating PI</span>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"files": {
|
||||
"main.css": "/projects/cellular_automata/static/css/main.5cae1eb5.css",
|
||||
"main.js": "/projects/cellular_automata/static/js/main.608a23ae.js",
|
||||
"index.html": "/projects/cellular_automata/index.html",
|
||||
"main.5cae1eb5.css.map": "/projects/cellular_automata/static/css/main.5cae1eb5.css.map",
|
||||
"main.608a23ae.js.map": "/projects/cellular_automata/static/js/main.608a23ae.js.map"
|
||||
},
|
||||
"entrypoints": [
|
||||
"static/css/main.5cae1eb5.css",
|
||||
"static/js/main.608a23ae.js"
|
||||
]
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
@@ -0,0 +1 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/projects/cellular_automata/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="/projects/cellular_automata/logo192.png"/><link rel="manifest" href="/projects/cellular_automata/manifest.json"/><title>React App</title><script defer="defer" src="/projects/cellular_automata/static/js/main.608a23ae.js"></script><link href="/projects/cellular_automata/static/css/main.5cae1eb5.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div></body></html>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"short_name": "React App",
|
||||
"name": "Create React App Sample",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# https://www.robotstxt.org/robotstxt.html
|
||||
User-agent: *
|
||||
Disallow:
|
||||
@@ -0,0 +1,2 @@
|
||||
#root,body,html{margin:0;min-height:100%}body{background:radial-gradient(circle at top,#eef4ff 0,#f8fbff 55%,#eef2f7 100%);color:#0f172a;font-family:Segoe UI,sans-serif}.cell{border:1px solid #1f2937;box-sizing:border-box;margin:0;padding:0}.dead{background:#000}.alive{background:#fff}.board{border:1px solid #94a3b8;cursor:crosshair;display:inline-block;-webkit-user-select:none;user-select:none}.row{display:flex}.horizontal-slider{margin:auto;width:100%}.example-thumb{background:#fff;border:5px solid #3774ff;border-radius:100%;box-shadow:0 0 2px 0 #00000070;cursor:pointer;display:block;position:absolute;z-index:100}.example-thumb.active{background-color:grey}.example-track{background:#ddd;position:relative}.example-track.example-track-0{background:#83a9ff}.horizontal-slider .example-track{height:4px;top:20px}.horizontal-slider .example-thumb{height:10px;line-height:38px;outline:none;top:12px;width:10px}.radioGroup{grid-gap:.45rem;display:grid;gap:.45rem}.radioOption{align-items:center;color:#1e293b;cursor:pointer;display:flex;font-size:.92rem;gap:.5rem}.radioOption input{accent-color:#2f7df6;margin:0}.title{margin:2rem 0 1.25rem;text-align:center}.title h1{color:#0f172a;font-size:2.2rem;letter-spacing:.03em;margin:0}.title p{color:#475569;font-size:.95rem;margin:.35rem 0 0}.body{align-items:flex-start;display:flex;gap:1.25rem;justify-content:center;margin:0 auto 1.75rem;max-width:980px;padding:0 1rem}.gameBoard{padding:.6rem}.controlPanel,.gameBoard{background:#fff;border:1px solid #d5deea;border-radius:12px;box-shadow:0 12px 28px #0f172a1a}.controlPanel{color:#1e293b;padding:1rem;width:270px}.panelSection{margin-bottom:1rem}.panelSection h3{color:#334155;font-size:.95rem;margin:0 0 .5rem}.buttonRow{grid-gap:.5rem;display:grid;gap:.5rem;grid-template-columns:repeat(3,1fr);margin-bottom:1.1rem}.controlButton{background:#f8fafc;border:1px solid #cbd5e1;border-radius:8px;color:#1e293b;cursor:pointer;font-weight:500;padding:.45rem .35rem}.controlButton:hover{background:#eef2f8}.sliderContainer{grid-gap:.25rem;display:grid;gap:.25rem}.sliderContainer span{color:#334155;font-size:.95rem}.fpsValue{color:#64748b;font-size:.85rem;margin:.3rem 0 0}
|
||||
/*# sourceMappingURL=main.5cae1eb5.css.map*/
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/css/main.5cae1eb5.css","mappings":"AAAA,gBAGE,QAAS,CACT,eACF,CAEA,KAEE,4EAAiF,CACjF,aAAc,CAFd,+BAGF,CCXA,MAGE,wBAAyB,CACzB,qBAAsB,CAHtB,QAAS,CACT,SAGF,CAEA,MACE,eACF,CAEA,OACE,eACF,CCbA,OAEE,wBAAyB,CAEzB,gBAAiB,CAHjB,oBAAqB,CAErB,wBAAiB,CAAjB,gBAEF,CAEA,KACE,YACF,CCTA,mBAEE,WAAY,CADZ,UAEF,CAEA,eAIE,eAAmB,CACnB,wBAAyB,CACzB,kBAAmB,CAEnB,8BAAsC,CAPtC,cAAe,CAMf,aAAc,CALd,iBAAkB,CAClB,WAMF,CAEA,sBACE,qBACF,CAEA,eAEE,eAAgB,CADhB,iBAEF,CAEA,+BACE,kBACF,CAEA,kCAEE,UAAW,CADX,QAEF,CAEA,kCAIE,WAAY,CACZ,gBAAiB,CAFjB,YAAa,CAFb,QAAS,CACT,UAIF,CCxCA,YAEE,eAAY,CADZ,YAAa,CACb,UACF,CAEA,aAEE,kBAAmB,CAInB,aAAc,CADd,cAAe,CAJf,YAAa,CAGb,gBAAkB,CADlB,SAIF,CAEA,mBAEE,oBAAqB,CADrB,QAEF,CCjBA,OACE,qBAAsB,CACtB,iBACF,CAEA,UAIE,aAAc,CAFd,gBAAiB,CACjB,oBAAsB,CAFtB,QAIF,CAEA,SAGE,aAAc,CADd,gBAAkB,CADlB,iBAGF,CAEA,MAGE,sBAAuB,CAFvB,YAAa,CAGb,WAAY,CAFZ,sBAAuB,CAIvB,qBAAsB,CADtB,eAAgB,CAEhB,cACF,CAEA,WAIE,aAEF,CAEA,yBAPE,eAAmB,CACnB,wBAAyB,CACzB,kBAAmB,CAEnB,gCAWF,CARA,cAME,aAAc,CADd,YAAa,CAJb,WAOF,CAEA,cACE,kBACF,CAEA,iBAGE,aAAc,CADd,gBAAkB,CADlB,gBAGF,CAEA,WAGE,cAAW,CAFX,YAAa,CAEb,SAAW,CADX,mCAAqC,CAErC,oBACF,CAEA,eAEE,kBAAmB,CADnB,wBAAyB,CAGzB,iBAAkB,CADlB,aAAc,CAGd,cAAe,CACf,eAAgB,CAFhB,qBAGF,CAEA,qBACE,kBACF,CAEA,iBAEE,eAAY,CADZ,YAAa,CACb,UACF,CAEA,sBAEE,aAAc,CADd,gBAEF,CAEA,UAGE,aAAc,CADd,gBAAkB,CADlB,gBAGF","sources":["index.css","styles/cell.css","styles/board.css","styles/slider.css","styles/brushes.css","styles/game.css"],"sourcesContent":["html,\nbody,\n#root {\n margin: 0;\n min-height: 100%;\n}\n\nbody {\n font-family: \"Segoe UI\", sans-serif;\n background: radial-gradient(circle at top, #eef4ff 0%, #f8fbff 55%, #eef2f7 100%);\n color: #0f172a;\n}\n",".cell {\n margin: 0;\n padding: 0;\n border: 1px solid #1f2937;\n box-sizing: border-box;\n}\n\n.dead {\n background: #000000;\n}\n\n.alive {\n background: #ffffff;\n}\n",".board {\n display: inline-block;\n border: 1px solid #94a3b8;\n user-select: none;\n cursor: crosshair;\n}\n\n.row {\n display: flex;\n}\n",".horizontal-slider {\n width: 100%;\n margin: auto;\n}\n\n.example-thumb {\n cursor: pointer;\n position: absolute;\n z-index: 100;\n background: #ffffff;\n border: 5px solid #3774ff;\n border-radius: 100%;\n display: block;\n box-shadow: 0 0 2px 0 rgb(0 0 0 / 44%);\n}\n\n.example-thumb.active {\n background-color: grey;\n}\n\n.example-track {\n position: relative;\n background: #ddd;\n}\n\n.example-track.example-track-0 {\n background: #83a9ff;\n}\n\n.horizontal-slider .example-track {\n top: 20px;\n height: 4px;\n}\n\n.horizontal-slider .example-thumb {\n top: 12px;\n width: 10px;\n outline: none;\n height: 10px;\n line-height: 38px;\n}\n",".radioGroup {\n display: grid;\n gap: 0.45rem;\n}\n\n.radioOption {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.92rem;\n cursor: pointer;\n color: #1e293b;\n}\n\n.radioOption input {\n margin: 0;\n accent-color: #2f7df6;\n}\n",".title {\n margin: 2rem 0 1.25rem;\n text-align: center;\n}\n\n.title h1 {\n margin: 0;\n font-size: 2.2rem;\n letter-spacing: 0.03em;\n color: #0f172a;\n}\n\n.title p {\n margin: 0.35rem 0 0;\n font-size: 0.95rem;\n color: #475569;\n}\n\n.body {\n display: flex;\n justify-content: center;\n align-items: flex-start;\n gap: 1.25rem;\n max-width: 980px;\n margin: 0 auto 1.75rem;\n padding: 0 1rem;\n}\n\n.gameBoard {\n background: #ffffff;\n border: 1px solid #d5deea;\n border-radius: 12px;\n padding: 0.6rem;\n box-shadow: 0 12px 28px rgb(15 23 42 / 10%);\n}\n\n.controlPanel {\n width: 270px;\n background: #ffffff;\n border: 1px solid #d5deea;\n border-radius: 12px;\n padding: 1rem;\n color: #1e293b;\n box-shadow: 0 12px 28px rgb(15 23 42 / 10%);\n}\n\n.panelSection {\n margin-bottom: 1rem;\n}\n\n.panelSection h3 {\n margin: 0 0 0.5rem;\n font-size: 0.95rem;\n color: #334155;\n}\n\n.buttonRow {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n gap: 0.5rem;\n margin-bottom: 1.1rem;\n}\n\n.controlButton {\n border: 1px solid #cbd5e1;\n background: #f8fafc;\n color: #1e293b;\n border-radius: 8px;\n padding: 0.45rem 0.35rem;\n cursor: pointer;\n font-weight: 500;\n}\n\n.controlButton:hover {\n background: #eef2f8;\n}\n\n.sliderContainer {\n display: grid;\n gap: 0.25rem;\n}\n\n.sliderContainer span {\n font-size: 0.95rem;\n color: #334155;\n}\n\n.fpsValue {\n margin: 0.3rem 0 0;\n font-size: 0.85rem;\n color: #64748b;\n}\n"],"names":[],"sourceRoot":""}
|
||||
@@ -0,0 +1,3 @@
|
||||
/*! For license information please see main.608a23ae.js.LICENSE.txt */
|
||||
(()=>{"use strict";var e={463:(e,t,n)=>{var r=n(791),l=n(296);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n<arguments.length;n++)t+="&args[]="+encodeURIComponent(arguments[n]);return"Minified React error #"+e+"; visit "+t+" for the full message or use the non-minified dev environment for full errors and additional helpful warnings."}var o=new Set,i={};function u(e,t){s(e,t),s(e+"Capture",t)}function s(e,t){for(i[e]=t,e=0;e<t.length;e++)o.add(t[e])}var c=!("undefined"===typeof window||"undefined"===typeof window.document||"undefined"===typeof window.document.createElement),f=Object.prototype.hasOwnProperty,d=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,p={},h={};function m(e,t,n,r,l,a,o){this.acceptsBooleans=2===t||3===t||4===t,this.attributeName=r,this.attributeNamespace=l,this.mustUseProperty=n,this.propertyName=e,this.type=t,this.sanitizeURL=a,this.removeEmptyString=o}var v={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach((function(e){v[e]=new m(e,0,!1,e,null,!1,!1)})),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach((function(e){var t=e[0];v[t]=new m(t,1,!1,e[1],null,!1,!1)})),["contentEditable","draggable","spellCheck","value"].forEach((function(e){v[e]=new m(e,2,!1,e.toLowerCase(),null,!1,!1)})),["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach((function(e){v[e]=new m(e,2,!1,e,null,!1,!1)})),"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach((function(e){v[e]=new m(e,3,!1,e.toLowerCase(),null,!1,!1)})),["checked","multiple","muted","selected"].forEach((function(e){v[e]=new m(e,3,!0,e,null,!1,!1)})),["capture","download"].forEach((function(e){v[e]=new m(e,4,!1,e,null,!1,!1)})),["cols","rows","size","span"].forEach((function(e){v[e]=new m(e,6,!1,e,null,!1,!1)})),["rowSpan","start"].forEach((function(e){v[e]=new m(e,5,!1,e.toLowerCase(),null,!1,!1)}));var g=/[\-:]([a-z])/g;function y(e){return e[1].toUpperCase()}function b(e,t,n,r){var l=v.hasOwnProperty(t)?v[t]:null;(null!==l?0!==l.type:r||!(2<t.length)||"o"!==t[0]&&"O"!==t[0]||"n"!==t[1]&&"N"!==t[1])&&(function(e,t,n,r){if(null===t||"undefined"===typeof t||function(e,t,n,r){if(null!==n&&0===n.type)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":return!r&&(null!==n?!n.acceptsBooleans:"data-"!==(e=e.toLowerCase().slice(0,5))&&"aria-"!==e);default:return!1}}(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case 3:return!t;case 4:return!1===t;case 5:return isNaN(t);case 6:return isNaN(t)||1>t}return!1}(t,n,l,r)&&(n=null),r||null===l?function(e){return!!f.call(h,e)||!f.call(p,e)&&(d.test(e)?h[e]=!0:(p[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):l.mustUseProperty?e[l.propertyName]=null===n?3!==l.type&&"":n:(t=l.attributeName,r=l.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(l=l.type)||4===l&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach((function(e){var t=e.replace(g,y);v[t]=new m(t,1,!1,e,null,!1,!1)})),"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach((function(e){var t=e.replace(g,y);v[t]=new m(t,1,!1,e,"http://www.w3.org/1999/xlink",!1,!1)})),["xml:base","xml:lang","xml:space"].forEach((function(e)Line truncated
|
||||
//# sourceMappingURL=main.608a23ae.js.map
|
||||
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* @license React
|
||||
* react-dom.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react-jsx-runtime.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* react.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @license React
|
||||
* scheduler.production.min.js
|
||||
*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"static/js/main.608a23ae.js","mappings":"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 truncated
|
||||
@@ -0,0 +1,73 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Percolation</title>
|
||||
<link rel="stylesheet" href="style.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<a href="/#projects" class="back-button">← Back</a>
|
||||
|
||||
<header>
|
||||
<h1>Percolation</h1>
|
||||
<p class="subtitle">A simulation written in C & Raylib.</p>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
<p>
|
||||
<strong>Percolation</strong> is a simple model for connectivity on a grid. Each cell is either open or closed.
|
||||
This simulation stops as soon as there is a path from the top of the grid to the bottom through the open cells.
|
||||
</p>
|
||||
<div class="info-box">
|
||||
<p>
|
||||
In this simulation, cells are randomly opened on a grid. Percolation occurs when there exists
|
||||
a connected path of open cells from the top to the bottom of the grid. It is a neat way to visualise
|
||||
threshold behaviour: below a certain probability nothing connects, and above it large connected regions
|
||||
suddenly begin to appear.
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<div class="canvas-container">
|
||||
<div class="canvas-toolbar">
|
||||
<p>Canvas</p>
|
||||
<button id="fullscreenButton" class="action-button" type="button">Fullscreen</button>
|
||||
</div>
|
||||
|
||||
<div class="canvas-shell">
|
||||
<canvas id="canvas" aria-label="Percolation simulation canvas" oncontextmenu="event.preventDefault()"></canvas>
|
||||
</div>
|
||||
|
||||
<div id="status" class="status">Downloading...</div>
|
||||
<progress id="progress" value="0" max="100" hidden></progress>
|
||||
|
||||
<details>
|
||||
<summary>Show console output</summary>
|
||||
<label class="visually-hidden" for="output">Console output</label>
|
||||
<textarea id="output" rows="8" readonly></textarea>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<section>
|
||||
<h3>Technical Details</h3>
|
||||
<p>
|
||||
The simulation uses a <strong>disjoint-set (Union-Find)</strong> style connectivity algorithm. As random cells open,
|
||||
each open cell is union-ed with its open neighbours, and two virtual nodes represent the top and bottom edges
|
||||
of the grid. Percolation is detected the moment those two virtual nodes become connected.
|
||||
</p>
|
||||
<p>
|
||||
This makes each update fast and scalable even for larger grids.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<footer>
|
||||
<p>Built with C, Raylib, and WebAssembly</p>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<script src="script.js"></script>
|
||||
<script async src="index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
File diff suppressed because it is too large.
Load diff
Executable
BIN
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
const statusElement = document.getElementById('status');
|
||||
const progressElement = document.getElementById('progress');
|
||||
const canvasElement = document.getElementById('canvas');
|
||||
const outputElement = document.getElementById('output');
|
||||
const fullscreenButton = document.getElementById('fullscreenButton');
|
||||
|
||||
outputElement.value = '';
|
||||
|
||||
canvasElement.addEventListener('webglcontextlost', (event) => {
|
||||
event.preventDefault();
|
||||
setStatus('WebGL context lost. Reload the page to restart the simulation.');
|
||||
}, false);
|
||||
|
||||
function setStatus(text) {
|
||||
if (!setStatus.last) {
|
||||
setStatus.last = { time: Date.now(), text: '' };
|
||||
}
|
||||
|
||||
if (text === setStatus.last.text) {
|
||||
return;
|
||||
}
|
||||
|
||||
const match = text && text.match(/([^(]+)\((\d+(?:\.\d+)?)\/(\d+)\)/);
|
||||
const now = Date.now();
|
||||
|
||||
if (match && now - setStatus.last.time < 30) {
|
||||
return;
|
||||
}
|
||||
|
||||
setStatus.last.time = now;
|
||||
setStatus.last.text = text;
|
||||
|
||||
if (match) {
|
||||
statusElement.textContent = match[1].trim();
|
||||
progressElement.value = Number.parseInt(match[2], 10) * 100;
|
||||
progressElement.max = Number.parseInt(match[3], 10) * 100;
|
||||
progressElement.hidden = false;
|
||||
} else {
|
||||
statusElement.textContent = text || '';
|
||||
progressElement.hidden = !text;
|
||||
if (!text) {
|
||||
progressElement.removeAttribute('value');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var Module = {
|
||||
canvas: canvasElement,
|
||||
print: (...args) => {
|
||||
console.log(...args);
|
||||
outputElement.value += `${args.join(' ')}\n`;
|
||||
outputElement.scrollTop = outputElement.scrollHeight;
|
||||
},
|
||||
printErr: (...args) => {
|
||||
console.error(...args);
|
||||
outputElement.value += `[err] ${args.join(' ')}\n`;
|
||||
outputElement.scrollTop = outputElement.scrollHeight;
|
||||
},
|
||||
setStatus,
|
||||
totalDependencies: 0,
|
||||
monitorRunDependencies(left) {
|
||||
this.totalDependencies = Math.max(this.totalDependencies, left);
|
||||
setStatus(left ? `Preparing... (${this.totalDependencies - left}/${this.totalDependencies})` : 'Running...');
|
||||
if (!left) {
|
||||
setTimeout(() => setStatus(''), 250);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fullscreenButton.addEventListener('click', () => {
|
||||
if (typeof Module.requestFullscreen === 'function') {
|
||||
Module.requestFullscreen(false, false);
|
||||
}
|
||||
});
|
||||
|
||||
globalThis.onerror = () => {
|
||||
setStatus('Exception thrown, see JavaScript console');
|
||||
};
|
||||
@@ -0,0 +1,197 @@
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
background: white;
|
||||
color: black;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
header {
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2.5rem;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.8rem;
|
||||
margin: 20px 0 15px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.3rem;
|
||||
margin: 15px 0;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
padding: 10px 15px;
|
||||
background: #f0f0f0;
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.back-button:hover,
|
||||
.action-button:hover {
|
||||
background: #e0e0e0;
|
||||
}
|
||||
|
||||
.info-box {
|
||||
background: #f9f9f9;
|
||||
border-left: 4px solid #333;
|
||||
padding: 15px;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.canvas-container {
|
||||
background: #f9f9f9;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
padding: 20px;
|
||||
margin: 30px 0;
|
||||
}
|
||||
|
||||
.canvas-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 15px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.canvas-toolbar p {
|
||||
margin: 0;
|
||||
color: #666;
|
||||
font-size: 0.95rem;
|
||||
}
|
||||
|
||||
.action-button {
|
||||
padding: 8px 12px;
|
||||
background: #f0f0f0;
|
||||
color: black;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.canvas-shell {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 500px;
|
||||
overflow: auto;
|
||||
background: white;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
#canvas {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
background: black;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.status {
|
||||
margin-top: 15px;
|
||||
min-height: 24px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
progress {
|
||||
width: 100%;
|
||||
height: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
progress[hidden] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
details {
|
||||
margin-top: 15px;
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
textarea {
|
||||
width: 100%;
|
||||
min-height: 120px;
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
font-family: "Courier New", monospace;
|
||||
font-size: 0.9rem;
|
||||
resize: vertical;
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
|
||||
footer {
|
||||
text-align: center;
|
||||
margin-top: 40px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #ccc;
|
||||
font-size: 0.85rem;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
body {
|
||||
padding: 16px;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
}
|
||||
|
||||
.canvas-container {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
.canvas-shell {
|
||||
min-height: 360px;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user