Skip to content

Instantly share code, notes, and snippets.

@bozzin
Created December 2, 2019 15:20
Show Gist options
  • Save bozzin/70eb4819b09435fbb7e45d4b4b5c41a9 to your computer and use it in GitHub Desktop.
Save bozzin/70eb4819b09435fbb7e45d4b4b5c41a9 to your computer and use it in GitHub Desktop.
Decision Compass
<section class="north-values-album-matte">
<div class="north-values-album-sleeve">
<div id="northValuesAlbumMain" class="north-values-album-main">
<div id="northValuesAlbumContainer" class="north-values-album-container"></div>
<div id="northValuesAlbumContent" class="north-values-album-content">
<div id="title" class="north-values-album-title">Decision<br>Compass</div>
<div id="header" class="north-values-album-header">
<div id="baseline" class="north-values-album-baseline">
<p id="date" class="north-values-album-date">37 SONGS</p>
<h1>#A div Above</h1>
<p id="description" class="north-values-album-description">A reflection of soul and value.</p>
</div>
<div id="author" class="north-values-album-author">— Carefully Crafted by <a href="https://www.chasenorth.com" target = "_blank">Chase North</a></div>
</div>
</div>
</div>
</div>
</section>
<!-- GLSL SCRIPT -->
<!-- vertex shader -->
<script id="vertexShader" type="x-shader/x-vertex">
void main() {
gl_Position = vec4(position, 1.0);
}
</script>
<!-- fragment shader -->
<script id="fragmentShader" type="x-shader/x-fragment">
uniform vec2 resolution;
uniform float time;
uniform sampler2D texture;
uniform float amplitude;
uniform float frequency;
uniform float lacunarity;
uniform float gain;
uniform float eta;
uniform float gamma;
uniform float eps;
#define PI 3.14159265359
#define TWO_PI 6.28318530718
#define octave 8
float expStep(float x, float k, float n ){
//Author: Inigo Quiles
return exp( -k*pow(x,n) );
}
mat2 rotate2d(float _angle){
return mat2(cos(_angle),-sin(_angle),
sin(_angle),cos(_angle));
}
vec2 rotateFrom(vec2 uv, vec2 center, float angle){
vec2 uv_ = uv - center;
uv_ = rotate2d(angle) * uv_;
uv_ = uv_ + center;
return uv_;
}
float random(float value){
return fract(sin(value) * 43758.5453123);
}
float random(vec2 tex){
return fract(sin(dot(tex.xy, vec2(12.9898, 78.233))) * 43758.5453123);
}
float random(vec3 tex){
//return fract(sin(x) * offset);
return fract(sin(dot(tex.xyz, vec3(12.9898, 78.233, 12.9898))) * 43758.5453123);//43758.5453123);
}
vec2 random2D(vec2 uv){
uv = vec2(dot(uv, vec2(127.1, 311.7)), dot(uv, vec2(269.5, 183.3)));
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}
vec3 random3D(vec3 uv){
uv = vec3(dot(uv, vec3(127.1, 311.7, 120.9898)), dot(uv, vec3(269.5, 183.3, 150.457)), dot(uv, vec3(380.5, 182.3, 170.457)));
return -1.0 + 2.0 * fract(sin(uv) * 43758.5453123);
}
float cubicCurve(float value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
vec2 cubicCurve(vec2 value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
vec3 cubicCurve(vec3 value){
return value * value * (3.0 - 2.0 * value); // custom cubic curve
}
float noise(vec2 uv){
vec2 iuv = floor(uv);
vec2 fuv = fract(uv);
vec2 suv = cubicCurve(fuv);
float dotAA_ = dot(random2D(iuv + vec2(0.0)), fuv - vec2(0.0));
float dotBB_ = dot(random2D(iuv + vec2(1.0, 0.0)), fuv - vec2(1.0, 0.0));
float dotCC_ = dot(random2D(iuv + vec2(0.0, 1.0)), fuv - vec2(0.0, 1.0));
float dotDD_ = dot(random2D(iuv + vec2(1.0, 1.0)), fuv - vec2(1.0, 1.0));
return mix(
mix(dotAA_, dotBB_, suv.x),
mix(dotCC_, dotDD_, suv.x),
suv.y);
}
float noise(vec3 uv){
vec3 iuv = floor(uv);
vec3 fuv = fract(uv);
vec3 suv = cubicCurve(fuv);
float dotAA_ = dot(random3D(iuv + vec3(0.0)), fuv - vec3(0.0));
float dotBB_ = dot(random3D(iuv + vec3(1.0, 0.0, 0.0)), fuv - vec3(1.0, 0.0, 0.0));
float dotCC_ = dot(random3D(iuv + vec3(0.0, 1.0, 0.0)), fuv - vec3(0.0, 1.0, 0.0));
float dotDD_ = dot(random3D(iuv + vec3(1.0, 1.0, 0.0)), fuv - vec3(1.0, 1.0, 0.0));
float dotEE_ = dot(random3D(iuv + vec3(0.0, 0.0, 1.0)), fuv - vec3(0.0, 0.0, 1.0));
float dotFF_ = dot(random3D(iuv + vec3(1.0, 0.0, 1.0)), fuv - vec3(1.0, 0.0, 1.0));
float dotGG_ = dot(random3D(iuv + vec3(0.0, 1.0, 1.0)), fuv - vec3(0.0, 1.0, 1.0));
float dotHH_ = dot(random3D(iuv + vec3(1.0, 1.0, 1.0)), fuv - vec3(1.0, 1.0, 1.0));
float passH0 = mix(
mix(dotAA_, dotBB_, suv.x),
mix(dotCC_, dotDD_, suv.x),
suv.y);
float passH1 = mix(
mix(dotEE_, dotFF_, suv.x),
mix(dotGG_, dotHH_, suv.x),
suv.y);
return mix(passH0, passH1, suv.z);
}
float computeCurl2DAt(float x, float y) {
//based Pete Werner implementation on http://platforma-kooperativa.org/media/uploads/curl_noise_slides.pdf
//float eps = 1.0; //here epsilon is a global
float n1, n2, a, b;
//compute gradients
n1 = noise(vec3(x, y + eps, 0));
n2 = noise(vec3(x, y - eps, 0));
a = (n1 - n2) / (2.0 * eps);
n1 = noise(vec3(x + eps, y, 0));
n2 = noise(vec3(x - eps, y, 0));
b = (n1 - n2) / (2.0 * eps);
vec2 curl = vec2(a, -b);
return (curl.x + curl.y) / 2.0;
}
float computeCurl3DAt(float x, float y, float z) {
//based Pete Werner implementation on http://platforma-kooperativa.org/media/uploads/curl_noise_slides.pdf
//float eps = 1.0; //here epsilon is a global
float n1, n2, a, b;
vec3 curl;
//compute gradients
n1 = noise(vec3(x, y + eps, z));
n2 = noise(vec3(x, y - eps, z));
a = (n1 - n2) / (2.0 * eps);
n1 = noise(vec3(x, y, z + eps));
n2 = noise(vec3(x, y, z - eps));
b = (n1 - n2) / (2.0 * eps);
curl.x = a - b;
n1 = noise(vec3(x, y, z + eps));
n2 = noise(vec3(x, y, z - eps));
a = (n1 - n2) / (2.0 * eps);
n1 = noise(vec3(x + eps, y, z));
n2 = noise(vec3(x + eps, y, z));
b = (n1 - n2) / (2.0 * eps);
curl.y = a - b;
n1 = noise(vec3(x + eps, y, z));
n2 = noise(vec3(x - eps, y, z));
a = (n1 - n2) / (2.0 * eps);
n1 = noise(vec3(x, y + eps, z));
n2 = noise(vec3(x, y - eps, z));
b = (n1 - n2) / (2.0 * eps);
curl.z = a - b;
return (curl.x + curl.y + curl.z) / 3.0;
}
float fbm(vec3 st, float amp, float freq, float lac, float gain){
//initial value
float fbm = 0.0;
vec3 shift = vec3(1.0);
mat2 rot2 = mat2(cos(-eta), sin(eta), -sin(eta), cos(eta));
mat3 rot3 = mat3(sin(-gamma) * cos(-eta), cos(gamma) * sin(eta), sin(gamma),
sin(gamma) * -sin(eta), sin(-gamma) * cos(eta), sin(gamma),
sin(gamma) * cos(eta), cos(gamma) * sin(eta), sin(gamma)
);
for(int i = 0; i < octave; i++){
fbm += amp * computeCurl3DAt(st.x * freq, st.y * freq, st.z * freq);//(st * freq);
st = rot3 * st * 1.5 + shift;
freq *= lac;
amp *= gain;
}
return fbm;
}
float domainWarping(vec3 st, float amp, float freq, float lac, float g){
vec3 q = vec3(0.0);
q.x = fbm(st, amp, freq, lac, g);
q.y = fbm(st + vec3(1.0), amp, freq, lac, g);
q.z = fbm(st + vec3(0.5), amp, freq, lac, g);
vec3 r = vec3(0.0);
r.x = fbm(st + 1.0 * q + vec3(0.610, 0.330, 0.556), amp, freq, lac, g);
r.y = fbm(st + 1.0 * q + vec3(-0.180, 0.190, - 0.156), amp, freq, lac, g);
r.z = fbm(st + 1.0 * q + vec3(0.750, -0.269, 0.256), amp, freq, lac, g);
return fbm(st + r, amp, freq, lac, g);
}
vec4 addGrain(vec2 uv, float time, float grainIntensity){
float grain = random(fract(uv * time)) * grainIntensity;
return vec4(vec3(grain), 1.0);
}
void main(){
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec2 ouv = uv;
vec2 center = vec2(0.5, 0.5);
float maxTime = 8.0;
float timeMod = mod(time, maxTime) / maxTime;
//uv = rotateFrom(uv, vec2(0.0, 0.5), (timeMod * 2.0 - 1.0) * TWO_PI * 0.1);
//uv.y += expStep(timeMod, 4.0, 1.0) * 2.0 - 0.55;//(fract(timeMod) * 1.5 - 0.75);
float amplitudeX = 0.01;
float periodX = 0.5;
float amplitudeY = 0.01;
float periodY = 5.0;
float wavex = sin(TWO_PI * periodX * uv.x + time) * amplitudeX;
float wavey = sin(TWO_PI * periodY * uv.y + time) * amplitudeY;
uv.y += wavex;
uv.x += wavey;
float dist = length(center - ouv);
float distEge = 0.05 + smoothstep(0.25, 0.5, dist) * 0.95;
float dw = domainWarping(vec3(ouv + vec2(0.0, time * 0.01), fract(time * 0.01)), 1.0, 5.0 , 1., 1.0);
dw = sin(dw * TWO_PI * distEge * 0.5);
float displace = dw;// * 2.0 - 1.0;
displace *= 1.0;
//displace *= distEge;
float grey = dw * 0.5 + 0.5;
vec2 offset = vec2(0.01, 0.01) * noise(vec3(ouv, time));
float R = texture2D(texture, uv + offset + displace).r;
float G = texture2D(texture, uv + displace).g;
float B = texture2D(texture, uv - offset + displace).b;
vec4 grain = addGrain(ouv, time, 0.1);
gl_FragColor = vec4(R, G, B, 1.0) + grain;
}
</script>
//Create var for the contenair, the webGL 3D scene, uniforms to bind into shader and timer
var stats = new Stats();
stats.showPanel( 7 ); // 0: fps, 1: ms, 2: mb, 3+: custom
document.body.appendChild( stats.domElement );
var main;
var content;
var container;
var camera, scene, renderer;
var uniforms;
var startTime;
var canvasWidth;
var canvasHeight;
var resPoster = 841.0/594.0;
var minWidth = 450;
var minHeight = minWidth * resPoster;
var margin = 50;
var text = "";
var texture;
var ctx;
var bitmap;
var fontSize = 100;
var loop = 1.0;
init(); //init scene
animate(); //updateScene
function init() {
//create image
bitmap = document.createElement('canvas');
ctx = bitmap.getContext('2d');
bitmap.width = 594;
bitmap.height = 841;
ctx.mozImageSmoothingEnabled = true;
ctx.webkitImageSmoothingEnabled = true;
ctx.msImageSmoothingEnabled = true;
ctx.imageSmoothingEnabled = true;
// canvas contents will be used for a texture
texture = new THREE.Texture(bitmap)
texture.needsUpdate = true;
//get contenaire
main = document.getElementById('northValuesAlbumMain');
container = document.getElementById('northValuesAlbumContainer');
content = document.getElementById('northValuesAlbumContent');
//Create THREE.JS scene and timer
startTime = Date.now();
camera = new THREE.Camera();
camera.position.z = 1;
scene = new THREE.Scene();
//create a simple plance
var geometry = new THREE.PlaneBufferGeometry(16, 9);
//create uniform table which provide all our GLSL binding
uniforms = {
time: { type: "f", value: 1.0 },
resolution: { type: "v2", value: new THREE.Vector2() },
texture: {type: 't', value: texture},
amplitude : {type:'f', value:0.5},
frequency : {type:'f', value:0.25},
lacunarity : {type:'f', value:2.0},
gain : {type:'f', value:0.5},
eta : {type:'f', value:0.0},
gamma : {type:'f', value:0.0},
eps : {type:'f', value:1.0}
};
//create THREE.JS material
var material = new THREE.ShaderMaterial( {
//set shaders and uniforms into material
uniforms: uniforms,
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent
} );
//create mesh, add it to the scene
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
//create renderer and add it to the DOM
renderer = new THREE.WebGLRenderer();
container.appendChild(renderer.domElement);
//check window for resize This will give us the proper resolution values to bind
onWindowResize();
window.addEventListener('resize', onWindowResize, false);
}
function onWindowResize(event) {
var mainHeight = window.innerHeight - margin * 2.0;
var mainWidth = mainHeight / resPoster;
var contentHeight = content.offsetHeight;
var contentMargin = margin * 0.25;
var containerHeight = mainHeight - (contentHeight + contentMargin);
var containerMinHeight = minHeight - (contentHeight + contentMargin);
main.style.height = mainHeight+"px";
main.style.width = mainWidth+"px";
main.style.minHeight = minHeight+"px";
main.style.minWidth = minWidth+"px";
main.style.padding = margin*0.5+"px";
content.style.margin = "0 0 "+contentMargin+"px 0";
container.style.height = containerHeight+"px";
container.style.minHeight = containerMinHeight+"px";
canvasWidth = container.offsetWidth;
canvasHeight = container.offsetHeight;
//send new size value to the shader and resize the window
uniforms.resolution.value.x = canvasWidth;
uniforms.resolution.value.y = canvasHeight;
renderer.setSize(canvasWidth, canvasHeight);
ctx = bitmap.getContext('2d');
bitmap.width = canvasWidth;
bitmap.height = canvasHeight;
ctx.mozImageSmoothingEnabled = true;
ctx.webkitImageSmoothingEnabled = true;
ctx.msImageSmoothingEnabled = true;
ctx.imageSmoothingEnabled = true;
}
function wrapText(context, text, x, y, maxWidth, lineHeight) {
var currentTime = Date.now();
var elaspedSeconds = (currentTime - startTime) / 1000.0;
var maxTime = 4.0;
var normTime = (elaspedSeconds % maxTime) / maxTime;
var words = text.split('');
var line = '';
var len = Math.floor(words.length * normTime)
for(var n = 0; n < words.length; n++) {
var testLine = line + words[n] + '';
var metrics = context.measureText(testLine);
var testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) {
context.fillText(line, x, y);
line = words[n] + '';
y += lineHeight;
}
else {
line = testLine;
}
}
context.fillText(line, x, y);
}
function animate() {
stats.begin();
text = "DECSION COMPASS DECSION COMPASS DECSION COMPASS DECSION COMPASS DECSION COMPASS DECSION"
ctx.fillRect(0, 0, bitmap.width, bitmap.height);
ctx.font = 'Bold '+fontSize+'px sans-serif';
ctx.fillStyle = "white";
wrapText(ctx, text, 20, 0, bitmap.width, fontSize * 0.85)
render();
stats.end();
requestAnimationFrame(animate);
}
function render() {
var currentTime = Date.now();
var elaspedSeconds = (currentTime - startTime) / 1000.0;
var maxTime = 8.0;
var normTime = (elaspedSeconds % maxTime) / maxTime;
uniforms.time.value = elaspedSeconds;
renderer.render(scene, camera);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script>
@import url('https://fonts.googleapis.com/css?family=Inconsolata');
@import url('https://fonts.googleapis.com/css?family=Poppins:100,200,300,400,500,600,700,800,900');
.values-album-matte {
background: #f8f8f8;
width: calc(100% - 345px);
position: relative;
left: 255px;
}
.north-values-album-sleeve {
position: relative;
margin: 0;
width: 100%;
height: 100%;
background : #151515;
padding: 120px 10px 30px 10px;
}
a,
a:active{
background-color: transparent;
color : white;
font-weight : normal
-webkit-transition: color 0.5s, background-color 0.5s; /* Safari 3.1 to 6.0 */
transition: color 0.5s, background-color 0.5s;
transition-timing-function: ease-in-out;
}
a:hover
{
background-color: #f8f8f8;
color : #151515;
}
canvas {
display: block;
}
.north-values-album-main
{
background : #151515;
position: relative;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
box-shadow: 2px 2px 5px rgba(0,0,0,0.3);
border: solid #d1d1d1;
border-width: 73px 27px 143px 27px;
}
.north-values-album-container,
.north-values-album-content{
position : relative;
color : #f8f8f8;
margin: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.north-values-album-content{
overflow : hidden;
border : solid;
border-width : 7px 0 0 0;
border-color : #d1d1d1;
height : auto;
display: flex;
position: relative;
}
.north-values-album-title{
padding : 10px 30px 10px 0;
width : 60%;
font-size : 42px;
text-transform : uppercase;
font-family : 'Poppins', 'Helvetica', sans-serif;
font-weight: 700;
letter-spacing : -0.75px;
font-kerning: auto;
}
.north-values-album-header{
text-align : right;
width : 500%;
font-family:'Inconsolata', monospace;
letter-spacing : 1.15px;
padding : 5px 0 20px 10px;
border : solid;
border-width : 0 0 0 1px;
border-color : #d1d1d1;
}
.north-values-album-date{
margin: 5px 0;
font-size : 0.95em;
}
.north-values-album-header h1{
margin: 5px 0;
font-size : 2.0em;
text-transform : uppercase;
}
.north-values-album-description, #author {
max-width: 85%;
display: block;
float: right;
}
.north-values-album-description{
margin : 10px 0;
}
.north-values-album-baseline{
width: 100%;
font-size : 0.85em;
line-height : 1.75em;
}
.north-values-album-author{
width: 100%;
font-size : 0.75em;
line-height : 1.75em;
padding : 10px 0 0 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment