anycoder-c3180613 / index.html
Passakorn43's picture
Upload folder using huggingface_hub
7176381 verified
Raw
History Blame Contribute Delete
21.9 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Ultimate FPS Benchmark</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&family=Orbitron:wght@400;700;900&display=swap" rel="stylesheet">
<!-- Icons -->
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
:root {
--primary: #00f3ff;
--secondary: #bc13fe;
--accent: #ffee00;
--bg-dark: #050507;
--panel-bg: rgba(10, 10, 14, 0.75);
--border: rgba(255, 255, 255, 0.1);
--text-main: #e0e0e0;
--font-display: 'Orbitron', sans-serif;
--font-mono: 'JetBrains Mono', monospace;
--glass: blur(12px) saturate(180%);
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
user-select: none;
}
body {
background-color: var(--bg-dark);
color: var(--text-main);
font-family: var(--font-mono);
overflow: hidden; /* Canvas covers everything */
height: 100vh;
width: 100vw;
}
/* --- Header --- */
header {
position: absolute;
top: 0;
left: 0;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 2rem;
z-index: 100;
pointer-events: none; /* Let clicks pass through to canvas where needed */
}
.brand {
font-family: var(--font-display);
font-size: 1.5rem;
font-weight: 900;
letter-spacing: 2px;
color: white;
text-shadow: 0 0 10px var(--primary);
pointer-events: auto;
}
.brand span {
color: var(--primary);
}
.anycoder-link {
font-family: var(--font-mono);
font-size: 0.8rem;
color: var(--text-main);
text-decoration: none;
background: rgba(255, 255, 255, 0.05);
padding: 8px 16px;
border-radius: 4px;
border: 1px solid var(--border);
transition: all 0.3s ease;
pointer-events: auto;
backdrop-filter: blur(5px);
}
.anycoder-link:hover {
background: rgba(0, 243, 255, 0.15);
border-color: var(--primary);
box-shadow: 0 0 15px rgba(0, 243, 255, 0.3);
color: white;
}
/* --- Main Canvas --- */
#renderCanvas {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
/* --- HUD / Dashboard --- */
.hud-container {
position: absolute;
top: 80px;
left: 2rem;
width: 320px;
z-index: 10;
display: flex;
flex-direction: column;
gap: 1rem;
pointer-events: none;
}
.panel {
background: var(--panel-bg);
backdrop-filter: var(--glass);
-webkit-backdrop-filter: var(--glass);
border: 1px solid var(--border);
border-left: 4px solid var(--primary);
padding: 1.5rem;
border-radius: 4px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.5);
pointer-events: auto;
transition: transform 0.2s;
}
.panel:hover {
border-color: rgba(255,255,255,0.2);
}
.fps-display {
text-align: center;
}
.fps-value {
font-family: var(--font-display);
font-size: 4rem;
font-weight: 900;
line-height: 1;
color: white;
text-shadow: 0 0 20px rgba(0, 243, 255, 0.5);
}
.fps-label {
color: var(--primary);
font-size: 0.9rem;
text-transform: uppercase;
letter-spacing: 4px;
margin-bottom: 10px;
}
.stats-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 10px;
margin-top: 1rem;
border-top: 1px solid var(--border);
padding-top: 1rem;
}
.stat-item {
display: flex;
flex-direction: column;
align-items: center;
}
.stat-item span:first-child {
font-size: 0.7rem;
color: #888;
text-transform: uppercase;
}
.stat-item span:last-child {
font-size: 1.1rem;
font-weight: 700;
color: white;
}
/* --- Graph Panel --- */
.graph-panel {
height: 150px;
display: flex;
flex-direction: column;
padding: 1rem;
}
.graph-title {
font-size: 0.8rem;
color: #aaa;
margin-bottom: 0.5rem;
display: flex;
justify-content: space-between;
}
canvas#fpsGraph {
width: 100%;
height: 100%;
border-bottom: 1px solid var(--border);
border-left: 1px solid var(--border);
}
/* --- Controls --- */
.controls-container {
position: absolute;
bottom: 2rem;
left: 2rem;
right: 2rem;
display: flex;
justify-content: center;
align-items: flex-end;
z-index: 10;
pointer-events: none;
}
.control-panel {
background: var(--panel-bg);
backdrop-filter: var(--glass);
-webkit-backdrop-filter: var(--glass);
border: 1px solid var(--border);
border-top: 4px solid var(--secondary);
padding: 1.5rem 2rem;
border-radius: 12px;
pointer-events: auto;
width: 100%;
max-width: 800px;
display: flex;
flex-direction: column;
gap: 1.5rem;
}
.control-row {
display: flex;
align-items: center;
justify-content: space-between;
gap: 2rem;
flex-wrap: wrap;
}
.slider-group {
flex: 1;
min-width: 200px;
}
.slider-label {
display: flex;
justify-content: space-between;
margin-bottom: 0.5rem;
font-size: 0.9rem;
color: var(--secondary);
font-weight: 700;
}
input[type="range"] {
-webkit-appearance: none;
width: 100%;
height: 6px;
background: rgba(255,255,255,0.1);
border-radius: 3px;
outline: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--secondary);
cursor: pointer;
box-shadow: 0 0 10px var(--secondary);
transition: transform 0.2s;
}
input[type="range"]::-webkit-slider-thumb:hover {
transform: scale(1.2);
}
.btn-group {
display: flex;
gap: 1rem;
}
.btn {
background: transparent;
border: 1px solid var(--border);
color: white;
padding: 10px 20px;
border-radius: 4px;
font-family: var(--font-mono);
cursor: pointer;
transition: all 0.2s;
text-transform: uppercase;
font-size: 0.85rem;
display: flex;
align-items: center;
gap: 8px;
}
.btn:hover {
background: rgba(255,255,255,0.05);
border-color: white;
}
.btn-primary {
background: var(--secondary);
border-color: var(--secondary);
color: black;
font-weight: bold;
}
.btn-primary:hover {
background: #d45aff;
box-shadow: 0 0 15px rgba(188, 19, 254, 0.4);
}
/* --- Responsive --- */
@media (max-width: 768px) {
header {
padding: 1rem;
}
.hud-container {
left: 1rem;
right: 1rem;
width: auto;
top: 70px;
}
.fps-value {
font-size: 3rem;
}
.controls-container {
bottom: 1rem;
left: 1rem;
right: 1rem;
}
.control-panel {
padding: 1rem;
}
.control-row {
flex-direction: column;
align-items: stretch;
gap: 1rem;
}
.btn-group {
justify-content: center;
}
}
</style>
</head>
<body>
<header>
<div class="brand">
<i class="fa-solid fa-bolt"></i> FPS<span>TESTER</span>
</div>
<a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-link">
Built with anycoder
</a>
</header>
<canvas id="renderCanvas"></canvas>
<div class="hud-container">
<!-- FPS Panel -->
<div class="panel">
<div class="fps-display">
<div class="fps-label">Current FPS</div>
<div class="fps-value" id="fpsDisplay">00</div>
</div>
<div class="stats-grid">
<div class="stat-item">
<span>Avg</span>
<span id="avgFps">0</span>
</div>
<div class="stat-item">
<span>Min 1%</span>
<span id="minFps">0</span>
</div>
<div class="stat-item">
<span>Objects</span>
<span id="objCount">0</span>
</div>
<div class="stat-item">
<span>Res</span>
<span id="resDisplay">1080p</span>
</div>
</div>
</div>
<!-- Graph Panel -->
<div class="panel graph-panel">
<div class="graph-title">
<span>FPS HISTORY</span>
<span style="color:var(--primary)">60s</span>
</div>
<canvas id="fpsGraph"></canvas>
</div>
</div>
<div class="controls-container">
<div class="control-panel">
<div class="control-row">
<div class="slider-group">
<div class="slider-label">
<span><i class="fa-solid fa-cubes"></i> STRESS LEVEL (Particles)</span>
<span id="sliderValue">1000</span>
</div>
<input type="range" id="particleSlider" min="100" max="20000" step="100" value="1000">
</div>
</div>
<div class="control-row">
<div class="btn-group">
<button class="btn" id="togglePhysics"><i class="fa-solid fa-magnet"></i> Physics</button>
<button class="btn" id="toggleTrails"><i class="fa-solid fa-wind"></i> Trails</button>
</div>
<button class="btn btn-primary" id="resetBtn"><i class="fa-solid fa-rotate-right"></i> Reset Stats</button>
</div>
</div>
</div>
<script>
/**
* FPS TESTER APPLICATION
*
* Logic:
* 1. Render Loop: Uses requestAnimationFrame.
* 2. Particle System: Spawns objects to stress the GPU/CPU.
* 3. Monitoring: Calculates frame delta time to determine FPS.
*/
class ParticleSystem {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext('2d', { alpha: false }); // Optimize for speed
this.particles = [];
this.physicsEnabled = true;
this.trailsEnabled = false;
this.colors = ['#00f3ff', '#bc13fe', '#ffee00', '#ffffff'];
this.resize();
window.addEventListener('resize', () => this.resize());
}
resize() {
this.width = window.innerWidth;
this.height = window.innerHeight;
this.canvas.width = this.width;
this.canvas.height = this.height;
document.getElementById('resDisplay').innerText = `${this.width}x${this.height}`;
}
createParticle() {
const size = Math.random() * 3 + 1;
return {
x: Math.random() * this.width,
y: Math.random() * this.height,
vx: (Math.random() - 0.5) * 4,
vy: (Math.random() - 0.5) * 4,
size: size,
color: this.colors[Math.floor(Math.random() * this.colors.length)],
history: []
};
}
updateCount(count) {
const currentLen = this.particles.length;
if (count > currentLen) {
for (let i = 0; i < count - currentLen; i++) {
this.particles.push(this.createParticle());
}
} else {
this.particles.length = count;
}
document.getElementById('objCount').innerText = this.particles.length.toLocaleString();
}
render() {
// Clear Canvas (or create trail effect)
if (this.trailsEnabled) {
this.ctx.fillStyle = 'rgba(5, 5, 7, 0.2)'; // Trail fade
this.ctx.fillRect(0, 0, this.width, this.height);
} else {
this.ctx.fillStyle = '#050507';
this.ctx.fillRect(0, 0, this.width, this.height);
}
this.ctx.lineWidth = 1;
for (let i = 0; i < this.particles.length; i++) {
let p = this.particles[i];
// Physics Update
if (this.physicsEnabled) {
p.x += p.vx;
p.y += p.vy;
// Boundary Check
if (p.x < 0 || p.x > this.width) p.vx *= -1;
if (p.y < 0 || p.y > this.height) p.vy *= -1;
}
// Render
this.ctx.fillStyle = p.color;
this.ctx.beginPath();
this.ctx.arc(p.x, p.y, p.size, 0, Math.PI * 2);
this.ctx.fill();
}
}
}
class FPSMonitor {
constructor() {
this.fpsDisplay = document.getElementById('fpsDisplay');
this.avgDisplay = document.getElementById('avgFps');
this.minDisplay = document.getElementById('minFps');
this.frames = 0;
this.lastTime = performance.now();
this.fpsHistory = [];
this.minHistory = [];
// Graph setup
this.graphCanvas = document.getElementById('fpsGraph');
this.graphCtx = this.graphCanvas.getContext('2d');
this.graphData = new Array(60).fill(0); // 60 data points
this.resizeGraph();
window.addEventListener('resize', () => this.resizeGraph());
// Reset logic
this.startTime = performance.now();
this.totalFrames = 0;
}
resizeGraph() {
const rect = this.graphCanvas.parentElement.getBoundingClientRect();
this.graphCanvas.width = rect.width - 32; // padding adjustment
this.graphCanvas.height = rect.height - 30;
}
reset() {
this.fpsHistory = [];
this.minHistory = [];
this.totalFrames = 0;
this.startTime = performance.now();
this.graphData.fill(0);
this.updateUI(0, 0, 0);
}
update() {
const now = performance.now();
this.frames++;
this.totalFrames++;
if (now >= this.lastTime + 1000) {
const fps = Math.round((this.frames * 1000) / (now - this.lastTime));
this.fpsHistory.push(fps);
if (this.fpsHistory.length > 60) this.fpsHistory.shift();
// Calculate Stats
const avg = Math.round((this.totalFrames * 1000) / (now - this.startTime));
const min = Math.min(...this.fpsHistory);
this.updateUI(fps, avg, min);
this.updateGraph(fps);
this.frames = 0;
this.lastTime = now;
}
}
updateUI(fps, avg, min) {
this.fpsDisplay.innerText = fps;
this.avgDisplay.innerText = avg;
this.minDisplay.innerText = min;
// Color coding
if(fps >= 55) this.fpsDisplay.style.color = '#00f3ff'; // Good
else if(fps >= 30) this.fpsDisplay.style.color = '#ffee00'; // Warning
else this.fpsDisplay.style.color = '#ff0055'; // Bad
}
updateGraph(currentFps) {
this.graphData.shift();
this.graphData.push(currentFps);
const ctx = this.graphCtx;
const w = this.graphCanvas.width;
const h = this.graphCanvas.height;
ctx.clearRect(0, 0, w, h);
// Draw Guide Lines
ctx.strokeStyle = '#333';
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, h/2);
ctx.lineTo(w, h/2); // 30 FPS line roughly
ctx.stroke();
// Draw Graph
ctx.strokeStyle = '#00f3ff';
ctx.lineWidth = 2;
ctx.beginPath();
const step = w / (this.graphData.length - 1);
const maxVal = 144; // Normalize to 144hz for visual scaling
for (let i = 0; i < this.graphData.length; i++) {
const val = this.graphData[i];
const y = h - (Math.min(val, maxVal) / maxVal) * h;
if (i === 0) ctx.moveTo(0, y);
else ctx.lineTo(i * step, y);
}
ctx.stroke();
// Fill gradient under
ctx.lineTo(w, h);
ctx.lineTo(0, h);
ctx.closePath();
const grad = ctx.createLinearGradient(0, 0, 0, h);
grad.addColorStop(0, 'rgba(0, 243, 255, 0.2)');
grad.addColorStop(1, 'rgba(0, 243, 255, 0)');
ctx.fillStyle = grad;
ctx.fill();
}
}
// --- Init ---
const canvas = document.getElementById('renderCanvas');
const particleSystem = new ParticleSystem(canvas);
const fpsMonitor = new FPSMonitor();
// UI Inputs
const slider = document.getElementById('particleSlider');
const sliderVal = document.getElementById('sliderValue');
const resetBtn = document.getElementById('resetBtn');
const physicsBtn = document.getElementById('togglePhysics');
const trailsBtn = document.getElementById('toggleTrails');
// Initial Load
particleSystem.updateCount(parseInt(slider.value));
// Event Listeners
slider.addEventListener('input', (e) => {
const val = parseInt(e.target.value);
sliderVal.innerText = val.toLocaleString();
particleSystem.updateCount(val);
});
resetBtn.addEventListener('click', () => {
fpsMonitor.reset();
});
physicsBtn.addEventListener('click', (e) => {
particleSystem.physicsEnabled = !particleSystem.physicsEnabled;
e.currentTarget.classList.toggle('btn-primary');
e.currentTarget.style.borderColor = particleSystem.physicsEnabled ? 'var(--border)' : '#555';
e.currentTarget.style.opacity = particleSystem.physicsEnabled ? '1' : '0.5';
});
trailsBtn.addEventListener('click', (e) => {
particleSystem.trailsEnabled = !particleSystem.trailsEnabled;
e.currentTarget.classList.toggle('btn-primary');
});
// Main Loop
function animate() {
particleSystem.render();
fpsMonitor.update();
requestAnimationFrame(animate);
}
animate();
</script>
</body>
</html>