Skip to content

Instantly share code, notes, and snippets.

@caputomarcos
Created July 10, 2022 04:31
Show Gist options
  • Save caputomarcos/f45b13d4a8202af3c4aa2120a7c184b8 to your computer and use it in GitHub Desktop.
Save caputomarcos/f45b13d4a8202af3c4aa2120a7c184b8 to your computer and use it in GitHub Desktop.
DZKdNp
<div id="spacer"></div>
<div id="stage">
<canvas></canvas>
</div>
!function(win, doc) {
'use strict';
/////////////////////////////////////////////////
var raf = win.requestAnimationFrame ||
win.webkitRequestAnimationFrame ||
win.mozRequestAnimationFrame ||
win.msRequestAnimationFrame ||
win.oRequestAnimationFrame ||
function(func) { setTimeout(func, 1000 / 60); };
/////////////////////////////////////////////////
var WIDTH = 465,
HEIGHT = 465,
ERROR = .03,
HEXAGON_SIZE = 15,
cvs = doc.querySelector('canvas'),
ctx = cvs.getContext('2d'),
hexagons = [],
curScrollRate = 0,
destScrollRate = 0,
frame = 0;
/////////////////////////////////////////////////
win.addEventListener('DOMContentLoaded', main, false);
/////////////////////////////////////////////////
/**
*
*/
function main() {
hexagons = createHexagons();
cvs.width = WIDTH;
cvs.height = HEIGHT;
win.addEventListener('scroll', handleScroll, false);
handleEnterFrame();
setTimeout(function() {
win.scrollTo(0, 2800);
}, 500);
}
/////////////////////////////////////////////////
/**
*
*/
function handleEnterFrame() {
var MIN = 0.0001,
deltaScrollRate;
if (++frame > 3) {
frame = 0;
deltaScrollRate = (destScrollRate - curScrollRate) / 5;
if (deltaScrollRate < -MIN || MIN < deltaScrollRate) {
curScrollRate = curScrollRate + deltaScrollRate;
render(curScrollRate);
}
}
raf(handleEnterFrame, cvs);
}
/////////////////////////////////////////////////
/**
*
*/
function handleScroll() {
var scrollTop = doc.body.scrollTop || doc.documentElement.scrollTop,
scrollHeight = doc.body.scrollHeight || doc.documentElement.scrollHeight,
scrollRate = scrollTop / (scrollHeight - win.innerHeight);
scrollRate = scrollRate < 0 ? 0 :
scrollRate > 1 ? 1 :
scrollRate;
destScrollRate = scrollRate;
}
/////////////////////////////////////////////////
/**
* @class
* @constructor
* @param {number} x
* @param {number} y
*/
function Point(x, y) {
this.x = x;
this.y = y;
}
/////////////////////////////////////////////////
/**
* @class
* @constructor
* @param {Point} a
* @param {Point} b
* @param {Point} c
* @param {Point} d
* @param {Point} e
* @param {Point} f
* @param {Point} center
* @param {number} delay
*/
function Hexagon(a, b, c, d, e, f, center, delay) {
this.a = a;
this.b = b;
this.c = c;
this.d = d;
this.e = e;
this.f = f;
this.center = center;
this.delay = delay;
}
/////////////////////////////////////////////////
/**
* @param {number} x
* @param {number} y
* @param {number} delay
* @return {Hexagon}
*/
function createHexagon(x, y, delay) {
var deg30 = 30 * Math.PI / 180,
sin30 = Math.sin(deg30),
cos30 = Math.cos(deg30),
center = new Point(x, y),
a, b, c, d, e, f;
/**
*
* a b
*
*
* |
* f -[x,y]- c
* |
*
*
* e d
*
*/
a = new Point(
-sin30 * HEXAGON_SIZE,
-cos30 * HEXAGON_SIZE
);
b = new Point(
sin30 * HEXAGON_SIZE,
-cos30 * HEXAGON_SIZE
);
c = new Point(
HEXAGON_SIZE,
0
);
d = new Point(
sin30 * HEXAGON_SIZE,
cos30 * HEXAGON_SIZE
);
e = new Point(
-sin30 * HEXAGON_SIZE,
cos30 * HEXAGON_SIZE
);
f = new Point(
-HEXAGON_SIZE,
0
);
return new Hexagon(a, b, c, d, e, f, center, delay);
}
/////////////////////////////////////////////////
/**
* @return {Array.<Hexagon>}
*/
function createHexagons() {
var deg30 = 30 * Math.PI / 180,
sin30 = Math.sin(deg30),
cos30 = Math.cos(deg30),
COLS = Math.ceil(WIDTH / (HEXAGON_SIZE * 3 )) + 1,
ROWS = Math.ceil(HEIGHT / (HEXAGON_SIZE * cos30)) + 1,
radius = Math.sqrt(WIDTH * WIDTH + HEIGHT * HEIGHT),
DELTA_X = HEXAGON_SIZE * sin30 + HEXAGON_SIZE,
arr = [],
x, y, r, c, delay;
for (r = ROWS; r--;) {
for (c = COLS; c--;) {
x = -(HEXAGON_SIZE / 2) + (HEXAGON_SIZE * 3 ) * c + HEXAGON_SIZE;
y = (HEXAGON_SIZE * cos30) * r;
delay = Math.sqrt(x * x + y * y) * (1 - ERROR) / radius + ERROR * Math.random();
if (r & 1) {
arr.push(createHexagon(x + DELTA_X, y, delay));
} else {
arr.push(createHexagon(x, y, delay));
}
}
}
return arr;
}
/////////////////////////////////////////////////
/**
* @param {number} scrollRate
*/
function render(scrollRate) {
var SPEED = .01,
arr = hexagons,
i = arr.length,
hex, rate;
ctx.clearRect(0, 0, WIDTH, HEIGHT);
ctx.save();
ctx.beginPath();
while (i--) {
hex = arr[i];
rate = (scrollRate - hex.delay) / SPEED;
rate = rate < 0 ? 0 :
rate > 1 ? 1 :
rate;
ctx.save();
ctx.translate(hex.center.x, hex.center.y);
ctx.moveTo(hex.a.x * rate, hex.a.y * rate);
ctx.lineTo(hex.b.x * rate, hex.b.y * rate);
ctx.lineTo(hex.c.x * rate, hex.c.y * rate);
ctx.lineTo(hex.d.x * rate, hex.d.y * rate);
ctx.lineTo(hex.e.x * rate, hex.e.y * rate);
ctx.lineTo(hex.f.x * rate, hex.f.y * rate);
ctx.lineTo(hex.a.x * rate, hex.a.y * rate);
ctx.restore();
}
ctx.fillStyle = '#222';
ctx.fill();
ctx.beginPath();
i = arr.length;
while (i--) {
hex = arr[i];
rate = (scrollRate - hex.delay + .02) / SPEED;
rate = rate < 0 ? 0 :
rate > 1 ? 1 :
rate;
ctx.save();
ctx.translate(hex.center.x, hex.center.y);
ctx.moveTo(hex.a.x * rate, hex.a.y * rate);
ctx.lineTo(hex.b.x * rate, hex.b.y * rate);
ctx.lineTo(hex.c.x * rate, hex.c.y * rate);
ctx.lineTo(hex.d.x * rate, hex.d.y * rate);
ctx.lineTo(hex.e.x * rate, hex.e.y * rate);
ctx.lineTo(hex.f.x * rate, hex.f.y * rate);
ctx.lineTo(hex.a.x * rate, hex.a.y * rate);
ctx.restore();
}
ctx.globalCompositeOperation = 'destination-over';
ctx.fillStyle = '#09f';
ctx.fill();
ctx.restore();
ctx.strokeStyle = '#000';
ctx.stroke();
}
/////////////////////////////////////////////////
}(this, document);
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
* {
margin: 0; padding: 0;
}
body {
background-color: #000;
overflow-x: hidden;
}
#spacer {
height: 10000px;
}
#stage {
position: fixed;
top: 0; left: 0;
width: 465px; height: 465px;
background: url(http://jsrun.it/assets/z/3/q/s/z3qsK.gif) no-repeat scroll 123px 212px;
}
canvas {
opacity: .9;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment