Spiralator 9000

Size
4,671 Kb
Views
6,072

How do I make an spiralator 9000?

My first toy using Google's dat-gui library. You can even save your settings on this toy - Share your presets in the comments!. What is a spiralator 9000? How do you make a spiralator 9000? This script and codes were developed by Admiral Potato on 10 December 2022, Saturday.

Spiralator 9000 Previews

Spiralator 9000 - Script Codes HTML Codes

<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Spiralator 9000</title> <link rel="stylesheet" href="css/style.css">
</head>
<body> <div id="buttonHolder"> <button id="save">Save</button>
</div>
<div id="fade"> <input type="text" id="short"><br><button id="close">Close</button>
</div> <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src='https://dat-gui.googlecode.com/git/build/dat.gui.min.js'></script>
<script src='https://admiralpotato.github.io/js/npos3d/build/npos3d.min.js'></script> <script src="js/index.js"></script>
</body>
</html>

Spiralator 9000 - Script Codes CSS Codes

*{ font-family: sans-serif;
}
#buttonHolder{ position: absolute; padding: 16px;
}
button{ display: inline-block; position: relative;	z-index: 2;	border: 1px solid #444;	background-color: #2b2b2b;	color: #999;	margin-right: 16px;	line-height: 32px;	padding: 0 8px;	border-radius: 4px; cursor: pointer;
}
button:hover{	color: #eee;	background-color: #333;	border: 1px solid #555;
}
#fade{ display: none;	position: absolute;	z-index: 2; top: 0; left: 0; color: #fff; height: 100%; width: 100%; text-align: center; background-color: rgba(0,0,0,0.8);
}
#short{ margin-top: 100px;
}
body .dg .property-name{	width: 30%;
}
body .dg .c{	width: 70%;
}
body .dg .slider{	width: 76%;
}
body .dg .has-slider input[type="text"]{	width: 20%;
}

Spiralator 9000 - Script Codes JS Codes

