javascript
tutorial
elout
javascript creative coding 01

javascript creative coding 01

written by Elout de Kok

01 Feb 2023256 EDITIONS
1 TEZ

lets start with a simple index.html file

<!-- text and commenting in html: use  < ! -- and  -- > without spaces
first test  <p>start of a paragraph <br> line break / <b> bold  -->

<html>
<body>

<p> 
<b>hiyaaaaa!</b> 

<br> - my fist html page - 
<br> but no code at all yet!

</p>

</body>
</html>

001. Copy the code, in a 'plain' text-editor ( I use the notepad ++ myself ) and save it as like index01.html - and open/run it in a browser


html is like this text, that you can give all fancy colors, sizes, with tags <b>this is bold</b>


the <br> tag is a linebreak


Next:

my first javascript. Copy the code and save it like index02.html. and run-open it in a web-browser!

<html>
<body>

<script> // with 2 // you can comment in your javascript code

alert('yo!');

var a=4; // I have an 'a' with 4
var b=5; // I have a 'b' with 5
var c=a+b; // I add a and b, and put the result in 'c'

alert('hiyaa.. 4+5 is like: ' + c);  // and show some text, and c in an alert window-pop-up


// never forget to close it as well!
</script>

</body>
</html>

002. The alert gives like a pop-up window, you can output some text. and I do my first calculation

next setting up the basics for my javascript template


<html>
<head>

<script> 
//--------------javascript start------------------
// also changed the script now to the top of the page
// inbetween head and /head !!!!


//----------- window events --- 
window.addEventListener('load',mywindow_page_loaded, false );

// this sets an window event listener in javascript - 

// it looks technical; but it's just simple/default 'browser' tech
// for this case: when the page gets loaded, it will jump to the routine 
// mywindow_page_loaded()

// I use eventlisteners - for like checking the windowsize, mouse, touch and keyboard input
// this is default 'tech' -> the browser needs when windows-actions changes

// now  handle those events
// is the page loaded for the first time? then do this function!!
function mywindow_page_loaded() 
{
	//alert('yo!');

	var a=5; // I have an 'a' with 4
	var b=15; // I have a 'b' with 5
	var c = a + b; // I add a and b, and put the result in 'c'

	// I added a and b not as text, but as like a variable,
	// if I change it above; it also will show in the 'my_text' variable
	var my_text =  "Adding "+  a + " and "+ b + " gives me "+ c;
	
	alert(my_text);		
}

</script>

</head>
<body>

</body>
</html>

003. I will setup the basics of my javascript template next. the windows.event looks complicated tech, but it's needed for like when I do interactions with the screen, get the mouse position, window scale, keyboard etc. etc. then I need windows.events

For this example, I use a windows event, when the page gets loaded!


<html>

<head>
<script>  //--------------javascript start------------------


//----------- window events --- 

// jump to mywindow_page_loaded when the page is loaded
window.addEventListener('load',mywindow_page_loaded, false ); // ! default browser tech! call the function  mywindow_page_loaded

// page loaded? do this function; you can give it other names as well!!
function mywindow_page_loaded() 
{
	var a=5; // I have an 'a' with 4
	var b=15; // I have a 'b' with 5
	var c = a + b; // I add a and b, and put the result in 'c'

	var my_text =  "Adding "+  a + " and "+ b + " gives me "+ c;
	
	// you can use javascript to write and change the html! - 
	document.getElementById('infoblock').innerHTML = my_text; // ! default browser tech! to select my div containers etc.
	
	// In the body on the bottom I declared this  div 'container' 
	// and gave it a name; an id called --> !!!!!!! 'infoblock' !!! 
	// and next I use javascript, to select that block and write into it! 
}

</script>
</head>

<body>

<div id="infoblock">0__.</div>

</body>
</html>

004. Here I added a new div container in the html part, and use javascript next to write and change the text of the html page.



<html>

<head>
<script>  //javascript start


//----------- window events --- 
// jump to mywindow_page_loaded when the page is loaded
window.addEventListener('load',mywindow_page_loaded, false );

// page loaded? do this function!!
function mywindow_page_loaded() 
{

	// you can use javascript to write and change the html!
	document.getElementById('infoblock').innerHTML = 'page loaded - next draw in my canvas';
	
	
	// I added a canvas as well, I want to get creative! - I also gave it my own name called 'my_canvas'
	
	var canvas = document.getElementById("my_canvas"); // select the canvas with the name 'my_canvas'!
	var ctx = canvas.getContext("2d"); // browser tech - this is how it's done, I didnt made this up myself!
	ctx.font = "30px Arial"; // font size
	ctx.fillText("Hiiyyaaaa", 30, 50); // text, x,y 
	ctx.strokeText("yooz!", 60, 100); // outline text x,y
	
}

</script>
</head>

<body>

<div id="infoblock">0__.</div>

<canvas id="my_canvas">- needs a javascript enabled browser to see the drawing-animation!-</canvas>

</body>
</html>

005. Ok want to get creative next. Added also a 'canvas' with the id 'my_canvas'

and can use javascript to write and draw in it as well!



<html>

<head>

 <!-- css stylesheet -->
<style type="text/css">
body
{
	/*  background color  #rgb   you can do like 907070 or 977  just a bit more red, then green and blue*/
	background-color: #977;	
	/* these numbers are in hexadecimal! see photoshop-gimp for hex colors incase! #ffffff is white!*/

	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #ffffff;  
}

/* my info block*/
.info_css
{
	background-color: #555;
}

.canvas_css
{
	background-color: #ccc;

	position: absolute;  
	max-height: 100%; max-width: 100%;
	
	object-fit: contain;
	top: 50%; left: 50%;
	transform: translate(-50%, -50%); 	
}
</style>


<script>  //javascript start


//----------- window events --- 
// when the page is loaded
window.addEventListener('load',mywindow_page_loaded, false );

// page loaded? do this function!!
function mywindow_page_loaded() 
{

	// you can use javascript to write and change the html!
	document.getElementById('infoblock').innerHTML = 'page loaded - next draw in my canvas';
	
	
	var canvas = document.getElementById("my_canvas"); // select the canvas with the name 'my_canvas'!
	var ctx = canvas.getContext("2d"); // browser tech - this is how it's done, I didnt made this up myself!
	ctx.font = "30px Arial"; // font size
	ctx.fillText("Hiiyyaaaa", 30, 50); // text, x,y 
	ctx.strokeText("yooz!", 60, 100); // outline text x,y
	
}

</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">- error message: - needs a javascript enabled browser to see the drawing-animation!-</canvas>

</body>
</html>

006. Added a css stylesheet; where you can set the html background colors etc. so I can see the different blocks; give them different colors. and do positioning!


<html>

<head>

 <!-- css stylesheet -->
<style type="text/css">
body
{
	/*  background color  #rgb   you can do like 907070 or 977  just a bit more red, then green and blue*/
	background-color: #977;	
	/* these numbers are in hexadecimal! see photoshop-gimp for hex colors incase! #ffffff is white!*/

	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #ffffff;  
}

/* my info block*/
.info_css
{
	top: 0px;left: 0px; background-color: #558; font-size: 14px;
	border-style:none; border-width:0px; margin:0px 0px 0px 0px; 
	padding:2px 2px 2px 2px;color: #fff;  z-index:21;border-width:4px;
	position: fixed;
}

.canvas_css
{

	background-color: #ccc; /*grey now*/

	top:  0px; left: 0px; 
	z-index:20;
	position: absolute;

	border-style:solid; border-width:0px;margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; 

	/* you can set different cursor's type's' gets set again in javascript! */
	cursor: crosshair;
	/* cursor:none;   cursor: url(./cursor.cur),auto.*/

	/*this next shows my image like pixel-sharp - no pixel blurring by the browser!! */
	image-rendering:optimizeSpeed;             /* Legal fallback */
	image-rendering:-moz-crisp-edges;          /* Firefox        */
	image-rendering:-o-crisp-edges;            /* Opera          */
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */
	image-rendering:crisp-edges;               /* CSS4 Proposed  */
	image-rendering:pixelated;                 /* CSS4 Proposed  */
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */

}
</style>


<script>  //javascript start


//----------- window events --- 
// when the page is loaded
window.addEventListener('load',mywindow_page_loaded, false );

// page loaded? do this function!!
function mywindow_page_loaded() 
{
	// you can use javascript to write and change the html!
	document.getElementById('infoblock').innerHTML = 'page loaded - next draw in my canvas';
	
	
	var canvas = document.getElementById("my_canvas"); // select canvas: 'my_canvas'!
	
	// set my canvas
	var im_w = 800;  // image width 
	var im_h = 800;  // image height

        // now set the canvas width and height size 
	canvas.width = im_w; 
	canvas.height = im_h;
	


	var ctx = canvas.getContext("2d"); // browser tech 

	// introducing the for next loop! do this now 50 times
	for (var i = 0; i < 50; i++)
	{
		var red   = Math.floor(Math.random() * 255); // get a color between 0 and 255!
		var green = Math.floor(Math.random() * 255);
		var blue  = Math.floor(Math.random() * 255);
		
		var my_fontsize=Math.floor(Math.random() *  55)+9;
		ctx.font = my_fontsize+"px Verdana"; // random font size now
		
		

		var x = Math.floor(Math.random() * 420)+20; // random x and y screen position
		var y = Math.floor(Math.random() * 720)+20;
	
		ctx.fillStyle =  "rgb(0,0,0)";
		ctx.fillText("fxhash - " + i, x , y+1); // black text little offset on y!

		ctx.fillStyle =  "rgb("+red+", "+green+", "+blue+")"; // color text
		ctx.fillText("fxhash - " + i, x, y); // text, x,y position, also show the i-number !

			
		// emulate like a random dice - between 1 and 6
		var myrandom_dice = Math.floor(Math.random()*6) + 1; 
		// random number between 1 and 6 now		 
		
		x = Math.floor(Math.random() * 520)+20; // random x and y screen position
		y = Math.floor(Math.random() * 720)+20;
	
		ctx.font = "40px Arial"; // font size
		ctx.fillStyle =  "rgb( 0,0,0)";
		ctx.fillText(myrandom_dice, x, y); // text, x,y 
		
	}// end for-next loop!

	
} //end mywindow_page_loaded

</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">- error message: - needs a javascript enabled browser to see the drawing-animation!-</canvas>

</body>
</html>

007. Added different cursor support in the css, and no pixel blurring on the canvas.

