Dripping ink

You may have noticed the drops of ink running down randomly from top to bottom of the page. These appear sometimes, not always. They are fully scripted, without the use of any images. They have randomized size, speed and direction. They fade out when they are near the bottom of the page.

HTML:

JAVASCRIPT:

document.addEventListener('DOMContentLoaded', () => {
//are we in mobile view
const headerActions = document.querySelector('.header-actions');
let isTouch = false;
function checkHeader() {
const styles = window.getComputedStyle(headerActions);
isTouch = styles.getPropertyValue('display') !== 'flex';
}
checkHeader();
const subString = 'shop';
const subStringTwo = 'legal';
const subStringThree = 'contact';
const subStringFour = 'cart';
const gallery = document.getElementsByClassName("gallery-masonry");
const getURL = window.location.href;
if (!getURL.includes(subString) && gallery.length <= 0 && !getURL.includes(subStringTwo) && !getURL.includes(subStringThree) && !getURL.includes(subStringFour)) {
const siteWrapper = document.getElementById('siteWrapper');
const container = document.createElement('div');
container.classList.add('dripContainer');
container.id = "dripContainer";
siteWrapper.appendChild(container);
function createTrail() {
const startX = Math.random() * (window.innerWidth - 10);
const startY = -20;
let lastX = startX;
let lastY = startY;
const segmentInterval = isTouch ? 60 : 30; //how often a new segment is spawned in ms
const minSize = 12;
const maxSize = 17;
const size = Math.floor(Math.random() * (maxSize - minSize + 1)) + minSize;
const segmentSize = size;
const trailInterval = setInterval(() => {
const randomOffset = (Math.random() - 0.5) * 3;
const newX = lastX + randomOffset;
const minSpeed = 0.5;
const maxSpeed = 3;
const speed = (Math.random() * (maxSpeed - minSpeed + 1)) + minSpeed;
const newY = lastY + speed;
const pageLength = siteWrapper.scrollHeight;
const trailSegment = createTrailSegment(newX, newY, segmentSize);
container.appendChild(trailSegment);
var pagePercent = (pageLength - lastY) / pageLength;
if (pagePercent < 0.2) {
trailSegment.style.opacity = Math.min(pagePercent * 5, 1);
trailSegment.style.transform = `scale(${Math.min(pagePercent * 5, 1)})`;
}
setTimeout(() => {
trailSegment.style.opacity = 0;
trailSegment.style.transform = 'scale(0.3)';
}, 30);
trailSegment.addEventListener('transitionend', () => {
if (parseFloat(trailSegment.style.opacity) <= 0) {
trailSegment.remove();
if (container.children.length === 0) {
container.remove();
	}
}
}, { once: true });
lastX = newX;
lastY = newY;
if (newY >= pageLength - 25) {
clearInterval(trailInterval);
	}
}, segmentInterval);
}
function createTrailSegment(x, y, size) {
const trail = document.createElement('div');
const transitionDuration = isTouch ? '4.5s' : '6.5s';
trail.classList.add('trail');
trail.style.left = `${x}px`;
trail.style.top = `${y}px`;
trail.style.width = `${size}px`;
trail.style.height = `${size}px`;
trail.style.transition = `opacity ${transitionDuration} ease-out, transform ${transitionDuration} ease-out`;
container.style.height = siteWrapper.scrollHeight + 'px';
return trail;
}
function getRandomInt(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
function runCreateTrailRandomTimes() {
const maxDrips = isTouch ? 1 : 2;
const randomNum = getRandomInt(-5, maxDrips); //change the min to lesser number for less frequency of appearing drips
let count = 0;
function execute() {
if (count < randomNum) {
createTrail();
count++;
const randomDelay = getRandomInt(3, 15) * 1000;
setTimeout(execute, randomDelay);
	}
}
execute();
}
runCreateTrailRandomTimes();
}
//forceful cleanup
const dripContainer = document.getElementById('dripContainer');
function executeAfterDelay() {
if (dripContainer !== null && dripContainer !== undefined) {
dripContainer.remove();
	}
}
setTimeout(executeAfterDelay, 69000);
});
CSS:

#dripContainer {
    position: absolute;
    width: 100%;
    height: 100%;
    background-color: transparent;
  	pointer-events: none;
  	overflow: hidden;
}
#dripContainer .trail {
    position: absolute;
    background-color: black;
    border-radius: 50%;
    width: 10px;
    height: 10px;
  	filter: blur(1px);
  	z-index: 9999;
}

The animation for fading out I leave up to you.

Previous
Previous

Images on add-to-cart buttons

Next
Next

Ink splatter on click