Add improvements
This commit is contained in:
parent
8a33293647
commit
05f4e08ad1
13 changed files with 185 additions and 76 deletions
|
|
@ -8,10 +8,12 @@ export const extractInsights = (
|
|||
fps?: number;
|
||||
renderScale?: number;
|
||||
lightScale?: number;
|
||||
version?: string;
|
||||
} => ({
|
||||
fps: insights?.fps,
|
||||
vendor: insights?.vendor,
|
||||
renderer: insights?.renderer,
|
||||
renderScale: insights?.renderPasses.distance.renderScale,
|
||||
lightScale: insights?.renderPasses.lights.renderScale,
|
||||
version: insights?.sdf2dVersion,
|
||||
});
|
||||
|
|
|
|||
48
src/helper/handle-full-screen.ts
Normal file
48
src/helper/handle-full-screen.ts
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
export const handleFullScreen = (
|
||||
minimizeButton: HTMLElement,
|
||||
maximizeButton: HTMLElement,
|
||||
target: HTMLElement
|
||||
) => {
|
||||
if (!document.fullscreenEnabled) {
|
||||
minimizeButton.style.visibility = 'hidden';
|
||||
maximizeButton.style.visibility = 'hidden';
|
||||
return;
|
||||
}
|
||||
|
||||
const isInFullScreen = (): boolean => document.fullscreenElement !== null;
|
||||
|
||||
const showButtons = () => {
|
||||
minimizeButton.style.visibility = isInFullScreen() ? 'visible' : 'hidden';
|
||||
maximizeButton.style.visibility = isInFullScreen() ? 'hidden' : 'visible';
|
||||
};
|
||||
|
||||
showButtons();
|
||||
|
||||
let currentWindowHeight = innerHeight;
|
||||
|
||||
const followToggle = () => {
|
||||
showButtons();
|
||||
currentWindowHeight = innerHeight;
|
||||
};
|
||||
|
||||
const triggerToggle = async () => {
|
||||
await (isInFullScreen() ? document.exitFullscreen() : target.requestFullscreen());
|
||||
followToggle();
|
||||
};
|
||||
|
||||
addEventListener('keydown', (e) => {
|
||||
if (e.key === 'F11') {
|
||||
triggerToggle();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
addEventListener('resize', () => {
|
||||
if (isInFullScreen && currentWindowHeight > innerHeight) {
|
||||
followToggle();
|
||||
}
|
||||
});
|
||||
|
||||
maximizeButton.addEventListener('click', triggerToggle);
|
||||
minimizeButton.addEventListener('click', triggerToggle);
|
||||
};
|
||||
|
|
@ -2,8 +2,12 @@ const baseUri = 'https://insights.decla.red';
|
|||
const type = 'sdf-2d-demo';
|
||||
|
||||
export const handleInsights = async (initialData: any): Promise<(data: any) => void> => {
|
||||
const sessionId = await createSession(initialData);
|
||||
return (data) => createFrame(sessionId, data);
|
||||
try {
|
||||
const sessionId = await createSession(initialData);
|
||||
return (data) => createFrame(sessionId, data);
|
||||
} catch {
|
||||
return () => null;
|
||||
}
|
||||
};
|
||||
|
||||
const createSession = async (data: any): Promise<string> => {
|
||||
|
|
@ -12,8 +16,8 @@ const createSession = async (data: any): Promise<string> => {
|
|||
return sessionId;
|
||||
};
|
||||
|
||||
const createFrame = async (sessionId: string, data: any): Promise<unknown> =>
|
||||
await sendPostRequest(`${baseUri}/${type}/sessions/${sessionId}`, data);
|
||||
const createFrame = (sessionId: string, data: any): Promise<unknown> =>
|
||||
sendPostRequest(`${baseUri}/${type}/sessions/${sessionId}`, data).catch();
|
||||
|
||||
const sendPostRequest = async (uri: string, data: any): Promise<Response> =>
|
||||
await fetch(uri, {
|
||||
|
|
|
|||
|
|
@ -33,20 +33,41 @@
|
|||
<h1>Javascript is required for this website.</h1>
|
||||
</noscript>
|
||||
|
||||
<main id="canvas-container">
|
||||
<canvas></canvas>
|
||||
|
||||
<div id="errors-container">
|
||||
<div id="errors">
|
||||
<h1>Encountered an error</h1>
|
||||
<p id="error-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img
|
||||
src="../static/minimize.svg"
|
||||
alt="minimize"
|
||||
id="minimize"
|
||||
class="full-screen-control"
|
||||
/>
|
||||
<img
|
||||
src="../static/maximize.svg"
|
||||
alt="maximize"
|
||||
id="maximize"
|
||||
class="full-screen-control"
|
||||
/>
|
||||
</main>
|
||||
|
||||
<a id="info" href="https://github.com/schmelczerandras/sdf-2d" target="_BLANK">
|
||||
<p>SDF-2D</p>
|
||||
<img width="64" height="64" src="logo-white.svg" alt="logo" />
|
||||
<img
|
||||
class="logo"
|
||||
width="64"
|
||||
height="64"
|
||||
src="../static/logo-white.svg"
|
||||
alt="logo"
|
||||
/>
|
||||
</a>
|
||||
<code id="overlay"></code>
|
||||
<button id="toggle-text">Loading…</button>
|
||||
|
||||
<canvas id="main"></canvas>
|
||||
|
||||
<div id="errors-container">
|
||||
<div id="errors">
|
||||
<h1>Encountered an error</h1>
|
||||
<p id="error-text"></p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
17
src/index.ts
17
src/index.ts
|
|
@ -6,10 +6,12 @@ import '../static/favicons/favicon-32x32.png';
|
|||
import '../static/favicons/favicon.ico';
|
||||
import '../static/logo-white.svg';
|
||||
import '../static/no-change/404.html';
|
||||
import '../static/no-change/og-image.png';
|
||||
import '../static/no-change/robots.txt';
|
||||
import '../static/og-image.png';
|
||||
import { extractInsights } from './helper/extract-insights';
|
||||
import { handleFullScreen } from './helper/handle-full-screen';
|
||||
import { handleInsights } from './helper/handle-insights';
|
||||
import { Random } from './helper/random';
|
||||
import { removeUnnecessaryOutlines } from './helper/remove-unnecessary-outlines';
|
||||
import { BlobScene } from './scenes/blob/blob-scene';
|
||||
import { MetaballScene } from './scenes/metaball/metaball-scene';
|
||||
|
|
@ -18,14 +20,18 @@ import { TunnelScene } from './scenes/tunnel-scene';
|
|||
import './styles/index.scss';
|
||||
|
||||
const scenes = [TunnelScene, MetaballScene, RainScene, BlobScene];
|
||||
Random.seed = 2;
|
||||
|
||||
glMatrix.setMatrixArrayType(Array);
|
||||
removeUnnecessaryOutlines();
|
||||
|
||||
const canvas = document.querySelector('canvas') as HTMLCanvasElement;
|
||||
const canvasContainer = document.querySelector('#canvas-container') as HTMLCanvasElement;
|
||||
const errorText = document.querySelector('#error-text') as HTMLParamElement;
|
||||
const errorsContainer = document.querySelector('#errors-container') as HTMLDivElement;
|
||||
const toggleButton = document.querySelector('#toggle-text');
|
||||
const minimizeButton = document.querySelector('#minimize') as HTMLElement;
|
||||
const maximizeButton = document.querySelector('#maximize') as HTMLElement;
|
||||
const overlay = document.querySelector('#overlay') as HTMLDivElement;
|
||||
|
||||
let textVisible = true;
|
||||
|
|
@ -43,18 +49,25 @@ toggleButton.addEventListener('click', handleTextToggle);
|
|||
handleTextToggle();
|
||||
|
||||
const startInsightsSession = async (): Promise<(data: any) => unknown> => {
|
||||
const { vendor, renderer } = extractInsights((await compile(canvas, [])).insights);
|
||||
const dummyRenderer = await compile(document.createElement('canvas'), []);
|
||||
const { vendor, renderer, version } = extractInsights(dummyRenderer.insights);
|
||||
dummyRenderer.destroy();
|
||||
|
||||
return await handleInsights({
|
||||
vendor,
|
||||
renderer,
|
||||
referrer: document.referrer,
|
||||
connection: (navigator as any)?.connection?.effectiveType,
|
||||
devicePixelRatio: devicePixelRatio,
|
||||
height: innerHeight,
|
||||
width: innerWidth,
|
||||
version,
|
||||
});
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const sendFramePromise = startInsightsSession();
|
||||
handleFullScreen(minimizeButton, maximizeButton, canvasContainer);
|
||||
|
||||
try {
|
||||
let i = 0;
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ export class BlobScene implements Scene {
|
|||
Blob.descriptor,
|
||||
],
|
||||
this.drawNextFrame.bind(this),
|
||||
{},
|
||||
{
|
||||
ambientLight: rgb255(89, 25, 115),
|
||||
enableHighDpiRendering: true,
|
||||
|
|
@ -65,6 +64,8 @@ export class BlobScene implements Scene {
|
|||
|
||||
const q = (currentTime % 8000) / 4300;
|
||||
this.blob.animate(currentTime);
|
||||
this.blob.position = [width / 2, -length / 4 + length / 2];
|
||||
|
||||
[
|
||||
new Circle([width / 2, -length / 4], length / 2),
|
||||
this.blob,
|
||||
|
|
|
|||
|
|
@ -120,8 +120,6 @@ export class Blob extends Drawable {
|
|||
Math.sin((q > 1 ? q - 1 : 0) * Math.PI) * 10
|
||||
)
|
||||
);
|
||||
|
||||
this.position = this.center;
|
||||
}
|
||||
|
||||
public minDistance(target: vec2): number {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ export class MetaballScene implements Scene {
|
|||
},
|
||||
],
|
||||
this.drawNextFrame.bind(this),
|
||||
{},
|
||||
{
|
||||
ambientLight: rgb(0.1, 0.1, 0.3),
|
||||
enableHighDpiRendering: true,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
import { ReadonlyVec2, vec2 } from 'gl-matrix';
|
||||
import { DropletFactory, rgb } from 'sdf-2d';
|
||||
import { DropletFactory, rgb255 } from 'sdf-2d';
|
||||
import { Random } from '../../helper/random';
|
||||
|
||||
export const Droplet = DropletFactory(rgb(0.3, 1, 1));
|
||||
export const Droplet = DropletFactory(rgb255(122, 122, 255));
|
||||
export class DropletWrapper {
|
||||
public readonly drawable: InstanceType<typeof Droplet>;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ import { Droplet, DropletWrapper } from './droplet';
|
|||
|
||||
export class RainScene implements Scene {
|
||||
private droplets: Array<DropletWrapper> = [];
|
||||
private light1: CircleLight = new CircleLight(vec2.create(), rgb255(184, 41, 255), 2);
|
||||
private light2: CircleLight = new CircleLight(vec2.create(), rgb255(255, 31, 109), 2);
|
||||
private light1: CircleLight = new CircleLight(vec2.create(), rgb255(184, 41, 255), 1.5);
|
||||
private light2: CircleLight = new CircleLight(vec2.create(), rgb255(255, 31, 109), 1.5);
|
||||
|
||||
private overlay: HTMLDivElement;
|
||||
public insights?: any;
|
||||
|
|
@ -32,8 +32,8 @@ export class RainScene implements Scene {
|
|||
},
|
||||
],
|
||||
this.drawNextFrame.bind(this),
|
||||
{},
|
||||
{
|
||||
backgroundColor: rgb(0.5, 0.5, 0.5),
|
||||
ambientLight: rgb(0.2, 0.2, 0.2),
|
||||
enableHighDpiRendering: true,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -70,12 +70,12 @@ export class TunnelScene implements Scene {
|
|||
}
|
||||
|
||||
public async run(canvas: HTMLCanvasElement, overlay: HTMLDivElement): Promise<void> {
|
||||
const noiseTexture = await renderNoise([1024, 1], 15, 1);
|
||||
const noiseTexture = await renderNoise([1024, 1], 15, 0.5);
|
||||
|
||||
this.canvas = canvas;
|
||||
this.overlay = overlay;
|
||||
|
||||
for (let i = 0; i < 200; i++) {
|
||||
for (let i = 0; i < 30; i++) {
|
||||
this.generateTunnel();
|
||||
}
|
||||
|
||||
|
|
@ -92,8 +92,8 @@ export class TunnelScene implements Scene {
|
|||
},
|
||||
],
|
||||
this.drawNextFrame.bind(this),
|
||||
{ lightPenetrationRatio: 0.5 },
|
||||
{
|
||||
lightPenetrationRatio: 0.5,
|
||||
isWorldInverted: true,
|
||||
enableHighDpiRendering: true,
|
||||
ambientLight: rgb(0.35, 0.1, 0.45),
|
||||
|
|
@ -123,7 +123,7 @@ export class TunnelScene implements Scene {
|
|||
const height = renderer.canvasSize.y;
|
||||
|
||||
this.deltaSinceStart += deltaTime;
|
||||
const startX = this.deltaSinceStart / 3;
|
||||
const startX = this.deltaSinceStart / 4;
|
||||
const endX = startX + width;
|
||||
renderer.setViewArea(vec2.fromValues(startX, height), vec2.fromValues(width, height));
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
export const settings = {
|
||||
sceneTimeInMilliseconds: 7000,
|
||||
sceneTimeInMilliseconds: 8000,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ $breakpoint: 800px;
|
|||
}
|
||||
|
||||
html,
|
||||
body,
|
||||
canvas#main {
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
|
|
@ -50,7 +49,7 @@ body {
|
|||
padding-top: 2px;
|
||||
}
|
||||
|
||||
img {
|
||||
.logo {
|
||||
@include square(64px);
|
||||
padding-left: 8px;
|
||||
}
|
||||
|
|
@ -58,12 +57,33 @@ body {
|
|||
@media (max-width: $breakpoint) {
|
||||
font-size: 2rem;
|
||||
|
||||
img {
|
||||
.logo {
|
||||
@include square(40px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#canvas-container {
|
||||
&,
|
||||
canvas {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.full-screen-control {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
box-sizing: content-box;
|
||||
@include square(40px);
|
||||
padding: 16px;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
#overlay {
|
||||
right: 0;
|
||||
white-space: pre-wrap;
|
||||
|
|
|
|||
Loading…
Reference in a new issue