(browser-tech - I didn't created that myself)


Added a for-next loop, that does a loop like x-times. A great thing to use!


And introducing Math.random! that gives a random floating point number like between 0 and 0.9999999 I can round it with Math.floor to make it like 'rounded' numbers. Also using the random; to Emulate like a dice.


And I'm going to ditch this ctx-drawing asap. since I guess you can better do that stuff in p5js- and like can be different in browsers-platforms? I'm really going to focus on rgb-pixel 'perfect' drawing and using RGB-pixel buffers!


<html>

<head>

 <!-- css stylesheet -->
<style type="text/css">
body
{
	background-color: #777;	
	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #ffffff;  
}
/* my info block*/
.info_css
{
	top: 0px;left: 0px; background-color: #558; font-size: 14px;
	border-style:none; border-width:0px; margin:0px 0px 0px 0px; 
	padding:2px 2px 2px 2px;color: #fff;  z-index:21;border-width:4px;
	position: fixed;
}
.canvas_css
{
	background-color: #ccc; /*grey now*/

	top:  0px; left: 0px; 
	z-index:20;
	position: absolute;

	border-style:solid; border-width:0px;margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; 

	/* you can set different cursor's type's' gets set again in javascript! */
	cursor: crosshair;
	/* cursor:none;   cursor: url(./cursor.cur),auto.*/

	/*this next shows my image like pixel-sharp - no pixel blurring by the browser!! */
	image-rendering:optimizeSpeed;             /* Legal fallback */
	image-rendering:-moz-crisp-edges;          /* Firefox        */
	image-rendering:-o-crisp-edges;            /* Opera          */
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */
	image-rendering:crisp-edges;               /* CSS4 Proposed  */
	image-rendering:pixelated;                 /* CSS4 Proposed  */
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */
}
</style>


<script>  //javascript start

// using some global variables now! I can use every where!

// my screen - canvas size now!
var im_w = 800;  // image - canvas width 
var im_h = 800;  // image - canvas height


//----------- window events --- 
// when the page is loaded
window.addEventListener('load',mywindow_page_loaded, false );

// page loaded? do this function!!
function mywindow_page_loaded() 
{
	// get the browser window size! - browser tech!
	var win_w=window.innerWidth;
	var win_h=window.innerHeight;
	 
	// and show the window size in the text: info block! - nice for testing!
	document.getElementById('infoblock').innerHTML = 'window width: '+win_w +' window height: '+win_h;

	var c = document.getElementById("my_canvas"); // select canvas: 'my_canvas'!
	var ctx=c.getContext("2d");
	
	c.width = im_w; // set my canvas to my im_w and im_h size!
	c.height = im_h;
		

	// set the canvas position now with javascript! 
	// pretty simple-crude now; will do better later on
	var xpos=(win_w - im_w)/2;
	var ypos=(win_h - im_h)/2;
	
	// position my canvas!
	c.style.left= xpos+'px';
	c.style.top = ypos+'px';

			
	// make a new empty'data' image
	// and fill my canvas with it!
	// now with some random grey-noise!
	var img1 = ctx.createImageData(im_w, im_h); // create an empty data image - with width, height
	
	for (var p=0, j = 0; j < im_h*im_w; j++) // do for every pixel on the screen!
	{			
			var grey = Math.floor(Math.random() * 256);
			img1.data[p++] = grey;	// red
			img1.data[p++] = grey;	// green
			img1.data[p++] = grey;	// blue
			img1.data[p++] = 255;   // alpha channel; not used atm
	}
	ctx.putImageData(img1, 0, 0);	// and draw it to my canvas!

	
} //end mywindow_page_loaded

</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">- error message: - needs a javascript enabled browser to see the drawing-animation!-</canvas>

</body>
</html>

008. Next I'm going to use like a data image; and write it to my canvas. The data-pixels I fill now with a random grey color: between 0 and 255 (0= total black 255=total white)


<html>

<head>

 <!-- css stylesheet -->
<style type="text/css">
body
{
	background-color: #777;	
	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #ffffff;  
}
/* my info block*/
.info_css
{
	top: 0px;left: 0px; background-color: #558; font-size: 14px;
	border-style:none; border-width:0px; margin:0px 0px 0px 0px; 
	padding:2px 2px 2px 2px;color: #fff;  z-index:21;border-width:4px;
	position: fixed;
}
.canvas_css
{
	background-color: #ccc; /*grey now*/

	top:  20px; left: 20px; 
	z-index:20;
	position: absolute;

	border-style:solid; border-width:0px;margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; 

	/* you can set different cursor's type's' gets set again in javascript! */
	cursor: crosshair;
	/* cursor:none;   cursor: url(./cursor.cur),auto.*/

	/*this next shows my image like pixel-sharp - no pixel blurring by the browser!! - old legacy code from the internet  */
	image-rendering:optimizeSpeed;             /* Legal fallback */ 
	image-rendering:-moz-crisp-edges;          /* Firefox        */ 
	image-rendering:-o-crisp-edges;            /* Opera          */ 
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */ 
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */ 
	image-rendering:crisp-edges;               /* CSS4 Proposed  */ 
	image-rendering:pixelated;                 /* CSS4 Proposed  * 
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */
}
</style>


<script>  //javascript start

// using some global variables now! I  use all the time now! and I can tune

//- my image / canvas size -
var im_w = 320;  // image - canvas width 
var im_h = 240;  // image - canvas height



//---------init tech - window management -  window scaling etc. - tech -
var win_w; // window width - gets set in mywindow_page_loaded
var win_h; // window height
	
//----------- window events --- 
//----------legacy code, from the internet-tech------------------------------------
// sets the animation at 60 fps
if ( !window.requestAnimationFrame ) 
{
	window.requestAnimationFrame = ( function() {
		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame ||
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function(callback, element ) {window.setTimeout( callback, 1000 / 60 );};
	} )();
}

	//!!!!!!!____Init here_____!!!!!!!!!!!!
// do wen the page is loaded - tech -
window.addEventListener('load',init_mywindow, false ); 


// init  - tech -
function init_mywindow() 
{
	// get the browser window size! - browser tech!
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	 
	// and show the window size in the text: info block! - nice for testing!
	document.getElementById('infoblock').innerHTML = 'window width: '+win_w +' window height: '+win_h;

	// but hide it for now~! since animation !
	document.getElementById('infoblock').style.visibility = "hidden";

	//---------------------------windows check on resize
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// when browser window gets resized - tech -
	window.addEventListener( 'resize', onWindowResize, false );

	// set the size of the canvas
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';
			
	animate(); // !!!____Init__ and trigger-start the animation
} 

//---window stuff
function onWindowResize() 
{
	win_w=window.innerWidth;
	win_h=window.innerHeight;	
}

function animate() 
{
	requestAnimationFrame( animate );
	draw();
}

// the animation-drawing set at 60fps frames per second atm
function draw()
{
	//now blit bomb data to the screen
	var c = document.getElementById("my_canvas"); // select canvas: 'my_canvas'!
	var ctx=c.getContext("2d");
	
	c.width = im_w; // set my canvas to my im_w and im_h size!
	c.height = im_h;
		
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';

	
	// Now finally draw something on the screen !!~ 
	// now  some random grey-noise pixels!
	var img1 = ctx.createImageData(im_w, im_h); // browser tech - create a new image: width, height
	
	for (var p=0, j = 0; j < im_h*im_w; j++) // draw those pixels on the screen!
	{			
			var grey = Math.floor(Math.random() * 256); // get a random grey color
			img1.data[p++] = grey;	// red
			img1.data[p++] = grey;	// green
			img1.data[p++] = grey;	// blue
			img1.data[p++] = 255;   // alpha channel; not used atm
	}
	ctx.putImageData(img1, 0, 0);	// and draw the data image to the canvas!
	
}

// javascript end
</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">-__-</canvas>

</body>
</html>

009. Next Lets start to animate these pixels ! Full-screen; real low res for now! Added a window_resizing check and the animation support (tech)



nxt plz!

-simple fxhash templates- 0__.


lil break:
!!!! Always use latest fxhash snippet!! this example below uses an older one!!!
<!doctype html>
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>0__.</title>

<!--the favicon a 16x16 .png image 
- why ? cause we can!
- ipfs often gives an error message, when you don't have a favicon
 I convert my 16x16 .png here -  www.base64-image.de -->

<link rel="icon" type="image/png" sizes="16x16" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5wIDFzsQl4w3vQAAATFJREFUOMudk7GNwzAMRd8xFuA0LpIuEGDIO3iFjBDAC6TMEBmHI6RxmYJDpMgS7nTFnQRZgYs7AsLH//wgJUrCOReBGEKIQKz5lp64+PcdEYHnla7r8O87XdfB85r1aZoofSKCf9+ZpglSpXolPXcSyfx4PGbEzCIQ/4JN02ROfdaEaW3ls8/M4m63i2YWD4fDCpN+u91WvNSpO21Ou5hBuUMJIZDCOcd+v8c5lzXvPcMwcDqdMgcIITAMA3kGaSg138LkE1XN3dq2RVVp25YyxnGkDlVlHEekFJdl4XK5sCzLymxmnM/njyJm9lMgnbnve1SVvu9XxnmeeTwe2Zdwnme+fqf57xAzo2kazAzv/QqTrqorXurUb37rF9b5/A7SvSZM8Xq9si4iH/kQAiLCNyE2CBjl+pJJAAAAAElFTkSuQmCC" />


 <!-- css stylesheet -->
<style type="text/css">
body
{
	background-color: #777;	
	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #fff;  
}
/* my info block*/
.info_css
{
	color: #fff; font-size: 14px; background-color: #558; 
	z-index:21;
	position: fixed;	
	top:0px;left:0px;
	border-style:none; border-width:4px;
	margin:0px 0px 0px 0px; padding:2px 2px 2px 2px;
}
.canvas_css
{
	z-index:20;
	position: absolute;

	border-style:solid; border-width:0px;
	margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; 

	/*this next shows my image like pixel-sharp - no pixel blurring by the browser!! - old legacy code from the internet  */
	image-rendering:optimizeSpeed;             /* Legal fallback */ 
	image-rendering:-moz-crisp-edges;          /* Firefox        */ 
	image-rendering:-o-crisp-edges;            /* Opera          */ 
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */ 
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */ 
	image-rendering:crisp-edges;               /* CSS4 Proposed  */ 
	image-rendering:pixelated;                 /* CSS4 Proposed  * 
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */
}
</style>


<script id="fxhash-snippet">
  //---- do not edit the following code (you can indent as you wish)
  let alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
  var fxhash = "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join('')
  let b58dec = str=>[...str].reduce((p,c)=>p*alphabet.length+alphabet.indexOf(c)|0, 0)
  let fxhashTrunc = fxhash.slice(2)
  let regex = new RegExp(".{" + ((fxhashTrunc.length/4)|0) + "}", 'g')
  let hashes = fxhashTrunc.match(regex).map(h => b58dec(h))
  let sfc32 = (a, b, c, d) => {
    return () => {
      a |= 0; b |= 0; c |= 0; d |= 0
      var t = (a + b | 0) + d | 0
      d = d + 1 | 0
      a = b ^ b >>> 9
      b = c + (c << 3) | 0
      c = c << 21 | c >>> 11
      c = c + t | 0
      return (t >>> 0) / 4294967296
    }
  }
  var fxrand = sfc32(...hashes)
  // true if preview mode active, false otherwise
  // you can append preview=1 to the URL to simulate preview active
  var isFxpreview = new URLSearchParams(window.location.search).get('preview') === "1"
  // call this method to trigger the preview
  function fxpreview() {
    console.log("fxhash: TRIGGER PREVIEW")
  }
  //---- /do not edit the following code
</script>



<script type="text/javascript">  //my javascript start

// using some global variables now! I  use all the time now! and I can tune


// you can change this when starting something new
var cversion="pixeldrop"; // title of the page, also name of the saved image
document.title =cversion;

var show_fps =    false;//     true;//  false;  // put this on wen testing!


var win_w;
var	win_h;
	
	
//- my image / canvas / animation screen-pixel size -
var im_w = 1024;  // image - canvas width 
var im_h = 768;  // image - canvas height


var temp_my_r=my_random_int(255);
var temp_my_g=my_random_int(255);
var temp_my_b=my_random_int(255); 	

//-----------------------------------tech--------------------------------------------------------


// my r g b pixel buffer  
var pix_r = new Uint8ClampedArray(im_w*im_h); // I only use Uint8ClampedArray for the image output buffer! 
var pix_g = new Uint8ClampedArray(im_w*im_h); // it can be 'buggy/funky', wen using it like a normal array
var pix_b = new Uint8ClampedArray(im_w*im_h);

// You don't need to understand the tech too much, but it's needed to get the car running smooth.

// globals to keep track of the animation
var animation_part=0;
var anim_loop=0;
var do_once=0;
var my_pause=false;
//---------init tech - window management -  window scaling etc. - tech -
var save_image=false;

//----------- show fps------------
var my_timer=setInterval(function(){timer_fps()},1000);//1000
var data_fps=0;
var counter_fps=0;
var timeCurrent, timeLast = Date.now();	
var test=""; // for testing  

//----------- window events --- 
//----------legacy code, from the internet (not mine)- tech------------------------------------
// sets the animation at 60 fps
if ( !window.requestAnimationFrame ) 
{
	window.requestAnimationFrame = ( function() {
		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame ||
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function(callback, element ) {window.setTimeout( callback, 1000 / 60 );};
	} )();
}

	//!!!!!!!____Init here_____!!!!!!!!!!!!
// do wen the page is loaded - tech -
window.addEventListener('load',init_mywindow, false ); 


// ------------tech next: keys, mouse and windows handling --------------------

document.addEventListener('keyup', function(event)
{
	// saving is now handled in the draw() function!
	if (event.code == 'KeyS') // s key
	{  
		save_image=true;
	}
	if (event.code == 'Space') // spacebar key gets paused in  the draw() function!
	{  
		if(my_pause==false){my_pause=true;}else {my_pause=false;}
	}	
	
}); 
	
// init  - tech -
function init_mywindow() 
{

	// hide info text block when showfps is  false
	if(show_fps==false){document.getElementById('infoblock').style.visibility = "hidden";}
	else {document.getElementById('infoblock').style.visibility = "visible";}
	
	//---------------------------windows check on resize
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// when browser window gets resized - tech -
	window.addEventListener( 'resize', onWindowResize, false );

	// set the size of the canvas
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';

	animate(); // !!!____Init__ and trigger-start the animation
} 

//---window stuff
function onWindowResize() 
{
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// set the size of the canvas
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';
}



// html - set text; and dump the html/text in a div
function set_msg(div, msg){document.getElementById(div).innerHTML = msg;}
function go_msg(div, msg) {document.getElementById(div).innerHTML += msg;} // add to your text message


// legacy code from the internet - quick and dirty fps counter!
function timer_fps() // dirty fps counter 
{
	timeCurrent = Date.now();
	if (show_fps==true)
	{
		var fpsThisFrame = 1000 / (timeCurrent - timeLast);
		if(timeCurrent > timeLast) 
		{
			set_msg('infoblock', 'fps:' + counter_fps + test);
			timeLast = timeCurrent;
			counter_fps=0;
		}
	}	
}


 //--- my random functions based on fxrand()------------

	function my_random_int(nummer){return ( ((fxrand()*nummer) << 0) );} //int: returns random number int!
	//   << 0 is a fast hack for Math.floor or Math.round

	function my_random_dub(nummer){return ( fxrand()*nummer );} //float: return random number float! 

	function my_random_int_minplus(nummer){return  (  ( (fxrand() * (nummer*2)) - nummer) << 0 );} 
	//int: returns random number int! between -num +num

	function my_random_dub_minplus(nummer){return  ( (fxrand() * (nummer*2)) - nummer)  ;} 
	//float: return random number float! between -num +num
	
//-------------------------------------------------------------------------------
function animate() 
{
	requestAnimationFrame( animate );
	if (show_fps==true){counter_fps++;}
	draw();
}

// the animation-drawing set at 60fps frames per second atm
function draw()
{

	if(my_pause==false) // check if the animation is not paused with spacebar
	{
		my_animation();
	}
	
	//now blit-bomb the data to the screen
	var c = document.getElementById("my_canvas"); // select canvas: 'my_canvas'!
	var ctx=c.getContext("2d");	
 	c.width = im_w; // set my canvas to my im_w and im_h size!
 	c.height = im_h;
	
	// dump the rgb buffer to the screen
	var img1 = ctx.createImageData(im_w, im_h); // browser tech - create a new image: width, height	
	for (var p=0, j = 0; j < im_h*im_w; j++) // draw those pixels on the screen!
	{			
			var grey = Math.floor(Math.random() * 256); // get a random grey color
			img1.data[p++] = pix_r[j];	// red
			img1.data[p++] = pix_g[j];	// green
			img1.data[p++] = pix_b[j];	// blue
			img1.data[p++] = 255;   // alpha channel; not used atm
	}
	ctx.putImageData(img1, 0, 0);	// and draw the data image to the canvas!
	
	
	if (save_image==true) // save image 
	{
		var imagename=cversion+'_'+fxhash+'_'+'.png';
		var my_download = document.createElement('a');
		my_download.setAttribute('download', imagename);
			
		var mcanvas = document.getElementById('my_canvas');
		mcanvas.toBlob(function(blob) {
						var url = URL.createObjectURL(blob);
						my_download.setAttribute('href', url);
						my_download.click();	
						}); 						
		save_image=false;
	}
	
} // end draw()
//---------------------------end tech--------------------

// !-------------- --- next the creative part -----------!


function my_animation()
{



	if (animation_part==0)
	{	
		animation_part++; // go next!
	}
	
	// init animation part
	else if (animation_part==1)
	{	
		anim_loop=0;
		animation_part++;
	}
		
	// draw random grey background 
	else if (animation_part==2)
	{

		// fill the screen with random noise				
		for (var j = 0; j < im_h; j++) // y
		{
			var grey=my_random_int(255); // just grey horizontal bars	now		
			var p1=j*im_w;
			for (var i = 0; i <  im_w; i++) // x
			{
				var p2=p1+i; // pixel position!	
				pix_r[p2]=grey;
				pix_g[p2]=grey;
				pix_b[p2]=grey;
			}	
		}	
		
		anim_loop=0;
		animation_part++;
	}
	
	
	// init next drawing
	else if (animation_part==3)
	{	
		anim_loop=0;
		animation_part++; // go next
	}

	// draw 'grate' squares
	else if (animation_part==4)
	{
	
		for (var soz = 0; soz <  100; soz++) // draw faster and more ! watch fps!
		{			
			var x1 = my_random_int(im_w) + my_random_int_minplus(100);
			var y1 = my_random_int(im_h) + my_random_int_minplus(100);
		 
			var randomsizex= 1+my_random_int(700);
			var randomsizey= 1+my_random_int(30);
		 
			var x2 = x1+randomsizex;
			var y2 = y1+randomsizey;
		 
			// important don't draw outside my screen! - check the position when drawing
			if(x1<0){x1=0;} if(y1<0){y1=0;}	if(x2<0){x2=0;} if(y2<0){y2=0;}
			if(x1 >= im_w){x1=im_w-1;} if(y1 >= im_h){y1=im_h-1;}
			if(x2 >= im_w){x2=im_w-1;} if(y2 >= im_h){y2=im_h-1;}
		 
			if(my_random_int(6999)==0)  //  new random color!
			{
				temp_my_r=my_random_int(255);
				temp_my_g=my_random_int(255);
				temp_my_b=my_random_int(255); 			
			}
			var r=temp_my_r;//my_random_int(255);
			var g=temp_my_g;//my_random_int(255); 
			var b=temp_my_b;//my_random_int(255); 
			
			if(my_random_int(2)==0)  //  random color green and blue
			{
				r=temp_my_r/2<<0;
				g=temp_my_g/2<<0;
				b=temp_my_b/2<<0;			
			}	
			
			if(my_random_int(14)==0)  //  random grey
			{
				g=r;//my_random_int(255);
				b=r;//my_random_int(255);
			}
		 
			var istep= 1 + my_random_int(16); // do extra step on x or y
			var jstep= 1 + my_random_int(16);
	
			// draw a rectangle
		
			var mode2 = my_random_int(3); // choose a random drawing mode	
			if(mode2 == 0) // draw hard r-g-b
			{
				var num=2+my_random_int(61);
				var deel=num+1;
				var bright=0.5+my_random_dub(7);
				for (var j = y1; j < y2; j=j+jstep) // y
				{
					var p1=j*im_w;
					for (var i = x1; i <  x2; i=i+istep) // x
					{
						var p2=p1+i; // pixel position!					
						pix_r[p2]=( ( (num*pix_r[p2])+(r*bright) ) / deel) <<0;
						pix_g[p2]=( ( (num*pix_g[p2])+(g*bright) ) / deel) <<0;
						pix_b[p2]=( ( (num*pix_b[p2])+(b*bright) ) / deel) <<0;
					}	
				}		
			}		
			else if(mode2 == 1) // draw simple blend mode r-g-b
			{
				var num=17+ my_random_int(41);
				var deel=num+1;	
				for (var j = y1; j < y2; j=j+jstep) // y
				{
					var p1=j*im_w;
					for (var i = x1; i <  x2; i=i+istep) // x
					{
						var p2=p1+i; // pixel position!
						pix_r[p2]=(( (num*pix_r[p2]) + r)/deel) <<0;
						pix_g[p2]=(( (num*pix_g[p2]) + g)/deel) <<0;
						pix_b[p2]=(( (num*pix_b[p2]) + b)/deel) <<0;
					}	
				}		
			}
			else if(mode2 == 2) ////min - darken - the shade
			{
				x1 = my_random_int(im_w)-1100 + my_random_int_minplus(1400);
				y1 = my_random_int(im_h)-1100 + my_random_int_minplus(1400);
		
				randomsizex= 1+my_random_int(1100);
				randomsizey= 1+my_random_int(1100);
		 
				x2 = x1+randomsizex;
				y2 = y1+randomsizey;
		
				// important don't draw outside my screen! - check the position when drawing
				if(x1<0){x1=0;} if(y1<0){y1=0;}	if(x2<0){x2=0;} if(y2<0){y2=0;}
				if(x1 >= im_w){x1=im_w;} if(y1 >= im_h){y1=im_h;}
				if(x2 >= im_w){x2=im_w;} if(y2 >= im_h){y2=im_h;}
		
				for (var j = y1; j < y2; j=j+jstep) // y
				{
					var p1=j*im_w;
					for (var i = x1; i <  x2; i=i+istep) // x
					{
						var p2=p1+i; // pixel position!
						pix_r[p2]=pix_r[p2]/3 << 0; 
						pix_g[p2]=pix_g[p2]/3 << 0; 
						pix_b[p2]=pix_b[p2]/3 << 0; 
					}	
				}		
			}// end mode2	
			
		}	// end draw faster	
		
		
		// go next
		anim_loop++; 			 
		if(anim_loop>51) // draw x times!
		{
			anim_loop=0;
			animation_part= 100; // go to the end
		}
	}
	
	
	// ------------------- end of animation, wrap it up-----------------------------
	else if (animation_part==100)
	{		
		anim_loop++; 	
		if(anim_loop==100 && do_once==0)
		{
			fxpreview(); // now make the fxhash thumbnail - preview image
			do_once=1; // and do this only at the start	
		}		 
		if(anim_loop>200) // wait a bit to go next
		{
			anim_loop=0;
			animation_part= 101; // go next - end
		}
		
		if(do_once==1)
		{
			animation_part= 101; // directly go to end, no need to wait or fxpreview anymore+
		}
	
	}
	else if (animation_part==101)
	{		
			animation_part=3;	// reset-continue with the animation; restart at 3 now 
	}


} // end my_animation()


// javascript end
</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">-__-</canvas>

</body>
</html>

10. Ok what's in this one?

coding hacks I use a lot

see it working here - https://elout.home.xs4all.nl/drawz/index10e.html



- template 11 -

11. Animation template #2

see it working on https://elout.home.xs4all.nl/drawz/index11_strip.html

index.html - source for 11 - pixeldrop


!!! Note: These examples use an older fxhash-snippet! Always use the latest one, when you want to test and upload it on fxhash !!!


<!doctype html>
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>0__.</title>

<!--favicon 16x16 .png -  created at www.base64-image.de -->
<link rel="icon" type="image/png" sizes="16x16" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5wIEFwEbuCAI9QAAAItJREFUOMul0jELwkAMhuHXa8TRQXBw082f7x+qW4eu4lh0uaHoGwg0kOUhHN/lbveADz81Ajf+yzwGGXwDVY9FBl9A1TXBNUlg3mSOCS9zvcI5uYJ5G3qsdc9imWsCkgRUl3hJlmjeln7qup9imW9/xq0J9B8ckgWax0nwDlQ9wk7tXfHYy+ARqPoXAl41bXJi4ncAAAAASUVORK5CYII=" />


 <!-- css stylesheet -->
<style type="text/css">
body
{
	background-color: #777;	
	margin:	0;padding: 0; 	
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; color: #fff;  
}

.info_css
{
	color: #fff; font-size: 14px; background-color: #558; 
	z-index:21;
	position: fixed;	
	top:0px;left:0px;
	border-style:none; border-width:4px;
	margin:0px 0px 0px 0px; padding:2px 2px 2px 2px;
}

.canvas_css
{
	z-index:20;
	position: absolute;

	border-style:solid; border-width:0px;
	margin:0px 0px 0px 0px; padding:0px 0px 0px 0px; 

	/*this next shows my image like pixel-sharp - no pixel blurring by the browser!! - old legacy code from the internet  */
	image-rendering:optimizeSpeed;             /* Legal fallback */ 
	image-rendering:-moz-crisp-edges;          /* Firefox        */ 
	image-rendering:-o-crisp-edges;            /* Opera          */ 
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */ 
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */ 
	image-rendering:crisp-edges;               /* CSS4 Proposed  */ 
	image-rendering:pixelated;                 /* CSS4 Proposed  * 
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */
}
</style>


<script id="fxhash-snippet">
  //---- do not edit the following code (you can indent as you wish)
  let alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
  var fxhash = "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join('')
  let b58dec = str=>[...str].reduce((p,c)=>p*alphabet.length+alphabet.indexOf(c)|0, 0)
  let fxhashTrunc = fxhash.slice(2)
  let regex = new RegExp(".{" + ((fxhashTrunc.length/4)|0) + "}", 'g')
  let hashes = fxhashTrunc.match(regex).map(h => b58dec(h))
  let sfc32 = (a, b, c, d) => {
    return () => {
      a |= 0; b |= 0; c |= 0; d |= 0
      var t = (a + b | 0) + d | 0
      d = d + 1 | 0
      a = b ^ b >>> 9
      b = c + (c << 3) | 0
      c = c << 21 | c >>> 11
      c = c + t | 0
      return (t >>> 0) / 4294967296
    }
  }
  var fxrand = sfc32(...hashes)
  // true if preview mode active, false otherwise
  // you can append preview=1 to the URL to simulate preview active
  var isFxpreview = new URLSearchParams(window.location.search).get('preview') === "1"
  // call this method to trigger the preview
  function fxpreview() {
    console.log("fxhash: TRIGGER PREVIEW")
  }
  //---- /do not edit the following code
</script>



<script type="text/javascript">  //my javascript start

// using some global variables now! I  use all the time now! and I can tune

// gets current browser window size
var win_w=window.innerWidth;
var win_h=window.innerHeight;


// !!!you can change this when starting something new!!!

var cversion="pixeldrop_"; // title of the page, also name of save file!
document.title =cversion;

var show_fps =        true;//  false;  // put this on wen testing!
	
//- my image / canvas / animation screen-pixel size now-
var im_w = 800;  // image - canvas width 
var im_h = 800;  // image - canvas height







// globals used for my colorlines 
var myco_num = 0;

var myco_x1 = new Array();
var myco_y1 = new Array();
var myco_x2 = new Array();
var myco_y2 = new Array(); 

var myco_xspeed = new Array();
var myco_yspeed = new Array();

var myco_direction = new Array();

var myco_r1 = new Array();
var myco_g1 = new Array();
var myco_b1 = new Array();

var myco_istep = new Array();
var myco_jstep = new Array();

var myco_fade = new Array();
var myco_mode2 = new Array();

  
  
// for my palette
var pallet_num=0;
var pallet_r = new Array();
var pallet_g = new Array();
var pallet_b = new Array();


//-----------------------------------tech--------------------------------------------------------

// rgb pixel buffer  
var pix_r = new Uint8ClampedArray(im_w*im_h);
var pix_g = new Uint8ClampedArray(im_w*im_h);
var pix_b = new Uint8ClampedArray(im_w*im_h);



// globals animation
var animation_part=0;
var anim_loop=0;
var do_once=0;

var my_pause=false; // pause anim
var save_image=false;
	
//----------- show fps------------
var my_timer=setInterval(function(){timer_fps()},1000);//1000
var data_fps=0;
var counter_fps=0;
var timeCurrent, timeLast = Date.now();	
var test=""; // for testing  !! gets used in fps-counter!

//----------- window events --- 
//----------legacy code, from the internet (not mine)- tech------------------------------------
// sets the animation at 60 fps
if ( !window.requestAnimationFrame ) 
{
	window.requestAnimationFrame = ( function() {
		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame ||
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function(callback, element ) {window.setTimeout( callback, 1000 / 60 );};
	} )();
}

// wen the page is loaded, jump here! - tech -
window.addEventListener('load',init_mywindow, false ); 

// ------------tech next: keys, mouse and windows handling --------------------
document.addEventListener('keyup', function(event)
{
	// saving is now handled in the draw() function!
	if (event.code == 'KeyS') // s key save in the draw() function!
	{  
		save_image=true;
	}
	if (event.code == 'Space') // spacebar key gets paused in  the draw() function!
	{  
		if(my_pause==false){my_pause=true;}else {my_pause=false;}
	}	
	
}); 

// init  - tech -
function init_mywindow() 
{
	// hide info text block when showfps is  false
	if(show_fps==false){document.getElementById('infoblock').style.visibility = "hidden";}
	else {document.getElementById('infoblock').style.visibility = "visible";}
	
	//---------------------------windows check on resize
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// window resize? do this.  
	window.addEventListener( 'resize', onWindowResize, false );

	// set the size of the canvas
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';

	animate(); // !!!____Init__ and trigger-start the animation
} 

//---window stuff
function onWindowResize() 
{
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// scale / sets the size of the canvas
	document.getElementById('my_canvas').style.width = win_w+'px'; 
	document.getElementById('my_canvas').style.height= win_h+'px';	
	document.getElementById('my_canvas').style.left= 0+'px';
	document.getElementById('my_canvas').style.top = 0+'px';	
}

// html - set text; and dump the html/text in a div
function set_msg(div, msg){document.getElementById(div).innerHTML = msg;}
function go_msg(div, msg) {document.getElementById(div).innerHTML += msg;} // add text


// legacy code from the internet - quick and dirty fps counter!
function timer_fps() // dirty fps counter 
{
	timeCurrent = Date.now();
	if (show_fps==true)
	{
		var fpsThisFrame = 1000 / (timeCurrent - timeLast);
		if(timeCurrent > timeLast) 
		{
			set_msg('infoblock', 'fps:' + counter_fps+test);
			timeLast = timeCurrent;
			counter_fps=0;
		}
	}	
}


 //--- my random using fxrand()------------

function my_random_int(nummer){return ( ((fxrand()*nummer) << 0) );} //int 

function my_random_dub(nummer){return ( fxrand()*nummer );} //float

function my_random_int_minplus(nummer){return  (  ( (fxrand() * (nummer*2)) - nummer) << 0 );} 
//returns int:  between -num +num
function my_random_dub_minplus(nummer){return  ( (fxrand() * (nummer*2)) - nummer)  ;} 
//returns float:  between -num +num
	
//-------------------------------------------------------------------------------
function animate() 
{
	requestAnimationFrame( animate );
	if (show_fps==true){counter_fps++;}
	draw();
}

// the animation-drawing set at 60fps frames per second atm
function draw()
{

	if(my_pause==false) // check if the animation is not paused with spacebar
	{
		my_animation();
	}

	//now blit-bomb the data to the screen
	var c = document.getElementById("my_canvas"); // select canvas: 'my_canvas'!
	var ctx=c.getContext("2d");	
 	c.width = im_w; // set my canvas to my im_w and im_h size!
 	c.height = im_h;
	
	// dump the rgb buffer to the screen
	var img1 = ctx.createImageData(im_w, im_h); // browser tech - create a new image: width, height	
	for (var p=0, j = 0; j < im_h*im_w; j++) // draw those pixels on the screen!
	{			
			var grey = Math.floor(Math.random() * 256); // get a random grey color
			img1.data[p++] = pix_r[j];	// red
			img1.data[p++] = pix_g[j];	// green
			img1.data[p++] = pix_b[j];	// blue
			img1.data[p++] = 255;   // alpha channel; not used atm
	}
	ctx.putImageData(img1, 0, 0);	// and draw the data image to the canvas!
	
	// legacy code and trick from the interwebz 
	if (save_image==true) // save image 
	{
		var imagename= cversion+'_'+fxhash+'_'+'.png'; // I also save the fxhashkey!
		var my_download = document.createElement('a');
		my_download.setAttribute('download', imagename);
			
		var mcanvas = document.getElementById('my_canvas');
		mcanvas.toBlob(function(blob) {
						var url = URL.createObjectURL(blob);
						my_download.setAttribute('href', url);
						my_download.click();	
						}); 						
		save_image=false;
	}
	
	
	
}
//---------------------------end tech--------------------
// you can use and learn from the tech

// the creative part and fine-tuning, you should do yourself !HF!

// !-------------- --- next the creative part -----------!


function init_my_palette()
{
	var palet_data=[
	200,20,20,   205, 205, 205 // r1 g1 b1 r2 g2 b2
	];
	// I will use this later to collect my favourite palettes 
	// - put fps on to see the rgb numbers
	pallet_num=0;
	
	palet_data[0]=my_random_int(255); // now just give 2 random colors
	palet_data[1]=my_random_int(255);
	palet_data[2]=my_random_int(255);
	
	palet_data[3]=my_random_int(255);
	palet_data[4]=my_random_int(255);
	palet_data[5]=my_random_int(255);
	
	// outputs text to the fps-info
	test="<hr><hr>----rgb----rgb---<hr>		" + "<b><span style='color:rgb("+palet_data[0]+","+palet_data[1]+","+palet_data[2]+");'>"+palet_data[0]+","+palet_data[1]+","+palet_data[2]+","+"</span>"+"<span style='color:rgb("+palet_data[3]+","+palet_data[4]+","+palet_data[5]+");'>"+palet_data[3]+","+palet_data[4]+","+palet_data[5]+", "+"</span></b><hr><hr>"	
	// you can either use " or ' 

	for (var i = 0; i <  6; i++) // fade to dark   rgb 1
	{
		pallet_r[pallet_num]= palet_data[0] - (i*12);
		pallet_g[pallet_num]= palet_data[1] - (i*12);
		pallet_b[pallet_num]= palet_data[2] - (i*12);
		pallet_num++;
	}
	for (var i = 0; i <  6; i++) // fade to dark   rgb 2
	{
		pallet_r[pallet_num]= palet_data[3] - (i*12);
		pallet_g[pallet_num]= palet_data[4] - (i*12);
		pallet_b[pallet_num]= palet_data[5] - (i*12);
		pallet_num++;
	}
	for (var i = 0; i <  6; i++) // fade to dark   grey 
	{
		pallet_r[pallet_num]= ((palet_data[0]+palet_data[1]+palet_data[2])/2) - (i*12)<<0;
		pallet_g[pallet_num]= pallet_r[pallet_num];
		pallet_b[pallet_num]= pallet_r[pallet_num];
		pallet_num++;
	}
	
	// little error check for
	for (var i = 0; i <  pallet_num; i++)
	{
		if(pallet_r[i]<0){pallet_r[i]=0;}
		if(pallet_g[i]<0){pallet_g[i]=0;}
		if(pallet_b[i]<0){pallet_b[i]=0;}
	}

}


function my_animation()
{
	// start init animation!
	if (animation_part==0)
	{
		init_my_palette();
		
		var grey=my_random_int(255); // just a grey screen	now		
		
		//clear screen!	
		for (var j = 0; j < im_h; j++) // y
		{
			var p1=j*im_w;
			for (var i = 0; i <  im_w; i++) // x
			{
				var p2=p1+i; // pixel position!
				pix_r[p2]=grey;
				pix_g[p2]=grey;
				pix_b[p2]=grey;
			}	
		}	
				
		
		animation_part++; //// go next!
	}
	
	
	// init --animation anim--
	else if (animation_part==1)
	{
		init_my_palette();
		myco_num = 0;

			
		var myran= 20 + my_random_int(20); // number of lines?
		for (var i = 0; i < myran; i++)
		{		
			myco_x1[myco_num] = my_random_int(im_w)-120;
			myco_y1[myco_num] = my_random_int(im_h);
			myco_x2[myco_num] = myco_x1[myco_num]+my_random_int(im_w);
			myco_y2[myco_num] = myco_y1[myco_num] + 1 + my_random_int(30);
			
			if(myco_x1[myco_num]<0){myco_x1[myco_num]=0;} // little out of bounds check
			if(myco_x1[myco_num]>im_w){myco_x1[myco_num]=im_w;}
			
	
			myco_xspeed[myco_num] = 0.2 + my_random_dub(2);
			myco_yspeed[myco_num] = 0.1 + my_random_dub(2);
	
			myco_direction[myco_num] = my_random_int(2);

			var col= my_random_int(pallet_num); 		
			myco_r1[myco_num]=pallet_r[col];
			myco_g1[myco_num]=pallet_g[col];
			myco_b1[myco_num]=pallet_b[col];
			
			myco_istep[myco_num] = 1;//  + my_random_int(7);
			myco_jstep[myco_num] = 1;//  + my_random_int(7);
			if(my_random_int(10)==0)
			{
				myco_istep[myco_num] = 1  + my_random_int(7);
				myco_jstep[myco_num] = 1   + my_random_int(7);
			
			}
			myco_fade[myco_num]= 1 + my_random_int(31);
			
			myco_mode2[myco_num]=   my_random_int(2);
			
			myco_num++; // !next particle-part
		}
		
		anim_loop=0;
		animation_part++;
	}
	
	// draw and animate horizontal lines
	else if (animation_part==2)
	{
	

		// alert(myco_num);
		for (var zi = 0; zi < myco_num; zi++) // number of horizontal block lines
		{
		
			var x1= myco_x1[zi]<<0;
			var y1= myco_y1[zi]<<0;
			var x2= myco_x2[zi]<<0;
			var y2= myco_y2[zi]<<0;
			
			if(x1<0){x1=0;} // check out of bounds!
			if(y1<0){y1=0;}
			if(x2<0){x2=0;}
			if(y2<0){y2=0;}

			if(x1>im_w){x1=im_w;}
			if(y1>im_h){y1=im_h;}
			if(x2>im_w){x2=im_w;}
			if(y2>im_h){y2=im_h;}
			
			var r= myco_r1[zi];
			var g= myco_g1[zi];
			var b= myco_b1[zi];
			
			if(my_random_int(29999)==0)  //  new random palette!
			{
				init_my_palette(); // reset palette
				
				for (var zii = 0; zii < myco_num; zii++) // reset all colors
				{
					var col= my_random_int(pallet_num); 		
					myco_r1[zii]=pallet_r[col];
					myco_g1[zii]=pallet_g[col];
					myco_b1[zii]=pallet_b[col];
				}
			}
			
			var istep= myco_istep[zi] ;// do extra step on x or y
			var jstep= myco_jstep[zi] ;
	
			var num=myco_fade[zi] ;
			var deel=num+1;

			var mode2=myco_mode2[zi]; 	
			if(mode2==0)	// blend		
			{
				for (var j = y1; j < y2; j=j+jstep) // y
				{
					var p1=j*im_w;
					for (var i = x1; i <  x2; i=i+istep) // x
					{
					
						var p2=p1+i; // pixel position!					
						pix_r[p2]= (r + (pix_r[p2]*num))/deel <<0;
						pix_g[p2]= (g + (pix_g[p2]*num))/deel <<0;
						pix_b[p2]= (b + (pix_b[p2]*num))/deel <<0;
					}	
				}		
			}
			else if(mode2==1)	// draw - darken		
			{
				for (var j = y1; j < y2; j=j+jstep) // y
				{
					var p1=j*im_w;
					for (var i = x1; i <  x2; i=i+istep) // x
					{
						var p2=p1+i; // pixel position!					
						pix_r[p2]--;
						pix_g[p2]--;
						pix_b[p2]--;
					}	
				}		
			}

			// new movement
			if(myco_direction[zi]==0)			
			{
			
				myco_y1[zi]+=myco_yspeed[zi];
				myco_y2[zi]+=myco_yspeed[zi];
				
				if(myco_y1[zi]>im_h+150) // check out of screen - reset block
				{
				
					myco_y1[myco_num] = im_h + my_random_int(2);			 
					myco_y2[myco_num] = myco_y1[myco_num]+1  + my_random_int(31);
						
					myco_direction[zi]=1;
					
					myco_yspeed[zi] = 0.1 + my_random_dub(1.1);
					myco_fade[zi]= 1 + my_random_int(31);
					
					var col= my_random_int(pallet_num); 
					myco_r1[zi] = pallet_r[col];
					myco_g1[zi] = pallet_g[col];
					myco_b1[zi] = pallet_b[col];
					
					myco_istep[zi] = 1;
					myco_jstep[zi] = 1;
					if(my_random_int(7)==0)
					{
						myco_istep[zi] = 1  + my_random_int(7);
						myco_jstep[zi] = 1  + my_random_int(7);
					}		
					myco_mode2[zi]=   my_random_int(2);					
				}
			}
			else if(myco_direction[zi]==1)			
			{
				myco_y1[zi]-=myco_yspeed[zi];
				myco_y2[zi]-=myco_yspeed[zi];
				
				if(myco_y2[zi]< -150) //check out of screen - reset block
				{
					myco_y1[myco_num] =0 - my_random_int(31);			 
					myco_y2[myco_num] = 0;


					myco_direction[zi]=0;
					
					myco_yspeed[zi] = 0.1 + my_random_dub(1.1);
					myco_fade[zi]= 1 + my_random_int(31);

					var col= my_random_int(pallet_num); 
					myco_r1[zi] = pallet_r[col];
					myco_g1[zi] = pallet_g[col];
					myco_b1[zi] = pallet_b[col];
					
					myco_istep[zi] = 1;
					myco_jstep[zi] = 1;
					
					if(my_random_int(7)==0)
					{
						myco_istep[zi] = 1  + my_random_int(7);
						myco_jstep[zi] = 1  + my_random_int(7);
					}	
					myco_mode2[zi]=   my_random_int(2);		
				}
			}

		
		}
		
		anim_loop++;
		if(anim_loop==100 && do_once==0) // do fxpreview after 100 drawings
		{
			fxpreview(); // now make the fxhash thumbnail - preview image
			do_once=1; // and do this only at the start
		}
		 
 
	}

	// ------------------- end of animation 

}


// javascript end
</script>
</head>

<body>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">-__-</canvas>

</body>
</html>

So what's in it?

a slightly different version you can check here: https://www.fxhash.xyz/generative/24719



comtemplate v.01

!!! Note: These examples use an older fxhash-snippet! Always use the latest one, when you want to test and upload it on fxhash !!!

<!doctype html>
<html>
<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

<title>0__.</title>

<!--a favicon 16x16 .png -  created at www.base64-image.de -->
<link rel="icon" type="image/png" sizes="16x16" href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH5wILEDkP6ElmoAAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAfUlEQVQ4y52SwQ2AIAxFf12IGRyhiRu5DgkjsIJOohvgxUND+Nj6TxB4r4EWIMlAy0DDR4TBdr+Re0MBq8ok4oFnEvHCTCIReCSRKNxLFvxMUr1+P2FXvd/lEf5EC4fb2MNnKat7kEawe5QZTAVWMoOnAtsqBnv7XZNqZecPngE+Zg1jiGkAAAAASUVORK5CYII=" />


 <!-- css stylesheet -->
<style type="text/css">
body
{
	background-color: #111;	margin:	0;padding: 0; 	
}

.css_background /*for color fader*/
{
	background-color: rgb(0, 0, 0);
	top: 0px;left: 0px;  width:100%; height:100%;
	z-index:11; border-width:0px; position: fixed;
}

.info_css
{
	color: rgb(220, 220, 220); 
	font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px;
	background-color: rgb(100, 100, 120); z-index:21;
	position: fixed; top:0px;left:0px; border-style:none; border-width:4px;
	margin:0px 0px 0px 0px; padding:2px 2px 2px 2px;
}

.canvas_css
{
	z-index:20; position: absolute;
	border-style:solid; border-width:0px; margin:0px 0px 0px 0px; padding:0px 0px 0px 0px;
	
	/*- no pixel blurring by the browser!! - old legacy code from the internet */
	image-rendering:optimizeSpeed;             /* Legal fallback */ 
	image-rendering:-moz-crisp-edges;          /* Firefox        */ 
	image-rendering:-o-crisp-edges;            /* Opera          */ 
	image-rendering:-webkit-optimize-contrast; /* Safari  		 */ 
	image-rendering:optimize-contrast;         /* CSS3 Proposed  */ 
	image-rendering:crisp-edges;               /* CSS4 Proposed  */ 
	image-rendering:pixelated;                 /* CSS4 Proposed  * 
	-ms-interpolation-mode:nearest-neighbor;   /* IE8+           */
}
</style>

<script id="fxhash-snippet">
  //-- do not edit the following code (you can indent as you wish) fxpreview -> canvas#my_canvas
  let alphabet = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"
  var fxhash = "oo" + Array(49).fill(0).map(_=>alphabet[(Math.random()*alphabet.length)|0]).join('')
  let b58dec = str=>[...str].reduce((p,c)=>p*alphabet.length+alphabet.indexOf(c)|0, 0)
  let fxhashTrunc = fxhash.slice(2)
  let regex = new RegExp(".{" + ((fxhashTrunc.length/4)|0) + "}", 'g')
  let hashes = fxhashTrunc.match(regex).map(h => b58dec(h))
  let sfc32 = (a, b, c, d) => {
    return () => {
      a |= 0; b |= 0; c |= 0; d |= 0
      var t = (a + b | 0) + d | 0
      d = d + 1 | 0
      a = b ^ b >>> 9
      b = c + (c << 3) | 0
      c = c << 21 | c >>> 11
      c = c + t | 0
      return (t >>> 0) / 4294967296
    }
  }
  var fxrand = sfc32(...hashes)
  // true if preview mode active, false otherwise
  // you can append preview=1 to the URL to simulate preview active
  var isFxpreview = new URLSearchParams(window.location.search).get('preview') === "1"
  // call this method to trigger the preview
  function fxpreview() {
    console.log("fxhash: TRIGGER PREVIEW")
  }
  //--do not edit the following code ^____^
</script>


<script type="text/javascript">  //my javascript start

// using some global variables now! I  use all the time now! and I can tune
// !!!you can change this when starting something new!!!

var cversion="comtemplate_v01"; // title of the page, also name of save file!

var show_fps = false;  // fps counter and info: put this on-true wen testing! also f-key
		
var random_palette =   true; // false; // - 3 random palette  colors?
var random_palette_grey =  false; // also add some grey to our palette
	
// css - use now a crosshair when your mouse is over the image
var my_crosshair="crosshair"; // none / default  / crosshair / 
	
//- my image / canvas / animation screen-pixel size now-
var im_w = 4096;  // image - canvas width !!!!
var im_h = 4096;  // image - canvas height!!!!
 
var aspi = my_random_int(3); //random aspect ratio!
if(aspi==0)
{
	im_h=5120;
	im_w=5120;
}
else if(aspi==1)
{
	im_w=4096;
	im_h=6144;
}
else if(aspi==2)
{
	im_w=6144;
	im_h=4096;
}
 



//-------------------tech: setting up screen--------------------	
// gets current browser window size
var win_w=window.innerWidth;
var win_h=window.innerHeight;
			  
// for my palette
var pallet_num=0;
var pallet_r = new Array();
var pallet_g = new Array();
var pallet_b = new Array();
var palette_name;

//globals for css bacrgroundchange
var css_bgchange =  false;
var css_bgchange_count = 0;
var css_bgchange_rgb = new Array();

// rgb pixel buffer  
var pix_r = new Uint8ClampedArray(im_w*im_h);
var pix_g = new Uint8ClampedArray(im_w*im_h);
var pix_b = new Uint8ClampedArray(im_w*im_h);

var pix_z = new Array(); // depth - z 

// screen rendering!
var show_buff=1;

// screen scaled image
var pix_screen_r = new Uint8ClampedArray(); 
var pix_screen_g = new Uint8ClampedArray(); 
var pix_screen_b = new Uint8ClampedArray();

var pix_screen_w = 0;
var pix_screen_h = 0;
var pix_screen_top=0;
var pix_screen_left=0;

var pix_screen_hor=false;
var pix_screen_ver=false;

var render_complete=false;

// highres to low screen rendering
var x_step = new Array();
var y_step = new Array();
var renderstepper=0;
var yline_pos=0;
 
var c_timesrendered=0;

 // mouse
 var mx, my; // mouse x and y position
 
// globals animation
var animation_part=0;
var anim_loop=0;
var do_once=0; // for fxpreview

var global_anim_frame=0;

var my_pause=false; // pause anim
var save_image=false;

	
// legacy code = technical code-snippets from tutorials found on the internet once 
// do not know the orginal author!
// mostly for the legacy code I kept variable names the same
// incase you find org. author:  apple-pie for both!

//----------- show fps------------some legacy code
var my_timer=setInterval(function(){timer_fps()},1000);//1000
var data_fps=0;
var counter_fps=0;
var timeCurrent, timeLast = Date.now();	
var test=""; // for testing  !! gets used in fps-counter!


// pre-calculated y-table-  y*image_width  
var ytable_im_w = new Array(im_h);

// a pre-calculated random buffer   
var	rnd_bufsize=1000;
var	rnd_buf = new Array();
var	rnd_pos=0;
var	rnd_step=1;

// pre-calculated sin cos buffer
var sincos=4096; // make this bigger; if you want bigger circle data
var my_cos=new Array();  
var my_sin=new Array(); 

//----------- window events --- 

// sets the animation at 60 fps - -legacy code
if ( !window.requestAnimationFrame ) 
{
	window.requestAnimationFrame = ( function() {
		return window.webkitRequestAnimationFrame ||
		window.mozRequestAnimationFrame ||
		window.oRequestAnimationFrame ||
		window.msRequestAnimationFrame ||
		function(callback, element ) {window.setTimeout( callback, 1000 / 60 );};
	} )();
}

// wen the page is loaded, jump here! - tech -
window.addEventListener('load',init_mywindow, false ); 

// page  init here!  - tech -
function init_mywindow() 
{
	document.title =cversion;// set html page title
	
	document.getElementById('my_canvas').style.cursor=my_crosshair; //crosshair; // none

	// precalculated: y table for (y * image_width) 
	for (var j= 0; j< im_h; j++){  ytable_im_w[j] = (j*im_w);}	
	
	//sets mouse mx and mouse my to middle of screen
	mx = im_w/2;
	my = im_h/2;
	
	//for the css background color fader
	for (var j= 0; j<6; j++){   css_bgchange_rgb[j]=0;}	
	
	// hide info-fps text block when showfps is  false
	if(show_fps==false){document.getElementById('infoblock').style.visibility = "hidden";}
	else {document.getElementById('infoblock').style.visibility = "visible";}
		
	// ------------tech next: keys, mouse and windows handling --------------------
	document.addEventListener('keyup', function(event)
	{
		// saving is now handled in the draw() function!
		if (event.code == 'KeyS') // s key save 
		{  
			save_image=true;
		}
		if (event.code == 'Space') // spacebar  pause 
		{  
			if(my_pause==false){my_pause=true;}else {my_pause=false;}
		}	
		if (event.code == 'KeyF') // f-key show hide fps
		{  
			if(show_fps==false){show_fps=true;}else {show_fps=false;}
			if(show_fps==false){document.getElementById('infoblock').style.visibility = "hidden";}
			else {document.getElementById('infoblock').style.visibility = "visible";}
		}
		if (event.code == 'KeyP') // random palette? // palette gets set at start animation-drawing
		{  
			if(random_palette==false){random_palette=true;}else {random_palette=false;}
		}
	}); 	
	
	//---mouse check and input
	var c=document.getElementById('my_canvas');	
	c.addEventListener("mousemove", function (evt) 
	{
		if(show_buff==0) // big image with scrollbars
		{
			xOffset=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft);
			yOffset=Math.max(document.documentElement.scrollTop,document.body.scrollTop);
			mx= Math.round((evt.clientX +xOffset ));	
			my= Math.round((evt.clientY +yOffset ));	
		}
		else if(show_buff==1) // screen scaled image
		{
			mx=Math.round( (im_w/pix_screen_w) * (evt.clientX - pix_screen_left) );
			my=Math.round( (im_h/pix_screen_h) * (evt.clientY - pix_screen_top)  );
		}
		else if(show_buff==2) // mouse zoom
		{
			mx= Math.round((evt.clientX));// could use better calculation, now just window mouse position
			my= Math.round((evt.clientY));	
		}
		//test="mouse - mx: "+mx+"   my: "+my;	
	}, false);
	
	c.addEventListener("mouseup", function (evt) 
	{	
		//show the screen scaled image or zoomed in
		show_buff++;
		if(show_buff>2){show_buff=1;}
		
		if(show_buff==0) // big image with scrollbars
		{
			xOffset=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft);
			yOffset=Math.max(document.documentElement.scrollTop,document.body.scrollTop);
			mx= Math.round((evt.clientX +xOffset ));	
			my= Math.round((evt.clientY +yOffset ));	
		}
		else if(show_buff==1) // screen scaled image
		{
			mx=Math.round( (im_w/pix_screen_w) * (evt.clientX - pix_screen_left) );
			my=Math.round( (im_h/pix_screen_h) * (evt.clientY - pix_screen_top)  );
		}
		else if(show_buff==2) // mouse zoom
		{
			mx= Math.round((evt.clientX));	
			my= Math.round((evt.clientY));	
		}
	}, false);
	
	c.addEventListener("mousedown", function (evt) 
	{
		// mouse_pressed=true;
	}, false);
	
	// touch event .. phone etc finger movement 'mouse position'
	c.addEventListener("touchmove", function (evt)   // 'touchstart' 'touchmove' 'touchend'
	{
		var touch = evt.touches[0] || evt.changedTouches[0];
		
		var tx = touch.pageX;
		var ty = touch.pageY;
		
		if(tx>0 && ty>0)  // check if there screen is touched.. if not tx/ty is undefined
		{
			if(show_buff==0) // big image with scrollbars
			{
				xOffset=Math.max(document.documentElement.scrollLeft,document.body.scrollLeft);
				yOffset=Math.max(document.documentElement.scrollTop,document.body.scrollTop);
				mx= Math.round((tx +xOffset ));	
				my= Math.round((ty +yOffset ));
			}
			else if(show_buff==1) // screen scaled image
			{
				mx=Math.round( (im_w/pix_screen_w) * (tx - pix_screen_left) );
				my=Math.round( (im_h/pix_screen_h) * (ty - pix_screen_top)  );
			}
			else if(show_buff==2) // mouse zoom
			{
				mx= Math.round(tx);	
				my= Math.round(ty);	
			}	
			// anim			
		}
		evt.preventDefault();// disable unwanted page scrolling; if you touch/swipe
	},{ passive: false },  false);  // found passive:false fixes a scroll bug now
	 
	//---------------------------windows check on resize
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	// window resize? do this.  
	window.addEventListener( 'resize', onWindowResize, false );

	windows_reset_screenimage();

	animate(); // !!!____Init__ and trigger-start the animation
} 