var n = NPos3d, m = n.Maths, s = new n.Scene();
var settings = { "pointsPerCircle":9, "circlesPerShape":120, "ripples":3, "rippleAmp":150, "offsetX":50, "offsetY":25, "scaleX":0.5, "rainbow":true, "hueMirror":false, "hueStart":0, "hueEnd":360, "hueRots":1, "hueAxies":"zy", "pointScale":4, "pointStyle":"fill", "lineWidth":1, "composite":"source-over", "autoRotate":true
};
var round = function(n, fac){ return Math.round(n * fac) / fac;
};
var normSin = function(r) { //normalized (0-1) sine return (cos(r) * 0.5) + 0.5;
};
var normCos = function(r) { //normalized (0-1) sine return (sin(r) * 0.5) + 0.5;
};
var hueAxies = {xy:[0,1],yx:[1,0],xz:[0,2],zx:[2,0],yz:[1,2],zy:[2,1]};
var Lathe = function(args){ var t = this, type = 'Lathe'; if(t.type !== type){	throw 'The ' + type + ' Constructor must be invoked prefixed with the `new` keyword.';	}	args = args || {};	t.args = args;	n.blessWith3DBase(t,args);	return t;
};
Lathe.prototype = {	type: 'Lathe',	renderStyle: 'points',	pointScale: settings.pointScale,	renderAlways: true,	shape: {	points: []	}, rotOrder: [0,1,2],	addCircle: function() {	var t = this, i, rot = t.rot.slice(), inverseLatheRot, mRotatedPoint, hue, degree, frac, rDegree, segment = 360 / settings.pointsPerCircle;	rangeDiff = settings.hueEnd - settings.hueStart;	for(i = 0; i < settings.pointsPerCircle; i += 1){	rot[1] += deg * segment;	inverseLatheRot = [tau - rot[0], tau - rot[1], tau - rot[2]];	mRotatedPoint = m.p3Rotate([pointer.x, pointer.y, 0], inverseLatheRot, t.rotOrder);	hue = Math.atan2(mRotatedPoint[hueAxies[settings.hueAxies][0]],mRotatedPoint[hueAxies[settings.hueAxies][1]]);	if(settings.rainbow){	//The rounding here is required because if the CSS hsl gets a really high precision `0`, things get wonky	if(settings.hueMirror){	degree = (normSin(hue * settings.hueRots) * rangeDiff) + settings.hueStart;	rDegree = round(degree, 100);	//derp();	} else {	degree = hue / deg;	}	rDegree = round(degree, 100);	mRotatedPoint[3] = 'hsl(' + rDegree +', 100%, 50%)';	}	//console.log( mRotatedPoint[3]);	t.shape.points.push(mRotatedPoint);	}	t.lastRotString = false; //even if the object if not rotating, triggers an update of the transformedPointCache	},	update: function(){	var t = this,settingsData, propertyName;	if(settings.autoRotate){ t.rot[1] += deg; t.rot[2] += deg * 0.5;	}	if(window.location.hash.length > 1){ //prolly a better way than this, but it's 5 AM, so brain failing settingsData = JSON.parse(decodeURIComponent(window.location.hash.slice(1))); for(propertyName in settingsData){ if(settingsData.hasOwnProperty(propertyName)){ settings[propertyName] = settingsData[propertyName]; } }	window.location.hash = '';	console.log(settings);	geomSettingsChangedHandler();	scaleSettingsChangedHandler();	renderPropertyChangeHandler();	}	}
};
var myLathe = new Lathe({scale:[settings.scaleX,1,1]});
s.add(myLathe);
s.update(); //so the lathe obtains a reference to the scene, as children are added at the end of each frame
var capturedRotation = [0,0,0];
var captureRotation = function(){	capturedRotation = myLathe.rot.slice();
};
var pointer = {x: 0, y: 0};
var populateShape = function(){	var i, angle = 360 / settings.circlesPerShape;	captureRotation();	myLathe.rot[0] = 0;	myLathe.rot[1] = 0;	for(i = 0; i < settings.circlesPerShape; i += 1){	pointer.x = (normCos(i * deg * angle * settings.ripples) * settings.rippleAmp) + settings.offsetX;	pointer.y = settings.offsetY;	myLathe.rot[0] += deg * angle;	myLathe.rot[1] += deg * angle;	myLathe.addCircle();	}	myLathe.rot = capturedRotation;
};
populateShape();
$(document.body).on('click', '#close', function(){$('#fade').fadeOut();});
$(document.body).on('click', '#save', function(){ $.ajax({ url: 'http://root.nuclearpixel.com/misc/wrappers/codepen_aFcDg.php', data: { data: JSON.stringify(settings) }, dataType: "json", success: function(data){ console.log(data); $('#short').attr('value', data.id); $('#fade').fadeIn(); } });
});
var geomSettingsChangedHandler = function(){	myLathe.shape.points = [];	populateShape();
};
var scaleSettingsChangedHandler = function(){	myLathe.scale[0] = settings.scaleX;
};
var renderPropertyChangeHandler = function(){	myLathe.pointScale = settings.pointScale;	myLathe.pointStyle = settings.pointStyle;	s.lineWidth = settings.lineWidth;	s.globalCompositeOperation = settings.composite;
};
var gui = new dat.GUI();
var folderGeom = gui.addFolder('Geometry');
var folderColor = gui.addFolder('Color');
var folderRender = gui.addFolder('Render Style');
folderGeom.add( settings, 'pointsPerCircle', 0, 360).step(1).onChange( geomSettingsChangedHandler );
folderGeom.add( settings, 'circlesPerShape', 1, 360).step(1).onChange( geomSettingsChangedHandler );
folderGeom.add( settings, 'ripples', 0, 24).step(1).onChange( geomSettingsChangedHandler );
folderGeom.add( settings, 'rippleAmp', -200, 200).step(1).onChange( geomSettingsChangedHandler );
gui_x = folderGeom.add( settings, 'offsetX', -200, 200).step(1).onChange( geomSettingsChangedHandler );
gui_y = folderGeom.add( settings, 'offsetY', -200, 200).step(1).onChange( geomSettingsChangedHandler);
folderGeom.add( settings, 'scaleX', 0.1, 2).onChange( scaleSettingsChangedHandler );
folderColor.add( settings, 'rainbow' ).onChange( geomSettingsChangedHandler );
folderColor.add( settings, 'hueMirror' ).onChange( geomSettingsChangedHandler );
folderColor.add( settings, 'hueStart', 0, 360).step(1).onChange( geomSettingsChangedHandler );
folderColor.add( settings, 'hueEnd', 0, 360).step(1).onChange( geomSettingsChangedHandler );
folderColor.add( settings, 'hueRots', 0, 10).step(1).onChange( geomSettingsChangedHandler );
folderColor.add( settings, 'hueAxies', ['xy','yx','xz','zx','yz','zy']).onChange( geomSettingsChangedHandler );
folderRender.add( settings, 'pointScale', 1, 20).step(1).onChange( renderPropertyChangeHandler );
folderRender.add( settings, 'pointStyle', ['fill','stroke']).onChange( renderPropertyChangeHandler );
folderRender.add( settings, 'lineWidth', 1, 20).step(1).onChange( renderPropertyChangeHandler );
folderRender.add( settings, 'composite', ['source-over','lighter','xor']).onChange( renderPropertyChangeHandler );
gui.add( settings, 'autoRotate' );
var clicked = false;
var updateFromMpos = function() {	settings.offsetX = s.mpos.x;	settings.offsetY = s.mpos.y;	geomSettingsChangedHandler();	gui_x.updateDisplay();	gui_y.updateDisplay();
};
var downHandler = function() {	clicked = true;
};
var moveHandler = function() {	if(clicked){	updateFromMpos();	}
};
var upHandler = function(){	updateFromMpos();	clicked = false;
};
s.canvas.addEventListener('mousedown',downHandler,false);
s.canvas.addEventListener('touchstart',downHandler,false);
s.canvas.addEventListener('mousemove',moveHandler,false);
s.canvas.addEventListener('touchmove',moveHandler,false);
s.canvas.addEventListener('mouseup',upHandler,false);
s.canvas.addEventListener('touchend',upHandler,false);
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-7088806-4']);
_gaq.push(['_trackPageview']);
(function() { var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
Spiralator 9000 - Script Codes
Spiralator 9000 - Script Codes
Home Page Home
Developer Admiral Potato
Username AdmiralPotato
Uploaded December 10, 2022
Rating 4
Size 4,671 Kb
Views 6,072
Do you need developer help for Spiralator 9000?

Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!

Admiral Potato (AdmiralPotato) Script Codes
Create amazing blog posts with AI!

Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!