Skip to content

Commit

Permalink
Various fixes
Browse files Browse the repository at this point in the history
- Make state transitions nicer
- Fix timer management
- Static camera
- Background friendly
- Limit max number of particles
  • Loading branch information
noobpwnftw committed Dec 26, 2022
1 parent 45ad0cd commit 5a57dd9
Show file tree
Hide file tree
Showing 14 changed files with 97 additions and 156 deletions.
2 changes: 1 addition & 1 deletion packages/snow3d/build/snow3d.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array(), 'version' => 'cc4a969e02505d0bca7c');
<?php return array('dependencies' => array(), 'version' => 'cbb216e8b4fa02975b8e');
2 changes: 1 addition & 1 deletion packages/snow3d/build/snow3d.js

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions packages/snow3d/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 0 additions & 49 deletions packages/snow3d/src/logic/controllers.ts

This file was deleted.

8 changes: 3 additions & 5 deletions packages/snow3d/src/logic/getTargets.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { getControllersState } from './controllers';
import { getWindowDimensions, scrollHeight } from './utils';

export const getCameraPoint = (): { x: number; y: number } => {
const { mouseX, mouseY, wheelY } = getControllersState();
const { innerWidth, innerHeight } = getWindowDimensions();

const pY = (innerHeight / 2 - mouseY) / innerHeight;
const pX = (innerWidth / 2 - mouseX) / innerWidth;
const pY = (innerHeight / 2) / innerHeight;
const pX = (innerWidth / 2) / innerWidth;

const sh = scrollHeight();
const pSH = (sh / 2 - wheelY) / sh;
const pSH = (sh / 2) / sh;

const x = (innerWidth * pX) / 4 - innerWidth / 8;
const y = (-1 * innerHeight * pY) / 4 - (innerHeight * pSH) / 2 + innerHeight / 4;
Expand Down
19 changes: 15 additions & 4 deletions packages/snow3d/src/logic/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import { Scene } from 'three/src/scenes/Scene.js';
import { getWindowDimensions } from './utils';

import { getTexture } from './getTexture';
import { queueRender } from './render';
import type { Settings } from './settings';
import { setSettings } from './settings';
import { setOpacity } from './opacity';
import { updateScene } from './updateScene';
import { variables } from './variables';

Expand All @@ -20,6 +20,8 @@ import fragmentShader from './shaders/fragment.glsl';
// @ts-ignore
import vertexShader from './shaders/vertex.glsl';

let resizeTimer;

export const init = async (settings: Settings = {}): Promise<void> => {
const { innerWidth, innerHeight } = getWindowDimensions();

Expand Down Expand Up @@ -56,7 +58,16 @@ export const init = async (settings: Settings = {}): Promise<void> => {
variables.particles = new Points(variables.bufferGeometry, shaderMaterial);
variables.scene.add(variables.particles);

queueRender();

window.addEventListener('resize', () => updateScene({ opacity: 1 }));
window.addEventListener('resize', () => {
setOpacity(0);
if (resizeTimer) {
clearTimeout(resizeTimer);
resizeTimer = undefined;
}
resizeTimer = setTimeout(() => {
updateScene({ opacity: 0 });
setOpacity(1);
resizeTimer = undefined;
}, 500);
});
};
4 changes: 4 additions & 0 deletions packages/snow3d/src/logic/opacity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export const setOpacity = (opacity: number): void => {
update: () => {
const opacity = variables.particles.geometry.attributes.opacity;

if (!opacity) {
return;
}

const particleNum = opacity.count / 2;
for (let i = 0; i < particleNum; i++) {
opacity.setX(i, opacityTarget.opacity);
Expand Down
50 changes: 12 additions & 38 deletions packages/snow3d/src/logic/render.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import anime from 'animejs/lib/anime.es.js';
import { getControllersState } from './controllers';
import { getCameraPoint, getTargets } from './getTargets';
import { getSettings } from './settings';
import { variables } from './variables';

const f = (val: number, delta: number): number => {
Expand All @@ -10,19 +7,17 @@ const f = (val: number, delta: number): number => {
return val;
};

let mouseXLast: number;
let mouseYLast: number;
let wheelYLast: number;
let animation: anime.AnimeInstance;

export const render = () => {
const { stoped } = getSettings();

if (stoped || !variables.particles) {
if (!variables.container || !variables.particles) {
return;
}

const position = variables.particles.geometry.attributes.position;

if (!position) {
return;
}

const posArr = variables.particles.geometry.attributes.position.array;
const velArr = variables.particles.geometry.attributes.velocity.array;
const delta = variables.camera.position.z;
Expand All @@ -41,32 +36,6 @@ export const render = () => {

variables.particles.geometry.attributes.position.needsUpdate = true;

const { mouseX, mouseY, wheelY } = getControllersState();

if (mouseXLast !== mouseX || mouseYLast !== mouseY || wheelYLast !== wheelY) {
const { x, y } = getCameraPoint();

animation = anime({
targets: getTargets(),
x,
y,
duration: 700,
easing: 'easeOutQuint',
update: () => {
const targets = getTargets();

variables.camera.position.x = targets.x;
variables.camera.position.y = targets.y;

variables.camera.lookAt(variables.scene.position);
},
});

mouseXLast = mouseX;
mouseYLast = mouseY;
wheelYLast = wheelY;
}

variables.renderer.render(variables.scene, variables.camera);

queueRender();
Expand All @@ -75,4 +44,9 @@ export const render = () => {
let requestID: number;

export const queueRender = () => (requestID = requestAnimationFrame(render));
export const cancelRender = () => requestID > 0 && cancelAnimationFrame(requestID);
export const cancelRender = () => {
if (requestID > 0) {
cancelAnimationFrame(requestID);
requestID = 0;
}
};
61 changes: 35 additions & 26 deletions packages/snow3d/src/logic/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { updateScene } from './updateScene';
import { variables } from './variables';

let removeTimer;
let redrawTimer;

let defaultSettings = {
speed: 50,
particleLevel: 500,
paused: false,
stoped: false,
};

export type Settings = Partial<typeof defaultSettings>;
Expand All @@ -20,45 +20,54 @@ let currentSettings = {
};

export const setSettings = (settings: Settings) => {
currentSettings = {
...defaultSettings,
...(settings?.speed ? { speed: Number(settings.speed) } : {}),
...(settings?.particleLevel ? { particleLevel: Number(settings.particleLevel) } : {}),
paused: settings?.paused || defaultSettings.paused,
};

if (!settings?.paused && currentSettings.stoped) {
currentSettings.stoped = false;
if (redrawTimer) {
clearTimeout(redrawTimer);
redrawTimer = undefined;
}

if (currentSettings.paused && variables.container) {
if (variables.container) {
setOpacity(0);

// TODO: remove async without timer.
if (removeTimer) {
clearTimeout(removeTimer);
removeTimer = undefined;
}

removeTimer = setTimeout(() => {
currentSettings.stoped = true;
variables.container.remove();
variables.container = undefined;
removeTimer = undefined;
}, 3000);
}

updateScene({ opacity: 0 });
currentSettings = {
...defaultSettings,
...(settings?.speed ? { speed: Number(settings.speed) } : {}),
...(settings?.particleLevel ? { particleLevel: Number(settings.particleLevel) } : {}),
paused: settings?.paused || defaultSettings.paused,
};

if (!currentSettings.paused && !variables.container) {
variables.container = createRootElement();
variables.container.appendChild(variables.renderer.domElement);
document.body.append(variables.container);
if (!currentSettings.paused) {
redrawTimer = setTimeout(() => {
updateScene({ opacity: 0 });
setOpacity(1);

cancelRender();
queueRender();
}
redrawTimer = undefined;
if (removeTimer) {
clearTimeout(removeTimer);
removeTimer = undefined;
}

if (!settings?.paused) {
if (removeTimer) {
clearTimeout(removeTimer);
}
if (!variables.container) {
variables.container = createRootElement();
variables.container.appendChild(variables.renderer.domElement);
document.body.append(variables.container);

cancelRender();
queueRender();
}

setOpacity(1);
}, 500);
}
};

Expand Down
42 changes: 18 additions & 24 deletions packages/snow3d/src/logic/updateScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@ import { getWindowDimensions, randomInt, randomIntMax } from './utils';
import { variables } from './variables';

export const updateScene = async ({ opacity }) => {
const { particleLevel, speed, paused, stoped } = getSettings();

if (paused) {
return;
}
const { particleLevel, speed, paused } = getSettings();

const { innerWidth, innerHeight } = getWindowDimensions();

Expand All @@ -20,30 +16,28 @@ export const updateScene = async ({ opacity }) => {
variables.renderer.setSize(innerWidth, innerHeight);
variables.camera.aspect = innerWidth / innerHeight;

if (true) {
const particleNum = ((innerWidth * innerHeight) / 100000) * particleLevel;
const particleNum = Math.min(3000, ((innerWidth * innerHeight) / 100000) * particleLevel);

const vertices = [];
const velocities = [];
const colors = [];
for (let i = 0; i < particleNum; i++) {
const x = randomIntMax(2 * innerWidth) - innerWidth;
const y = randomIntMax(2 * innerHeight) - innerHeight;
const z = randomIntMax(perspertiveLevel);
vertices.push(x, y, z);
const vertices = [];
const velocities = [];
const colors = [];
for (let i = 0; i < particleNum; i++) {
const x = randomIntMax(2 * innerWidth) - innerWidth;
const y = randomIntMax(2 * innerHeight) - innerHeight;
const z = randomIntMax(perspertiveLevel);
vertices.push(x, y, z);

velocities.push(...calcVelocity(speed, randomInt(-65, 65), randomIntMax(270)));
velocities.push(...calcVelocity(speed, randomInt(-65, 65), randomIntMax(270)));

colors.push(opacity, 0);
}
colors.push(opacity, 0);
}

const colorAttribute = new Float32BufferAttribute(colors, 2);
colorAttribute.normalized = true;
const colorAttribute = new Float32BufferAttribute(colors, 2);
colorAttribute.normalized = true;

variables.bufferGeometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
variables.bufferGeometry.setAttribute('velocity', new Float32BufferAttribute(velocities, 3));
variables.bufferGeometry.setAttribute('opacity', colorAttribute);
}
variables.bufferGeometry.setAttribute('position', new Float32BufferAttribute(vertices, 3));
variables.bufferGeometry.setAttribute('velocity', new Float32BufferAttribute(velocities, 3));
variables.bufferGeometry.setAttribute('opacity', colorAttribute);

const targets = getTargets();

Expand Down
3 changes: 0 additions & 3 deletions packages/snow3d/src/logic/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@ export const getWindowDimensions = (): { innerWidth: number; innerHeight: number
export const scrollHeight = (): number =>
Number(document.documentElement.scrollHeight || document.body.scrollHeight);

export const scrollPosition = (): number =>
Number(document.documentElement.scrollTop || document.body.scrollTop);

export const randomInt = (min: number, max: number): number => {
return min + Math.floor(Math.random() * (max - min + 1));
};
Expand Down
3 changes: 3 additions & 0 deletions packages/snow3d/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,6 @@ window['SNOW3D'] = {
start: () => setSettings({ paused: false }),
stop: () => setSettings({ paused: true }),
};

window.addEventListener('focus', window['SNOW3D'].start);
window.addEventListener('blur', window['SNOW3D'].stop);
2 changes: 1 addition & 1 deletion packages/wp-christmas-snow-3d/build/snow3d.asset.php
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<?php return array('dependencies' => array(), 'version' => 'cc4a969e02505d0bca7c');
<?php return array('dependencies' => array(), 'version' => 'cbb216e8b4fa02975b8e');
Loading

0 comments on commit 5a57dd9

Please sign in to comment.