//---window stuff
function onWindowResize() 
{
	windows_reset_screenimage();	
}

// do when resize window!
function windows_reset_screenimage()
{
	win_w=window.innerWidth;
	win_h=window.innerHeight;
	
	renderstepper=0; // refresh the render lines
	css_bgchange=true;

	//center screen image based on aspect-ratio 
	var img_ratio=im_w/im_h;
	var win_ratio=win_w/win_h;

	//center screen image based on aspect-ratio 
	var newratio=0;	
	pix_screen_w=win_w;
	newratio= (win_w/im_w);
	pix_screen_h = (im_h * newratio)<<0;			
	if (pix_screen_h > win_h)
	{
		pix_screen_h = win_h;
		newratio=(win_h/im_h);
		pix_screen_top=0;
		pix_screen_w=(im_w * newratio)<<0;
		pix_screen_left=((win_w - pix_screen_w)/2) <<0;
		pix_screen_hor=false;
		pix_screen_ver=true;
	}
	else
	{
		pix_screen_left=0;
		pix_screen_top=((win_h - pix_screen_h)/2) <<0;
		pix_screen_hor=true;
		pix_screen_ver=false;
	}
	
	pix_screen_r = new Uint8ClampedArray(pix_screen_w*pix_screen_h); 
	pix_screen_g = new Uint8ClampedArray(pix_screen_w*pix_screen_h); 
	pix_screen_b = new Uint8ClampedArray(pix_screen_w*pix_screen_h);
}

