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