Start with a neat lava lamp effect
This commit is contained in:
commit
3654ae61df
68
drift.js
Normal file
68
drift.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
const m = 76667 * 78887;
|
||||||
|
const nextRandom = x => x ** 2 % m
|
||||||
|
|
||||||
|
const generateRandomArray = (initialSeed, count) => (
|
||||||
|
count <= 0
|
||||||
|
? []
|
||||||
|
: [initialSeed].concat(generateRandomArray(nextRandom(initialSeed), count - 1)))
|
||||||
|
|
||||||
|
const zip = (f, ...lists) => (
|
||||||
|
lists.some(l => l.length == 0)
|
||||||
|
? []
|
||||||
|
: [f(...lists.map(l => l[0]))].concat(zip(f, ...lists.map(l => l.slice(1)))))
|
||||||
|
|
||||||
|
const goopZoneElem = document.getElementById("goop-zone");
|
||||||
|
const goopHeader = document.getElementById("header-box");
|
||||||
|
|
||||||
|
const nextState = (state, width, height) => document.hidden ? state : state.map(orig => {
|
||||||
|
const projectedNewX = orig.x + orig.vx;
|
||||||
|
const projectedNewY = orig.y + orig.vy;
|
||||||
|
const [newX, newVX] =
|
||||||
|
projectedNewX < 0 || projectedNewX > width
|
||||||
|
? [orig.x - orig.vx, -orig.vx]
|
||||||
|
: [projectedNewX, orig.vx];
|
||||||
|
const [newY, newVY] =
|
||||||
|
projectedNewY < -50 || projectedNewY > height - 20
|
||||||
|
? [orig.y - orig.vy, -orig.vy]
|
||||||
|
: [projectedNewY, orig.vy];
|
||||||
|
return ({
|
||||||
|
elem: orig.elem,
|
||||||
|
x: newX,
|
||||||
|
y: newY,
|
||||||
|
vx: newVX,
|
||||||
|
vy: newVY
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
const mkInitialState = (drifters, width, height) => zip(
|
||||||
|
(elem, random1, random2, random3) => (direction =>
|
||||||
|
({ elem: elem
|
||||||
|
, x: random1 % width
|
||||||
|
, y: random2 % height
|
||||||
|
, vx: 20 * Math.cos(direction)
|
||||||
|
, vy: 20 * Math.sin(direction)
|
||||||
|
})
|
||||||
|
)(random3 % 2000 / 1000 * Math.PI),
|
||||||
|
drifters,
|
||||||
|
generateRandomArray(5737051, drifters.length),
|
||||||
|
generateRandomArray(5457297, drifters.length),
|
||||||
|
generateRandomArray(3631413, drifters.length))
|
||||||
|
|
||||||
|
const applyState = states => states.map(s => {
|
||||||
|
s.elem.setAttribute('style', `transform: translate(${s.x}px, ${s.y}px)`)
|
||||||
|
});
|
||||||
|
|
||||||
|
loop = (state) => {
|
||||||
|
setInterval(() => {
|
||||||
|
const goopZoneWidth = goopZoneElem.width.baseVal.value;
|
||||||
|
const goopZoneHeight = goopZoneElem.height.baseVal.value;
|
||||||
|
|
||||||
|
goopHeader.setAttribute("x", goopZoneWidth/2-300);
|
||||||
|
|
||||||
|
state = nextState(state, goopZoneWidth, goopZoneHeight);
|
||||||
|
applyState(state)
|
||||||
|
}, 500)
|
||||||
|
}
|
||||||
|
|
||||||
|
const drifters = Array.from(document.getElementsByClassName("glob"));
|
||||||
|
loop(mkInitialState(drifters, goopZoneElem.width.baseVal.value, goopZoneElem.height.baseVal.value));
|
47
index.html
Normal file
47
index.html
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
<!Doctype HTML>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Emi Simpson - Nice to meet you!</title>
|
||||||
|
<link rel="stylesheet" href="style.css" />
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<header>
|
||||||
|
<svg id=goop-zone>
|
||||||
|
<defs>
|
||||||
|
<filter id="goop-full">
|
||||||
|
<feGaussianBlur stdDeviation="30"/>
|
||||||
|
<feColorMatrix values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1000 -250"/>
|
||||||
|
</filter>
|
||||||
|
<path
|
||||||
|
id="the-one-true-glob"
|
||||||
|
d="M 24.0,158.5 0,67.2 48.1,0 189.7,36.6 146.5,87.4 185.2,135.3 84.8,134.1 Z" />
|
||||||
|
</defs>
|
||||||
|
<g style="filter:url(#goop-full);width:100%;height:100%">
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<use class="glob" xlink:href="#the-one-true-glob" />
|
||||||
|
<rect width=2000 height=30 x=-60 y=400 /> <!-- base -->
|
||||||
|
<rect width=600 height=130 x=100 y=135 id="header-box" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
<h1>Emi Simpson</h1>
|
||||||
|
</header>
|
||||||
|
<script src="drift.js"></script>
|
||||||
|
<main>
|
||||||
|
</main>
|
||||||
|
</body>
|
||||||
|
</html>
|
27
style.sass
Normal file
27
style.sass
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
body, html
|
||||||
|
margin: 0
|
||||||
|
padding: 0
|
||||||
|
display: grid
|
||||||
|
grid-template-rows: 400px 1fr
|
||||||
|
height: 100vh
|
||||||
|
|
||||||
|
h1
|
||||||
|
position: absolute
|
||||||
|
top: 140px
|
||||||
|
text-align: center
|
||||||
|
width: 100vw
|
||||||
|
color: white
|
||||||
|
font-family: Atkinson Hyperlegible
|
||||||
|
font-size: 3em
|
||||||
|
|
||||||
|
#goop-zone
|
||||||
|
position: relative
|
||||||
|
width: 100vw
|
||||||
|
height: 400px
|
||||||
|
fill: #b50931
|
||||||
|
|
||||||
|
.glob
|
||||||
|
transition: transform 0.485s linear
|
||||||
|
|
||||||
|
main
|
||||||
|
background-color: #b50931
|
Loading…
Reference in a new issue