// html - set text; and dump the html/text in a div
function set_msg(div, msg){document.getElementById(div).innerHTML = msg;}
function go_msg(div, msg) {document.getElementById(div).innerHTML += msg;} // add text

// legacy code from the internet - quick and dirty fps counter!
function timer_fps() // dirty fps counter 
{
	timeCurrent = Date.now();
	if (show_fps==true)
	{
		var fpsThisFrame = 1000 / (timeCurrent - timeLast);
		if(timeCurrent > timeLast) 
		{
			set_msg('infoblock', 'fps:' + counter_fps+test);
			timeLast = timeCurrent;
			counter_fps=0;
		}
	}	
}
	
//-------------------------------------------------------------------------------
function animate() 
{
	requestAnimationFrame( animate );
	if (show_fps==true){counter_fps++;}
	draw();
}

// the animation-drawing set at 60fps frames per second atm
function draw()
{
	if(my_pause==false) // check if the animation is not paused with spacebar
	{
		my_animation(); //  draw!		
	}
	
	// calculate smoothed scaled image; in little steps
	toscreen_render();

	//the backround css color fader
	if(css_bgchange==true){css_background_change(200);} // fade in 200 steps

	if(show_buff==0)
	//render the big image (with scollbars) 
	//not really used at the moment- moved it: at save the big image
	{
		var c=document.getElementById('my_canvas');
		var ctx=c.getContext("2d");
		c.width = im_w; 
		c.height = im_h;
		document.getElementById('my_canvas').style.left='0px';
		document.getElementById('my_canvas').style.top='0px';
		//update image buffer - screen
		var img1 = ctx.createImageData(im_w, im_h); //var
		for (var p=0, j = 0; j < im_h*im_w; j++)
		{				
			img1.data[p++] = pix_r[j];	// r
			img1.data[p++] = pix_g[j];	// g
			img1.data[p++] = pix_b[j];	// b
			img1.data[p++] = 255;		// alpha
		}	
		ctx.putImageData(img1, 0, 0);	
	}
	
	// -------------render to screen - screen scaled image-------------------
	else if(show_buff==1)
	{
		var c=document.getElementById('my_canvas');
		var ctx=c.getContext("2d");
		c.width = pix_screen_w; 
		c.height = pix_screen_h;
		
		document.getElementById('my_canvas').style.left=pix_screen_left+'px';
		document.getElementById('my_canvas').style.top=pix_screen_top+'px';
		
		//update image buffer
		var img1 = ctx.createImageData(pix_screen_w, pix_screen_h); //var
		for (var p=0, j = 0; j < pix_screen_w*pix_screen_h; j++)
		{		
			img1.data[p++] =  pix_screen_r[j]; // red
			img1.data[p++] =  pix_screen_g[j]; // green
			img1.data[p++] =  pix_screen_b[j]; // blue
			img1.data[p++] =  255; // alpha not used atm
		}
		ctx.putImageData(img1, 0, 0);
	}
	
	//----------------mouse zoomed image!----------------
	else if(show_buff==2)
	{	
		var c=document.getElementById('my_canvas');
		var ctx=c.getContext("2d");
		c.width = win_w; 
		c.height = win_h;
		document.getElementById('my_canvas').style.left='0px';
		document.getElementById('my_canvas').style.top='0px';	
		
		// -200 make it smaller so you have a noscroll zone around borders
		var tratiox=(im_w-win_w)/(win_w-200);
		var tratioy=(im_h-win_h)/(win_h-200);
		var scrollx=((mx-100)*tratiox)<<0;
		var scrolly=((my-100)*tratioy)<<0;
		if(scrollx<0){scrollx=0;}
		if(scrolly<0){scrolly=0;}
		if(scrollx>im_w-win_w){scrollx=im_w-win_w;}
		if(scrolly>im_h-win_h){scrolly=im_h-win_h;}
	
		//update image buffer - screen
		var img1 = ctx.createImageData(win_w,win_h);
		
		if(im_w<win_w || im_h<win_h)// --my drawing-image is smaller then the screensize
		{
			var starw=win_w;
			var starh=win_h;
			var starx=0;
			var stary=0;
			
			if (im_w<win_w)
			{
				starx=((win_w-im_w)/2)<<0;
				starw=(im_w+starx)<<0;
				scrollx = -starx;
			}
			if (im_h<win_h)
			{
				stary=((win_h-im_h)/2)<<0;
				starh=(im_h+stary)<<0;
				scrolly	= -stary;
			}
			
			for (var p=0,j = stary; j < starh; j++)
			{				
					for (var i = starx; i < starw; i++)
					{	
						var p2=((j+scrolly)*im_w)+(i+scrollx);	//  scrolly	= -stary;				
						var p1=((j*4)*win_w)+((i)*4);					
						img1.data[p1] 	= pix_r[p2];	// r
						img1.data[p1+1] = pix_g[p2];	// g
						img1.data[p1+2] =  pix_b[p2];	// b
						img1.data[p1+3] = 255;		// alpha not used atm
					}
			}
			ctx.putImageData(img1, 0, 0);	
		}
		else // --my drawing-image is larger then the screen--
		{
			for (var p=0,j = 0; j < win_h; j++)
			{				
				for (var i = 0; i < win_w; i++)
				{	
					var p2=((j+scrolly)*im_w)+(i+scrollx);				
					img1.data[p++] = pix_r[p2];		// r
					img1.data[p++] = pix_g[p2];		// g
					img1.data[p++] =  pix_b[p2];	// b
					img1.data[p++] = 255;			// alpha not used atm
				}
			}		
			ctx.putImageData(img1, 0, 0);	
		}
		
	}

	// save part some legacy code
	if (save_image==true && render_complete==true) // save image 
	{	
		// first draw the image 'big'
		var c=document.getElementById('my_canvas');
		var ctx=c.getContext("2d");
		c.width = im_w; 
		c.height = im_h;
		document.getElementById('my_canvas').style.left='0px';
		document.getElementById('my_canvas').style.top='0px';			
		
		var img1 = ctx.createImageData(im_w, im_h); //var
		for (var p=0, j = 0; j < im_h*im_w; j++)
		{				
			img1.data[p++] = pix_r[j];	// r
			img1.data[p++] = pix_g[j];	// g
			img1.data[p++] = pix_b[j];	// b
			img1.data[p++] = 255;		// alpha
		}	
		ctx.putImageData(img1, 0, 0);
		// then save the image!
		var imagename= cversion+'_'+fxhash+'_'+'.png'; // I also save the fxhashkey!
		var my_download = document.createElement('a');
		my_download.setAttribute('download', imagename);			
		var mcanvas = document.getElementById('my_canvas');
		mcanvas.toBlob(function(blob) {
						var url = URL.createObjectURL(blob);
						my_download.setAttribute('href', url);
						my_download.click();	
						}); 						
		save_image=false;
	}
	
}

