ips-panel-simulator / index.html
PrinzPesia's picture
Es soll sich eine IPS Panel Simulator haben, also von der alle mögliche Technische verhalten - Initial Deployment
d799f96 verified
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>IPS Panel Simulator</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
.panel {
background: linear-gradient(135deg, #1a202c, #2d3748);
box-shadow: 0 0 30px rgba(0, 0, 0, 0.5);
border-radius: 15px;
overflow: hidden;
position: relative;
transition: all 0.3s ease;
}
.pixel {
position: absolute;
border-radius: 2px;
transition: all 0.1s ease;
}
.glow-effect {
box-shadow: 0 0 10px 2px rgba(59, 130, 246, 0.7);
}
.dead-pixel {
background-color: black !important;
}
.stuck-pixel {
background-color: white !important;
}
@keyframes flicker {
0% { opacity: 1; }
50% { opacity: 0.5; }
100% { opacity: 1; }
}
.flickering {
animation: flicker 0.1s infinite;
}
@keyframes imageRetention {
0% { opacity: 0.1; }
50% { opacity: 0.3; }
100% { opacity: 0.1; }
}
.image-retention {
animation: imageRetention 2s infinite;
}
.backlight-bleed {
position: absolute;
border-radius: 50%;
filter: blur(20px);
opacity: 0.3;
}
</style>
</head>
<body class="bg-gray-900 text-gray-100 min-h-screen">
<div class="container mx-auto px-4 py-8">
<h1 class="text-4xl font-bold text-center mb-8 text-blue-400">IPS Panel Simulator</h1>
<div class="grid grid-cols-1 lg:grid-cols-3 gap-8">
<!-- Main Panel Display -->
<div class="lg:col-span-2">
<div class="panel relative" style="width: 100%; aspect-ratio: 16/9;" id="displayPanel">
<!-- Pixels will be generated here by JavaScript -->
</div>
<div class="mt-4 flex flex-wrap gap-4 justify-center">
<button id="testPatternBtn" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded-lg transition">
<i class="fas fa-image mr-2"></i> Test Pattern
</button>
<button id="colorWashBtn" class="bg-purple-600 hover:bg-purple-700 text-white px-4 py-2 rounded-lg transition">
<i class="fas fa-palette mr-2"></i> Color Wash
</button>
<button id="grayScaleBtn" class="bg-gray-600 hover:bg-gray-700 text-white px-4 py-2 rounded-lg transition">
<i class="fas fa-sliders-h mr-2"></i> Gray Scale
</button>
<button id="resetBtn" class="bg-green-600 hover:bg-green-700 text-white px-4 py-2 rounded-lg transition">
<i class="fas fa-redo mr-2"></i> Reset
</button>
</div>
</div>
<!-- Control Panel -->
<div class="bg-gray-800 rounded-xl p-6">
<h2 class="text-2xl font-semibold mb-4 text-blue-300">Panel Controls</h2>
<div class="space-y-6">
<!-- Brightness Control -->
<div>
<label class="block text-sm font-medium mb-2">Brightness</label>
<input type="range" id="brightnessSlider" min="0" max="100" value="80" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
<div class="flex justify-between text-xs text-gray-400 mt-1">
<span>0%</span>
<span id="brightnessValue">80%</span>
<span>100%</span>
</div>
</div>
<!-- Contrast Control -->
<div>
<label class="block text-sm font-medium mb-2">Contrast</label>
<input type="range" id="contrastSlider" min="0" max="100" value="50" class="w-full h-2 bg-gray-700 rounded-lg appearance-none cursor-pointer">
<div class="flex justify-between text-xs text-gray-400 mt-1">
<span>0%</span>
<span id="contrastValue">50%</span>
<span>100%</span>
</div>
</div>
<!-- Defect Simulation -->
<div>
<label class="block text-sm font-medium mb-2">Defect Simulation</label>
<div class="grid grid-cols-2 gap-2">
<button id="deadPixelBtn" class="bg-red-600 hover:bg-red-700 text-white px-3 py-1 rounded text-sm transition">
Dead Pixel
</button>
<button id="stuckPixelBtn" class="bg-yellow-600 hover:bg-yellow-700 text-white px-3 py-1 rounded text-sm transition">
Stuck Pixel
</button>
<button id="backlightBleedBtn" class="bg-indigo-600 hover:bg-indigo-700 text-white px-3 py-1 rounded text-sm transition">
Backlight Bleed
</button>
<button id="imageRetentionBtn" class="bg-pink-600 hover:bg-pink-700 text-white px-3 py-1 rounded text-sm transition">
Image Retention
</button>
</div>
</div>
<!-- Viewing Angle -->
<div>
<label class="block text-sm font-medium mb-2">Viewing Angle</label>
<div class="flex space-x-2">
<button id="angle0Btn" class="bg-gray-700 hover:bg-gray-600 text-white px-3 py-1 rounded text-sm transition">
<i class="fas fa-eye mr-1"></i>
</button>
<button id="angle30Btn" class="bg-gray-700 hover:bg-gray-600 text-white px-3 py-1 rounded text-sm transition">
<i class="fas fa-eye mr-1"></i> 30°
</button>
<button id="angle45Btn" class="bg-gray-700 hover:bg-gray-600 text-white px-3 py-1 rounded text-sm transition">
<i class="fas fa-eye mr-1"></i> 45°
</button>
<button id="angle60Btn" class="bg-gray-700 hover:bg-gray-600 text-white px-3 py-1 rounded text-sm transition">
<i class="fas fa-eye mr-1"></i> 60°
</button>
</div>
</div>
<!-- Response Time -->
<div>
<label class="block text-sm font-medium mb-2">Response Time</label>
<div class="flex space-x-2">
<button id="fastResponseBtn" class="bg-green-700 hover:bg-green-600 text-white px-3 py-1 rounded text-sm transition">
Fast (1ms)
</button>
<button id="mediumResponseBtn" class="bg-yellow-700 hover:bg-yellow-600 text-white px-3 py-1 rounded text-sm transition">
Medium (5ms)
</button>
<button id="slowResponseBtn" class="bg-red-700 hover:bg-red-600 text-white px-3 py-1 rounded text-sm transition">
Slow (10ms)
</button>
</div>
</div>
<!-- Color Gamut -->
<div>
<label class="block text-sm font-medium mb-2">Color Gamut</label>
<div class="flex space-x-2">
<button id="srgbBtn" class="bg-blue-700 hover:bg-blue-600 text-white px-3 py-1 rounded text-sm transition">
sRGB
</button>
<button id="adobeRgbBtn" class="bg-purple-700 hover:bg-purple-600 text-white px-3 py-1 rounded text-sm transition">
Adobe RGB
</button>
<button id="dciP3Btn" class="bg-pink-700 hover:bg-pink-600 text-white px-3 py-1 rounded text-sm transition">
DCI-P3
</button>
</div>
</div>
</div>
</div>
</div>
<!-- Technical Specifications -->
<div class="mt-12 bg-gray-800 rounded-xl p-6">
<h2 class="text-2xl font-semibold mb-4 text-blue-300">Technical Specifications</h2>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="bg-gray-700 p-4 rounded-lg">
<h3 class="text-lg font-medium mb-2 text-blue-200">Display Characteristics</h3>
<ul class="space-y-1 text-sm">
<li><span class="font-medium">Panel Type:</span> IPS (In-Plane Switching)</li>
<li><span class="font-medium">Resolution:</span> 1920x1080 (Full HD)</li>
<li><span class="font-medium">Refresh Rate:</span> 60Hz (variable)</li>
<li><span class="font-medium">Response Time:</span> 5ms (GTG)</li>
<li><span class="font-medium">Viewing Angles:</span> 178°/178°</li>
</ul>
</div>
<div class="bg-gray-700 p-4 rounded-lg">
<h3 class="text-lg font-medium mb-2 text-blue-200">Color Performance</h3>
<ul class="space-y-1 text-sm">
<li><span class="font-medium">Color Gamut:</span> 100% sRGB</li>
<li><span class="font-medium">Color Depth:</span> 8-bit (16.7M colors)</li>
<li><span class="font-medium">Contrast Ratio:</span> 1000:1</li>
<li><span class="font-medium">Brightness:</span> 300 cd/m²</li>
<li><span class="font-medium">HDR:</span> HDR10 compatible</li>
</ul>
</div>
<div class="bg-gray-700 p-4 rounded-lg">
<h3 class="text-lg font-medium mb-2 text-blue-200">Connectivity</h3>
<ul class="space-y-1 text-sm">
<li><span class="font-medium">Inputs:</span> 2x HDMI 2.0, 1x DisplayPort 1.4</li>
<li><span class="font-medium">USB Hub:</span> 4x USB 3.0</li>
<li><span class="font-medium">Audio:</span> 3.5mm headphone jack</li>
<li><span class="font-medium">Power:</span> 100-240V AC</li>
<li><span class="font-medium">Consumption:</span> 30W typical</li>
</ul>
</div>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const panel = document.getElementById('displayPanel');
const panelWidth = panel.clientWidth;
const panelHeight = panel.clientHeight;
// Create a grid of pixels (simplified for performance)
const pixelSize = 5; // Size of each "pixel"
const cols = Math.floor(panelWidth / pixelSize);
const rows = Math.floor(panelHeight / pixelSize);
let pixels = [];
function createPixelGrid() {
panel.innerHTML = '';
pixels = [];
for (let y = 0; y < rows; y++) {
for (let x = 0; x < cols; x++) {
const pixel = document.createElement('div');
pixel.className = 'pixel';
pixel.style.width = `${pixelSize}px`;
pixel.style.height = `${pixelSize}px`;
pixel.style.left = `${x * pixelSize}px`;
pixel.style.top = `${y * pixelSize}px`;
pixel.style.backgroundColor = '#1a202c';
panel.appendChild(pixel);
pixels.push(pixel);
}
}
}
createPixelGrid();
// Test Pattern
document.getElementById('testPatternBtn').addEventListener('click', function() {
const testColors = [
'#FF0000', '#00FF00', '#0000FF', '#FFFF00', '#FF00FF', '#00FFFF',
'#FFFFFF', '#000000', '#808080', '#FFA500', '#800080', '#008000'
];
const blockWidth = cols / 6;
const blockHeight = rows / 2;
pixels.forEach((pixel, index) => {
const x = index % cols;
const y = Math.floor(index / cols);
const blockX = Math.floor(x / blockWidth);
const blockY = Math.floor(y / blockHeight);
const colorIndex = blockX + blockY * 6;
if (colorIndex < testColors.length) {
pixel.style.backgroundColor = testColors[colorIndex];
}
});
});
// Color Wash
document.getElementById('colorWashBtn').addEventListener('click', function() {
let hue = 0;
const colorWashInterval = setInterval(() => {
hue = (hue + 1) % 360;
const color = `hsl(${hue}, 100%, 50%)`;
pixels.forEach(pixel => {
pixel.style.backgroundColor = color;
});
}, 50);
// Stop after 5 seconds
setTimeout(() => {
clearInterval(colorWashInterval);
}, 5000);
});
// Gray Scale
document.getElementById('grayScaleBtn').addEventListener('click', function() {
const steps = 16;
const blockWidth = cols / steps;
pixels.forEach((pixel, index) => {
const x = index % cols;
const step = Math.floor(x / blockWidth);
const grayValue = Math.floor(255 * (step / (steps - 1)));
pixel.style.backgroundColor = `rgb(${grayValue}, ${grayValue}, ${grayValue})`;
});
});
// Reset
document.getElementById('resetBtn').addEventListener('click', function() {
createPixelGrid();
panel.style.filter = 'none';
panel.querySelectorAll('.backlight-bleed').forEach(el => el.remove());
});
// Brightness Control
const brightnessSlider = document.getElementById('brightnessSlider');
const brightnessValue = document.getElementById('brightnessValue');
brightnessSlider.addEventListener('input', function() {
const value = this.value;
brightnessValue.textContent = `${value}%`;
panel.style.filter = `brightness(${value / 100}) contrast(${document.getElementById('contrastSlider').value / 100})`;
});
// Contrast Control
const contrastSlider = document.getElementById('contrastSlider');
const contrastValue = document.getElementById('contrastValue');
contrastSlider.addEventListener('input', function() {
const value = this.value;
contrastValue.textContent = `${value}%`;
panel.style.filter = `brightness(${brightnessSlider.value / 100}) contrast(${value / 100})`;
});
// Dead Pixel
document.getElementById('deadPixelBtn').addEventListener('click', function() {
const randomPixel = pixels[Math.floor(Math.random() * pixels.length)];
randomPixel.classList.add('dead-pixel');
});
// Stuck Pixel
document.getElementById('stuckPixelBtn').addEventListener('click', function() {
const randomPixel = pixels[Math.floor(Math.random() * pixels.length)];
randomPixel.classList.add('stuck-pixel');
});
// Backlight Bleed
document.getElementById('backlightBleedBtn').addEventListener('click', function() {
// Create 4 corner bleeds
const colors = ['#ffffff', '#00ffff', '#ff00ff', '#ffff00'];
for (let i = 0; i < 4; i++) {
const bleed = document.createElement('div');
bleed.className = 'backlight-bleed';
bleed.style.backgroundColor = colors[i];
const size = 50 + Math.random() * 100;
bleed.style.width = `${size}px`;
bleed.style.height = `${size}px`;
if (i === 0) {
// Top-left
bleed.style.top = '0';
bleed.style.left = '0';
} else if (i === 1) {
// Top-right
bleed.style.top = '0';
bleed.style.right = '0';
} else if (i === 2) {
// Bottom-left
bleed.style.bottom = '0';
bleed.style.left = '0';
} else {
// Bottom-right
bleed.style.bottom = '0';
bleed.style.right = '0';
}
panel.appendChild(bleed);
}
});
// Image Retention
document.getElementById('imageRetentionBtn').addEventListener('click', function() {
// Create a semi-transparent copy of the current display
const retention = document.createElement('div');
retention.className = 'image-retention absolute inset-0';
retention.style.backgroundImage = 'url("data:image/svg+xml;utf8,<svg xmlns=\'http://www.w3.org/2000/svg\' width=\'' + panelWidth + '\' height=\'' + panelHeight + '\'><rect width=\'100%\' height=\'100%\' fill=\'black\'/></svg>")';
retention.style.backgroundSize = 'cover';
// Capture current pixel colors
const canvas = document.createElement('canvas');
canvas.width = panelWidth;
canvas.height = panelHeight;
const ctx = canvas.getContext('2d');
// Create a simplified representation (for performance)
const blockSize = 10;
for (let y = 0; y < rows; y += blockSize) {
for (let x = 0; x < cols; x += blockSize) {
const pixelIndex = y * cols + x;
if (pixelIndex < pixels.length) {
const pixel = pixels[pixelIndex];
const color = window.getComputedStyle(pixel).backgroundColor;
ctx.fillStyle = color;
ctx.fillRect(x, y, blockSize, blockSize);
}
}
}
retention.style.backgroundImage = `url(${canvas.toDataURL()})`;
panel.appendChild(retention);
// Remove after some time
setTimeout(() => {
retention.remove();
}, 10000);
});
// Viewing Angles
document.getElementById('angle0Btn').addEventListener('click', function() {
panel.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(0deg)';
panel.style.filter = 'brightness(1) contrast(1)';
});
document.getElementById('angle30Btn').addEventListener('click', function() {
panel.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(30deg)';
panel.style.filter = 'brightness(0.9) contrast(0.9)';
});
document.getElementById('angle45Btn').addEventListener('click', function() {
panel.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(45deg)';
panel.style.filter = 'brightness(0.8) contrast(0.8)';
});
document.getElementById('angle60Btn').addEventListener('click', function() {
panel.style.transform = 'perspective(1000px) rotateX(0deg) rotateY(60deg)';
panel.style.filter = 'brightness(0.7) contrast(0.7) saturate(0.8)';
});
// Response Time
document.getElementById('fastResponseBtn').addEventListener('click', function() {
pixels.forEach(pixel => {
pixel.style.transition = 'all 0.001s ease';
});
});
document.getElementById('mediumResponseBtn').addEventListener('click', function() {
pixels.forEach(pixel => {
pixel.style.transition = 'all 0.005s ease';
});
});
document.getElementById('slowResponseBtn').addEventListener('click', function() {
pixels.forEach(pixel => {
pixel.style.transition = 'all 0.01s ease';
});
});
// Color Gamut
document.getElementById('srgbBtn').addEventListener('click', function() {
panel.style.filter = 'brightness(1) contrast(1)';
});
document.getElementById('adobeRgbBtn').addEventListener('click', function() {
panel.style.filter = 'brightness(1) contrast(1) saturate(1.2)';
});
document.getElementById('dciP3Btn').addEventListener('click', function() {
panel.style.filter = 'brightness(1) contrast(1) saturate(1.5)';
});
});
</script>
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=PrinzPesia/ips-panel-simulator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
</html>