Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 48 additions & 9 deletions content/javascripts/hero.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/**
* This script applies to index.md.
*/
"use strict";
(async () => {
// DOM guard
// if (!document.querySelector(".hero-page"))
Expand Down Expand Up @@ -87,29 +88,67 @@
const iResolutionLoc = gl.getUniformLocation(program, "iResolution");
const iTimeLoc = gl.getUniformLocation(program, "iTime");

const isMobile = window.matchMedia("(pointer: coarse)").matches && !window.matchMedia("(hover: hover)").matches;
const targetMobileDeltaTime = 33.33; // 33.33ms ~ 30 FPS
const targetDesktopDeltaTime = 16.67; // 16.67ms ~ 60 FPS

let lastFrameTime = 0;
let renderQuality = 1.0; // Full desktop quality by default

function determineBestRenderQuality()
{
const start = performance.now();
render(0.0)
const deltaTime = performance.now() - start;

if (deltaTime > 16)
renderQuality = 0.4; // Low quality, 40% resolution
else if (deltaTime > 8)
renderQuality = 0.7; // Medium quality, 70% resolution
else
renderQuality = 1.0; // High quality, full resolution

console.log("Using render quality: %f", renderQuality);
}

// Render loop
function frame(time)
{
// Lock framerate to 30 FPS on mobile, and 60 FPS for desktop
const targetDeltaTime = isMobile ? targetMobileDeltaTime : targetDesktopDeltaTime;

// Framerate limiting
if ((time - lastFrameTime) >= targetDeltaTime)
{
lastFrameTime = time;
render(time);
}

requestAnimationFrame(frame);
}

function render(time)
{
// Resize handling (High-DPI / Retina aware)
const dpr = Math.min(window.devicePixelRatio || 1, 1.25); // Clamp resolution on mobile

const displayWidth = Math.floor(canvas.clientWidth * dpr);
const displayHeight = Math.floor(canvas.clientHeight * dpr);

if ((canvas.width !== displayWidth) || (canvas.height !== displayHeight))
{
canvas.width = displayWidth;
canvas.height = displayHeight;
gl.viewport(0, 0, canvas.width, canvas.height);
}
// NOTE: Previously, this was conditionally resized based on:
// if ((canvas.width !== displayWidth) || (canvas.height !== displayHeight))
// But we removed this to make renderQuality updates easier. This system doesn't need anymore complexity!
canvas.width = displayWidth * renderQuality;
canvas.height = displayHeight * renderQuality;

gl.viewport(0, 0, canvas.width, canvas.height);
gl.uniform3f(iResolutionLoc, canvas.width, canvas.height, 1.0);
gl.uniform1f(iTimeLoc, time * 0.001); // Convert time to seconds

gl.drawArrays(gl.TRIANGLES, 0, 6);
requestAnimationFrame(render);
}

determineBestRenderQuality();

// Start the render loop
requestAnimationFrame(render);
requestAnimationFrame(frame);
})();