//------------- css tricks -----------------------
// change - fade background-color of my css backdrop 
function css_background_change(steps)
{
	var r1,g1,b1;		
	if(css_bgchange_count<steps)
	{
		var cstep1=steps-css_bgchange_count;
		var cstep2=steps-cstep1;
		r1 = (((css_bgchange_rgb[3] *cstep1) +  (css_bgchange_rgb[0]*cstep2))/steps)<<0;
		g1 = (((css_bgchange_rgb[4] *cstep1) +  (css_bgchange_rgb[1]*cstep2))/steps)<<0;
		b1 = (((css_bgchange_rgb[5] *cstep1) +  (css_bgchange_rgb[2]*cstep2))/steps)<<0;		
		css_bgchange_count++;
	}
	else //done fading
	{
		r1= css_bgchange_rgb[0];
		g1= css_bgchange_rgb[1];
		b1= css_bgchange_rgb[2];
		css_bgchange_rgb[3] = r1;	 
		css_bgchange_rgb[4] = g1; 	
		css_bgchange_rgb[5] = b1;
		css_bgchange=false;
	}
	
	// make the borders a bit darker!
	var r3 = (r1/7)<<0; var g3 = (g1/7)<<0; var b3 = (b1/7)<<0; 
		
	var fadedirection='to top';
	if(pix_screen_ver==true){fadedirection='to right';}
		
	document.getElementById('backgroundblock').style.backgroundImage = 
		'linear-gradient('+fadedirection+', rgb('+r3+','+g3+','+b3+'), rgb('+r1+','+g1+','+b1+'),rgb('+r3+','+g3+','+b3+') )'; 
	//radial-gradient 
	
}

