Skip to content

Instantly share code, notes, and snippets.

@Sanokei
Created December 4, 2022 22:53
Show Gist options
  • Save Sanokei/ce33effb4d55e61e497fe87c84f935fc to your computer and use it in GitHub Desktop.
Save Sanokei/ce33effb4d55e61e497fe87c84f935fc to your computer and use it in GitHub Desktop.
https://dschool.stanford.edu/ Has a cool background, here is the code for it. It requires a lot of webpacks for it to work and im lazy so i didnt add that.
/*hero line stuff ONLY (FIXME: NO WEBPACKS INJECTION)*/
(function(module, exports, __webpack_require__) {
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _src = __webpack_require__(588);
var _src2 = _interopRequireDefault(_src);
var _domComponent = __webpack_require__(361);
var _domComponent2 = _interopRequireDefault(_domComponent);
var _patterns = __webpack_require__(599);
var _patterns2 = _interopRequireDefault(_patterns);
var _helpers = __webpack_require__(601);
var _utilities = __webpack_require__(332);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var LINE_COUNT = 50;
var PIVOT_COUNT = 40;
var MOVE_SPEED = 0.8;
var MODE_ATTRACT = 0;
var MODE_AVOID = 1;
var MODE_CRAZY = 2;
var COLORS = ['rgba(242, 64, 52, 0.3)', 'rgba(246, 101, 51, 0.3)', 'rgba(255, 171, 64, 0.3)', 'rgba(62, 204, 119, 0.3)', 'rgba(108, 190, 227, 0.3)', 'rgba(62, 102, 130, 0.3)'];
var HeroLines = function (_DOMComponent) {
_inherits(HeroLines, _DOMComponent);
function HeroLines() {
_classCallCheck(this, HeroLines);
return _possibleConstructorReturn(this, (HeroLines.__proto__ || Object.getPrototypeOf(HeroLines)).apply(this, arguments));
}
_createClass(HeroLines, [{
key: 'init',
value: function init() {
this.context = this.root.getContext('2d');
this.time = 0;
this.config = HeroLines.createConfig();
this.mouseX = null;
this.mouseY = null;
this.mouseMoveRatio = null;
this.isVisible = false;
this.lines = [];
this.pivots = [];
this.pivotsFixed = [];
this.attractions = [];
this.pixelRatio = window.devicePixelRatio;
this.physics = new _src2.default(0.1, 0.01);
this.big = this.physics.makeParticle(0.1, 0.0, 0.0, 0.0);
this.initiated = false;
this.mode = 0;
this.createLines();
if (this.config.interactive) {
this.onMouseMove = this.onMouseMove.bind(this);
this.onMouseClick = this.onMouseClick.bind(this);
window.addEventListener('mousemove', this.onMouseMove);
window.addEventListener('click', this.onMouseClick);
}
this.onUpdateViewport = this.onUpdateViewport.bind(this);
window.addEventListener('resize', (0, _utilities.simpleDebounce)(this.onUpdateViewport, 200));
window.addEventListener('scroll', (0, _utilities.simpleDebounce)(this.onUpdateViewport, 200));
this.onUpdateViewport();
this.onTick = this.onTick.bind(this);
this.scheduleTick();
}
}, {
key: 'createLines',
value: function createLines() {
this.big.makeFixed();
for (var i = 0; i < LINE_COUNT; i++) {
this.lines.push(new _helpers.Line());
this.pivots[i] = [];
this.pivotsFixed[i] = [];
this.attractions[i] = [];
for (var j = 0; j < PIVOT_COUNT; j++) {
this.pivots[i][j] = this.physics.makeParticle(0.4, 0, 0, 0.0);
this.pivotsFixed[i][j] = this.physics.makeParticle(0.4, 0, 0, 0.0);
this.pivotsFixed[i][j].makeFixed();
this.attractions[i][j] = new _src2.default.Attraction(this.big, this.pivots[i][j], 150000, 20.0);
this.physics.addAttraction(this.attractions[i][j]);
// this.physics.makeAttraction(this.big, this.pivots[i][j], 100000, 20.0)
this.physics.makeSpring(this.pivots[i][j], this.pivotsFixed[i][j], 0.2, 0.3, 5);
if (j > 0) {
this.physics.makeSpring(this.pivots[i][j - 1], this.pivots[i][j], 0.5, 0.1, 5);
}
}
}
}
}, {
key: 'onMouseMove',
value: function onMouseMove(e) {
if (!this.isVisible) {
return;
}
this.big.position.set((e.pageX - this.root.offsetLeft) * this.mouseMoveRatio, (e.pageY - this.root.offsetTop) * this.mouseMoveRatio, 0);
}
}, {
key: 'onMouseClick',
value: function onMouseClick() {
this.mode = (this.mode + 1) % 3;
var attraction = void 0;
if (MODE_ATTRACT === this.mode) {
attraction = 150000;
} else if (MODE_AVOID === this.mode) {
attraction = -5500000;
} else if (MODE_CRAZY === this.mode) {
attraction = 5500000;
}
for (var i = 0; i < LINE_COUNT; i++) {
for (var j = 0; j < PIVOT_COUNT; j++) {
this.attractions[i][j].constant = attraction;
}
}
}
}, {
key: 'onUpdateViewport',
value: function onUpdateViewport() {
var rect = this.root.getBoundingClientRect();
this.isVisible = rect.top < window.innerHeight && rect.bottom > 0;
if (rect.width * this.pixelRatio !== this.root.width || rect.height * this.pixelRatio !== this.root.height) {
this.width = rect.width;
this.root.width = rect.width * this.pixelRatio;
this.height = rect.height;
this.root.height = rect.height * this.pixelRatio;
this.yMin = (rect.width >= 1200 ? 100 : 0) * this.pixelRatio;
this.yMax = (rect.width >= 1200 ? 900 : 800) * this.pixelRatio;
}
this.mouseOffset = this.yMin / this.height;
this.mouseScale = (this.yMax - this.yMin) / this.height;
this.mouseMoveRatio = this.width / window.innerWidth;
}
}, {
key: 'scheduleTick',
value: function scheduleTick() {
var lastTime = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : Date.now() / (1000 / MOVE_SPEED);
this.lastTime = lastTime;
requestAnimationFrame(this.onTick);
}
}, {
key: 'onTick',
value: function onTick() {
if (!this.isVisible) {
this.scheduleTick(this.lastTime);
return;
}
var time = Date.now() / (1000 / MOVE_SPEED);
var delta = time - this.lastTime;
var mouseX = this.mouseX,
mouseY = this.mouseY,
width = this.width,
height = this.height,
physics = this.physics;
var context = {
time: time,
delta: delta,
width: width,
height: height,
mouseX: mouseX,
mouseY: mouseY
};
var pattern = this.config.pattern;
this.update(pattern(context));
physics.tick();
this.draw();
this.scheduleTick(time);
}
}, {
key: 'update',
value: function update(_ref) {
var line1 = _ref.line1,
line2 = _ref.line2;
for (var i = 1; i < LINE_COUNT - 1; i++) {
this.lines[i].interpolate(line1, line2, i / (LINE_COUNT - 1));
}
for (var j = 0; j < PIVOT_COUNT; j++) {
var newPosFirst = (0, _helpers.sliceBezier)([line1.p1.x, line1.p1.y, line1.p1c.x, line1.p1c.y, line1.p2c.x, line1.p2c.y, line1.p2.x, line1.p2.y], j / PIVOT_COUNT);
var newPosLast = (0, _helpers.sliceBezier)([line2.p1.x, line2.p1.y, line2.p1c.x, line2.p1c.y, line2.p2c.x, line2.p2c.y, line2.p2.x, line2.p2.y], j / PIVOT_COUNT);
this.pivotsFixed[0][j].position.set(newPosFirst.x, newPosFirst.y, 0);
this.pivotsFixed[LINE_COUNT - 1][j].position.set(newPosLast.x, newPosLast.y, 0);
if (!this.initiated) {
this.pivots[0][j].position.set(newPosFirst.x, newPosFirst.y, 0);
this.pivots[LINE_COUNT - 1][j].position.set(newPosLast.x, newPosLast.y, 0);
}
for (var _i = 1; _i < LINE_COUNT - 1; _i++) {
var newX = newPosFirst.x + (newPosLast.x - newPosFirst.x) * _i / LINE_COUNT;
var newY = newPosFirst.y + (newPosLast.y - newPosFirst.y) * _i / LINE_COUNT;
this.pivotsFixed[_i][j].position.set(newX, newY, 0);
if (!this.initiated) {
this.pivots[_i][j].position.set(newX, newY, 0);
}
}
}
this.initiated = true;
}
}, {
key: 'draw',
value: function draw() {
var context = this.context,
pixelRatio = this.pixelRatio,
mode = this.mode,
canvas = this.root;
var isInverted = this.config.isInverted;
context.clearRect(0, 0, canvas.width, canvas.height);
if (!isInverted) {
context.strokeStyle = 'rgba(0, 0, 0, 0.2)';
} else if (MODE_ATTRACT === mode) {
context.strokeStyle = 'rgba(242, 64, 52, 0.2)';
} else if (MODE_AVOID === mode) {
context.strokeStyle = 'rgba(108, 190, 227, 0.3)';
}
// lineWidth > 1 kills cpu performance
// context.scale(pixelRatio, pixelRatio)
for (var i = 1; i < LINE_COUNT - 1; i++) {
var line = this.pivots[i];
if (MODE_CRAZY === mode) {
context.strokeStyle = COLORS[Math.floor(Math.random() * COLORS.length)];
}
context.beginPath();
context.moveTo(this.lines[i].p1.x * pixelRatio, this.lines[i].p1.y * pixelRatio);
for (var j = 0, pivot; pivot = line[j]; j++) {
context.lineTo(pivot.position.x * pixelRatio, pivot.position.y * pixelRatio);
}
context.lineTo(this.lines[i].p2.x * pixelRatio, this.lines[i].p2.y * pixelRatio);
context.stroke();
}
}
}], [{
key: 'createConfig',
value: function createConfig() {
var themeClass = document.body.className.match(/Theme--(\S+)/);
var theme = themeClass && themeClass[1];
switch (theme) {
default:
{
var randomIndex = Math.floor(Math.random() * _patterns2.default.length);
return {
isInverted: theme === 'home' || theme === '404',
interactive: true,
pattern: _patterns2.default[randomIndex]
};
}
}
}
}]);
return HeroLines;
}(_domComponent2.default);
HeroLines.selector = '[data-hero-lines]';
exports.default = HeroLines;
/***/ })
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment