Beispiel:Tanne Worker offscreenCanvas.html
Aus SELFHTML-Wiki
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Tanne mit Worker und OffscreenCanvas</title>
<style>
#Tanne {
display: block;
margin: auto;
height: 90vh;
aspect-ratio: 0.7;
border-radius: 1em;
background-color: black;
}
</style>
<!-- https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
https://mdn.github.io/dom-examples/web-workers/offscreen-canvas-worker/-->
<script id="worker" type="javascript">
"use strict";
const tannenbaumFunktion = function(xy) {
// Nach https://en.wikipedia.org/wiki/Barnsley_fern
const P1 = 0.01;
const P2 = P1 + 0.85;
const P3 = P2 + 0.07;
const x = xy.x;
const y = xy.y;
const randomNumber = Math.random();
if ( randomNumber < P1 ) { // 1%
xy.x = 0;
xy.y = .16*y;
}
else if ( randomNumber < P2 ) { // 85%
xy.x = .85*x; // + 0.04*y;
xy.y = -0.04*x + 0.85*y + 1.6;
}
else if ( randomNumber < P3 ) { // 7%
xy.x = 0.20*x - 0.26*y;
xy.y = 0.23*x + 0.22*y + 0.44; //1.60;
}
else { // 7%
xy.x = -0.15*x + 0.28*y;
xy.y = 0.26*x + 0.24*y + 0.44;
}
return xy;
}
// Punkt bei x,y in Farbe c setzen
const punkt = function(x,y,c) {
context.fillStyle = c;
context.fillRect(x,y,1,1);
}
let canvas, context;
let canvasHeight, canvasWidth;
let px0, py0, pxfak, pyfak;
let px, py, pxy;
let color;
let Chroma = 125, Hue = 142; // green
let Lightness, maxLightness = 100;
let max = 0, Lfaktor;
const data = {};
let key;
self.addEventListener('message',function(messageEvent) {
canvas = messageEvent.data.canvas;
canvasHeight = canvas.height;
canvasWidth = canvas.width;
context = canvas.getContext("2d");
px0 = canvasWidth/2 ;
py0 = 15;
pxfak = canvasWidth/7;
pyfak = canvasHeight/12;
// Startwert
let xy = {x:1.0,y:1.0};
// 100 Blindläufe zum Einschwingen
for(let i=0;i<100;i++) xy = tannenbaumFunktion(xy);
// Aus 10000 * canvasHeight Läufen wird ein Baum
let Läufe = canvasHeight * 10000;
for(let i=0;i<Läufe;i++) {
xy = tannenbaumFunktion(xy);
px = Math.round(px0 + xy.x*pxfak);
py = Math.round(py0 + xy.y*pyfak);
key = px+"_"+py;
if(data[key]) data[key] ++;
else data[key] = 1;
if(data[key] > max) max = data[key];
}
// Grafik erstellen
Lfaktor = maxLightness/Math.log(max);
for(key in data) {
pxy = (key.split("_")).map(value => Number(value));
px = pxy[0];
py = canvasHeight - pxy[1];
Lightness = Math.ceil(Math.log(data[key])*Lfaktor);
color = `oklch(${Lightness}% ${Chroma}% ${Hue})`;
punkt(px,py,color);
}
},false);
</script>
<script type="module">
"use strict";
const workerscript = window.URL.createObjectURL(new Blob([document.getElementById("worker").textContent],{type:'application/javascript'}));
const worker = new Worker(workerscript);
const canvas = document.querySelector("#Tanne");
canvas.height = canvas.clientHeight;
canvas.width = canvas.clientWidth;
const offscreen = canvas.transferControlToOffscreen();
worker.postMessage({ canvas: offscreen }, [offscreen]);
</script>
</head>
<body>
<h1>Tanne mit Worker und OffscreenCanvas</h1>
<p>Eine Modifikation des <a href="https://en.wikipedia.org/wiki/Barnsley_fern">Barnsley fern</a></p>
<canvas id="Tanne"></canvas>
</body>
</html>