function toscreen_render()
{	
	if(renderstepper==0)
	{
		var stepr_x =(im_w / pix_screen_w);  
		var stepr_y =(im_h / pix_screen_h);
	
		//sampling org texture
		x_step = new Array(pix_screen_w*pix_screen_h);
		y_step = new Array(pix_screen_w*pix_screen_h);
			
		for (var j = 0; j < pix_screen_h; j++)  
		{
			for (var i = 0; i <pix_screen_w; i++) 
			{
				var p1=(j*pix_screen_w)+i;
				var ii =(i*stepr_x)<<0;
				var ii2=((i+1)*stepr_x)<<0;
				var jj=(j*stepr_y)<<0;
				var jj2=((j+1)*stepr_y)<<0;
				x_step[p1] = ii2-ii;
				y_step[p1] = jj2-jj;	
			}
		}
		renderstepper=1;
	}	
	if(renderstepper==1)
	{	
		render_complete=false;	
		
		var stepr_x =(im_w/pix_screen_w);
		var stepr_y =(im_h/pix_screen_h);
			
		var newy=yline_pos + 32; // render parts: now in steps of 32 !! you can change this faster-slower!
		var lastlines=false;
		if( newy > pix_screen_h-1)
		{
			newy = pix_screen_h;
			lastlines=true;
		}			
		for (var j = yline_pos; j < newy; j++) // 
		{
			for (var i = 0; i < pix_screen_w; i++) 
			{
					var p0=(j*pix_screen_w)+i; // step buff							
					var ii=(i*stepr_x)<<0;
					var jj=(j*stepr_y)<<0;
					var p2=(jj*im_w)+ii;
				
					var r1=pix_r[p2];
					var g1=pix_g[p2];
					var b1=pix_b[p2];
					var dc=1;

					for (var cj = 0; cj < (y_step[p0]); cj++) 
					{				
						for (var ci = 0; ci < (x_step[p0]); ci++) 
						{
							var tpos=(p2+ci) +ytable_im_w[cj]; 
							r1 += pix_r[tpos];
							g1 += pix_g[tpos];
							b1 += pix_b[tpos];
							dc++;
						}
					}
					pix_screen_r[p0]= (r1/dc)<<0;
					pix_screen_g[p0]= (g1/dc)<<0;
					pix_screen_b[p0]= (b1/dc)<<0;
			}
		} 
		if(lastlines==true)	
		{
			render_complete=true; // for save check!
			yline_pos=0;
			c_timesrendered++;
			//test='pages rendered: '+c_timesrendered
		}
		else{yline_pos=newy;}				
	}
}

