Spiralator 9000
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 - 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);
})();
Developer | Admiral Potato |
Username | AdmiralPotato |
Uploaded | December 10, 2022 |
Rating | 4 |
Size | 4,671 Kb |
Views | 6,072 |
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!
Name | Size |
A Pen by Admiral Potato | 1,957 Kb |
Basic 3D Webkit Frequency Analyser | 3,659 Kb |
Empty NPos3D template | 1,655 Kb |
Multiple Radial Point Interpolated Animation | 2,923 Kb |
Vertical Positioning | 1,690 Kb |
Black Hole | 2,089 Kb |
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!
Name | Username | Size |
Import shader in three.js | Khangeldy | 2,636 Kb |
Responsive Advert | James_zedd | 2,354 Kb |
Scrolling Horizontal Isotope | Bramus | 2,017 Kb |
Right Click Menu | Anodpixels | 2,252 Kb |
Importable Clearfix | Corysimmons | 1,411 Kb |
A Pen by Andrea Berardi | Aberry | 1,330 Kb |
Clock with full screen background | Owebboy | 2,415 Kb |
NT Tribute | Skybutterfly | 2,850 Kb |
Playing with FlexBox | _Billy_Brown | 3,162 Kb |
Project_one | MOHIM | 9,592 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!