// pre-calculated random noise buffer 0-255 int
function math_init_random_0_255(buf)
{	
	for (var i=0; i < rnd_bufsize; i++)
	{
		buf[i]=(fxrand()*256)<<0;
	}
}
// get the random number from my buffer
function math_get_random_0_255()
{
  rnd_pos=rnd_pos+rnd_step;
  if (rnd_pos>=rnd_bufsize)
  {
    rnd_step=((fxrand()*20)<<0)+1; // shuffle  the step and starting position
    rnd_pos=(fxrand()*20)<<0;
  }
  return (rnd_buf[rnd_pos]); // returns a random color between 0 and 255
}

// set up a cos/sin buffer (circles waves etc.)
function set_cossinbuffer(nsize,mcos,msin)
{
	for(var i=0; i<nsize; i++) 
	{
		mcos[i]=( Math.cos ( i*360/nsize * Math.PI / 180)); // note: this can change in time !!
		msin[i]=( Math.sin ( i*360/nsize * Math.PI / 180)); // depending on browser - cpu
	}
}

//clear array-screen with a value
function fill_array(buf,size,value)
{	
	for (var i=0; i < size; i++)
	{
		buf[i]=value;
	}
}

 //--- my random using fxrand()------------
function my_random_int(nummer){return ( ((fxrand()*nummer) << 0) );} //int 

function my_random_dub(nummer){return ( fxrand()*nummer );} //float

function my_random_int_minplus(nummer){return  (  ( (fxrand() * (nummer*2)) - nummer) << 0 );} 
//returns int:  between -num +num
function my_random_dub_minplus(nummer){return  ( (fxrand() * (nummer*2)) - nummer)  ;} 
//returns float:  between -num +num

//---------------------------end tech--------------------

// !-------------- --- next the creative part -----------!

// --- palette.js----
function init_my_palette()
{
	// you can store and collect your favourite palette's here
	var palet_data=[
	"red 'n grey", 220,10,10,   125,10,10,  200,200,200, //
	"green orange cyanish", 124,225,245,   219,127,59,    112,175,145,
	"orange-greenish", 245,97,56,   162,183,157,    72,195,57,
	
	"yellow cyanish",255, 255, 0,   0,  255,255,   200,200,200 ]; //  // last one without , !	
		
	var numpalettes=palet_data.length / 10; // how many palettes i got now?
	
	var randompalette=my_random_int(numpalettes)
	
	var whatpalette = randompalette * 10; // rgb position
	
	
	// - put fps on to see the rgb numbers	
	test="<hr>-rgb-rgb-rgb-<hr>	"
	if (random_palette ==  false)
	{
		test+= "palette: " +palet_data[whatpalette+0];
		palette_name=palet_data[whatpalette+0];
	}
	else
	{
		test+= "random palette";
		palette_name="random palette";
	}
	test+="<hr>"
	
	palet_data[0]=palet_data[whatpalette+1]; // get colors from my palette
	palet_data[1]=palet_data[whatpalette+2];
	palet_data[2]=palet_data[whatpalette+3];
	
	palet_data[3]=palet_data[whatpalette+4];
	palet_data[4]=palet_data[whatpalette+5];
	palet_data[5]=palet_data[whatpalette+6];
	
	palet_data[6]=palet_data[whatpalette+7];
	palet_data[7]=palet_data[whatpalette+8];
	palet_data[8]=palet_data[whatpalette+9];
	
	if(random_palette==true)
	{
		palet_data[0]=55+my_random_int(200); // 3 random rgb colors
		palet_data[1]=55+my_random_int(200);
		palet_data[2]=55+my_random_int(200);
	
		palet_data[3]=55+my_random_int(200);
		palet_data[4]=55+my_random_int(200);
		palet_data[5]=55+my_random_int(200);
	
		palet_data[6]=55+my_random_int(200);
		palet_data[7]=55+my_random_int(200);
		palet_data[8]=55+my_random_int(200);	
	}	
	
	// outputs rgb - text to the fps-info // you can either use " or ' 
	test+="<b><span style='color:rgb("+palet_data[0]+","+palet_data[1]+","+palet_data[2]+");'>"+palet_data[0]+","+palet_data[1]+","+palet_data[2]+","+"</span>&nbsp;&nbsp;&nbsp;<span style='color:rgb("+palet_data[3]+","+palet_data[4]+","+palet_data[5]+");'>"+palet_data[3]+","+palet_data[4]+","+palet_data[5]+", "+"</span>&nbsp;&nbsp;&nbsp;<span style='color:rgb("+palet_data[6]+","+palet_data[7]+","+palet_data[8]+");'>"+palet_data[6]+","+palet_data[7]+","+palet_data[8]+","+"</span></b><hr><hr>";

	// !!!! you can change and fine-tune the shades of your palette here. like number and steps to darker
	var numplay=32; // for every palette rgb, make 32 shades 
	var darkstep=7; // shades to darker step
	
	pallet_num=0;	// start with 0 colors
	for (var i = 0; i <  numplay; i++) //6 fade to dark   palette rgb 1
	{
		pallet_r[pallet_num]= palet_data[0] - (i*darkstep);
		pallet_g[pallet_num]= palet_data[1] - (i*darkstep);
		pallet_b[pallet_num]= palet_data[2] - (i*darkstep);
		pallet_num++; // add this color to the palette buffer
	}
	for (var i = 0; i <  numplay; i++) // fade to dark    palette rgb 2
	{
		pallet_r[pallet_num]= palet_data[3] - (i*darkstep)<<0;
		pallet_g[pallet_num]= palet_data[4] - (i*darkstep)<<0;
		pallet_b[pallet_num]= palet_data[5] - (i*darkstep)<<0;
		pallet_num++;
	}
	for (var i = 0; i <  numplay; i++) // fade to dark    palette rgb 3
	{
		pallet_r[pallet_num]= palet_data[6] - (i*darkstep)<<0;
		pallet_g[pallet_num]= palet_data[7] - (i*darkstep)<<0;
		pallet_b[pallet_num]= palet_data[8] - (i*darkstep)<<0;
		pallet_num++;
	}
	if(random_palette_grey==true)
	{
		for (var i = 0; i <  numplay; i++) // fade to dark  extra  palette grey 
		{
			pallet_r[pallet_num]= ((palet_data[0]+palet_data[1]+palet_data[2])/3) - (i*7) <<0;
			pallet_g[pallet_num]= pallet_r[pallet_num];
			pallet_b[pallet_num]= pallet_r[pallet_num];
			pallet_num++;
		} 	
	}
	
	// little error check else funky -colors!
	for (var i = 0; i <  pallet_num; i++)
	{
		if(pallet_r[i]<0){pallet_r[i]=0;}
		if(pallet_g[i]<0){pallet_g[i]=0;}
		if(pallet_b[i]<0){pallet_b[i]=0;}
	}
	
	for (var i = 0; i <  pallet_num; i++)
	{
		test+="<span style='background-color:rgb("+pallet_r[i]+","+pallet_g[i]+","+pallet_b[i]+");>&nbsp;</span>"
	}
	test+="<hr>";

}

//----------------------------  xxx.js 
// !now the drawing starts!
function my_animation()
{
	global_anim_frame++; // global frame counter  

	if (animation_part==0) // start init animation!
	{
		// create a new (random) palette
		init_my_palette();
		
		//clear screen!	
		var col= my_random_int(pallet_num); 
		var r1=pallet_r[col];
		var g1=pallet_g[col];
		var b1=pallet_b[col];
		fill_array(pix_r,im_w*im_h,r1);
		fill_array(pix_g,im_w*im_h,g1);
		fill_array(pix_b,im_w*im_h,b1);
		
		//change the css_background - color fader
		css_bgchange=true;  css_bgchange_count=0;
		css_bgchange_rgb[0] = r1; css_bgchange_rgb[1] = g1; css_bgchange_rgb[2] = b1;
		
		animation_part=1; // and go next!		 
	}
	
	// init -- draw random lines
	else if (animation_part==1)
	{	
		anim_loop=0;
		animation_part++; // go next
	}
		
	// draw random lines
	else if (animation_part==2)
	{	
		var col= my_random_int(pallet_num); // get a random color from my palette
		var r = pallet_r[col];
		var g = pallet_g[col];
		var b = pallet_b[col];
		
		var x1= my_random_int(im_w);//get random x and y
		var y1= my_random_int(im_h); 

		for (var i = 0; i < 20000; i++) //draw a line of 20000 points 
		{
			var pos= (y1*im_w)+ x1 ; // pixel position
			if(pos>-1 && pos<im_w*im_h) // never draw outside your pixel buffer!
			{				
				pix_r[pos]= r; // draw pixel
				pix_g[pos]= g;
				pix_b[pos]= b;
		
				x1+= my_random_int(2); // new random position
				y1+= my_random_int(2);
		 
				if(x1>im_w-1){x1=im_w-x1;} // out of bounds - screen check 
				if(y1>im_h-1){y1=im_h-y1;} // check image width and height
				if(x1<0){x1=im_w+x1;}
				if(y1<0){y1=im_h+y1;}
			}
			else {alert('out of bounds - never draw outside the buffer - memory!');}	
		}	

		anim_loop++;
		if(anim_loop>700) // draw 700 lines then jump to end
		{
			anim_loop=0; // reset loop again
			animation_part=100; // jump to end
		}
		
	}// end animation_part 2
	
	// end of animation - do fxpreview - and wait a bit
	else if (animation_part==100)
	{
		// do fxpreview after x drawings
		if( anim_loop > 200 && render_complete==true && do_once==0) 
		{
		
			if (random_palette ==  false)
			{
				window.$fxhashFeatures = 
				{
					"palette":  palette_name
				}
			}
			fxpreview(); // now make the fxhash thumbnail - preview image
			do_once=1; // and do this only 1 time!
		}
	
		anim_loop++;
		if(anim_loop>700) // wait 700 times
		{
			anim_loop=0;
			animation_part=101; // then jump to end
		}
	}
	else if (animation_part==101)
	{
		animation_part=0; // reset; restart with a new image // or just wait here
	}
	
}	// ------------------- end of animation 

// javascript end
</script>
</head>

<body>

<div id="backgroundblock" class="css_background"></div>

<div class="info_css" id="infoblock">0__.</div>

<canvas class="canvas_css" id="my_canvas">-__-</canvas>

</body>
</html>

See also my recent fxhash release. See it working here: https://elout.home.xs4all.nl/drawz/comtemplate/comtemplate01/

!!! Note: These examples use an older fxhash-snippet! Always use the latest one, when you want to test and upload it on fxhash !!!

I open Developer tools in chrome (F12 on windows); check google how to open it; incase you are on a different platform. There you can save the file as well. I use the Developer tools as well, for bug-checking.

So what's in it? - It's drawing a big image of like 4096x4096 - scale it down to the screen

I want to concentrate on this template next, for creative coding; in a new article

stay ahead with our newsletter

receive news on exclusive drops, releases, product updates, and more

feedback