Files
Comfyui-LayerForge/css_test.html
2025-07-28 19:42:10 +02:00

543 lines
22 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas View CSS Test - All Button Styles</title>
<link rel="stylesheet" href="src/css/canvas_view.css">
<style>
body {
font-family: Arial, sans-serif;
background: #2a2a2a;
color: #ffffff;
margin: 20px;
line-height: 1.6;
}
.test-section {
margin: 30px 0;
padding: 20px;
background: #353535;
border-radius: 8px;
border: 1px solid #444;
}
.test-section h2 {
color: #4a90e2;
margin-top: 0;
border-bottom: 1px solid #555;
padding-bottom: 10px;
}
.test-section h3 {
color: #ffffff;
margin: 20px 0 10px 0;
}
.demo-row {
margin: 15px 0;
display: flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.demo-label {
min-width: 150px;
color: #cccccc;
font-size: 14px;
}
.test-controls {
margin: 20px 0;
}
.test-controls button {
margin: 5px;
padding: 8px 16px;
background: #4a6cd4;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
.test-controls button:hover {
background: #5a7ce4;
}
/* Custom Slider Styles to match ComfyUI aesthetic */
input[type="range"] {
-webkit-appearance: none;
appearance: none;
width: 80px; /* Default width from painter-slider-container */
height: 7px;
background: #222;
border-radius: 5px;
outline: none;
margin: 0;
padding: 0;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 16px;
height: 16px;
background: #cccccc;
border-radius: 50%;
border: 2px solid #555;
cursor: pointer;
margin-top: -4.5px; /* Center thumb on track */
transition: background 0.2s;
}
input[type="range"]::-moz-range-thumb {
width: 16px;
height: 16px;
background: #cccccc;
border-radius: 50%;
border: 2px solid #555;
cursor: pointer;
}
input[type="range"]::-webkit-slider-thumb:hover {
background: #e0e0e0;
}
input[type="range"]::-moz-range-thumb:hover {
background: #e0e0e0;
}
input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 7px;
background: #222;
border-radius: 5px;
}
input[type="range"]::-moz-range-track {
width: 100%;
height: 7px;
background: #222;
border-radius: 5px;
}
</style>
</head>
<body>
<h1>Canvas View CSS Test Page</h1>
<p>This page demonstrates all button styles from <code>src/css/canvas_view.css</code></p>
<div class="test-controls">
<button onclick="toggleLoadingState()">Toggle Loading State</button>
<button onclick="toggleDisabledState()">Toggle Disabled State</button>
<button onclick="toggleClipboardSwitch()">Toggle Clipboard Switch</button>
</div>
<!-- CanvasView Full Control Panel -->
<div class="test-section">
<h2>CanvasView Control Panel Layout</h2>
<div class="painter-controls" style="position: relative; flex-wrap: wrap; padding: 10px; background: #383838;">
<!-- Group 1: Main Controls -->
<div class="painter-button-group">
<button class="painter-button icon-button" title="Open in Editor"></button>
<button class="painter-button icon-button" title="Show shortcuts">?</button>
<button class="painter-button primary">Add Image</button>
<button class="painter-button primary">Import Input</button>
<div class="painter-clipboard-group">
<button class="painter-button primary">Paste Image</button>
<label class="clipboard-switch" id="test-clipboard-switch">
<input type="checkbox">
<span class="switch-track"></span>
<span class="switch-labels">
<span class="text-clipspace">Clipspace</span>
<span class="text-system">System</span>
</span>
<span class="switch-knob">
<span class="switch-icon">
<img src="" alt="clipboard icon" style="width: 20px; height: 20px;">
</span>
</span>
</label>
</div>
</div>
<div class="painter-separator"></div>
<!-- Group 2: Layer Management -->
<div class="painter-button-group">
<button class="painter-button">Output Area Size</button>
<button class="painter-button requires-selection">Remove Layer</button>
<button class="painter-button requires-selection">Layer Up</button>
<button class="painter-button requires-selection">Layer Down</button>
<button class="painter-button requires-selection">Fuse</button>
</div>
<div class="painter-separator"></div>
<!-- Group 3: Transformations -->
<div class="painter-button-group">
<button class="painter-button requires-selection">Rotate +90°</button>
<button class="painter-button requires-selection">Scale +5%</button>
<button class="painter-button requires-selection">Scale -5%</button>
<button class="painter-button requires-selection">Mirror H</button>
<button class="painter-button requires-selection">Mirror V</button>
</div>
<div class="painter-separator"></div>
<!-- Group 4: Tools -->
<div class="painter-button-group">
<button class="painter-button matting-button requires-selection">Matting<div class="matting-spinner"></div></button>
<button class="painter-button">Undo</button>
<button class="painter-button">Redo</button>
</div>
<div class="painter-separator"></div>
<!-- Group 5: Masking -->
<div class="painter-button-group" id="test-mask-controls">
<label class="clipboard-switch mask-switch" title="Toggle mask overlay visibility" style="min-width: 56px; max-width: 56px; width: 56px;">
<input type="checkbox" checked="">
<span class="switch-track"></span>
<span class="switch-labels" style="font-size: 11px;">
<span class="text-clipspace" style="padding-right: 22px;">On</span>
<span class="text-system" style="padding-left: 20px;">Off</span>
</span>
<span class="switch-knob">
<span class="switch-icon" style="display: flex; align-items: center; justify-content: center; width: 16px; height: 16px;">
<!-- Icon would be loaded here by JS -->
</span>
</span>
</label>
<button class="painter-button">Edit Mask</button>
<button class="painter-button" id="test-mask-mode-btn" onclick="toggleTestMaskControls()">Draw Mask</button>
<div class="painter-slider-container mask-control" style="display: none;">
<label>Size:</label>
<input type="range" min="1" max="200" value="20">
<div class="slider-value">20px</div>
</div>
<div class="painter-slider-container mask-control" style="display: none;">
<label>Strength:</label>
<input type="range" min="0" max="1" step="0.05" value="0.5">
<div class="slider-value">50%</div>
</div>
<div class="painter-slider-container mask-control" style="display: none;">
<label>Hardness:</label>
<input type="range" min="0" max="1" step="0.05" value="0.5">
<div class="slider-value">50%</div>
</div>
<button class="painter-button mask-control" style="display: none;">Clear Mask</button>
</div>
<div class="painter-separator"></div>
<!-- Group 6: Dev/Debug -->
<div class="painter-button-group">
<button class="painter-button success">Run GC</button>
<button class="painter-button danger">Clear Cache</button>
</div>
</div>
</div>
<!-- Basic Buttons -->
<div class="test-section">
<h2>Basic Painter Buttons</h2>
<div class="demo-row">
<span class="demo-label">Normal Button:</span>
<button class="painter-button">Normal Button</button>
<button class="painter-button">Another Button</button>
<button class="painter-button">Third Button</button>
</div>
<div class="demo-row">
<span class="demo-label">Primary Button:</span>
<button class="painter-button primary">Primary Button</button>
<button class="painter-button primary">Save</button>
<button class="painter-button primary">Apply</button>
</div>
<div class="demo-row">
<span class="demo-label">Disabled Buttons:</span>
<button class="painter-button" disabled>Disabled Normal</button>
<button class="painter-button primary" disabled>Disabled Primary</button>
</div>
<div class="demo-row">
<span class="demo-label">Matting Buttons:</span>
<button class="painter-button matting-button" id="mattingBtn1">
Matting Tool
<div class="matting-spinner"></div>
</button>
<button class="painter-button matting-button" id="mattingBtn2">
Process Image
<div class="matting-spinner"></div>
</button>
</div>
</div>
<!-- Button Groups -->
<div class="test-section">
<h2>Button Groups and Controls</h2>
<h3>Painter Controls Container</h3>
<div class="painter-controls">
<button class="painter-button">Tool 1</button>
<button class="painter-button">Tool 2</button>
<button class="painter-button primary">Active Tool</button>
<div class="painter-separator"></div>
<button class="painter-button">Option A</button>
<button class="painter-button">Option B</button>
</div>
<h3>Button Group</h3>
<div class="painter-button-group">
<button class="painter-button">Group 1</button>
<button class="painter-button">Group 2</button>
<button class="painter-button primary">Group 3</button>
</div>
<h3>Clipboard Group</h3>
<div class="painter-clipboard-group">
<button class="painter-button">Copy</button>
<button class="painter-button">Paste</button>
<button class="painter-button primary">Clear</button>
</div>
</div>
<!-- Clipboard Switch -->
<div class="test-section">
<h2>Clipboard Switch</h2>
<div class="demo-row">
<span class="demo-label">Clipboard Switch:</span>
<label class="clipboard-switch" id="clipboardSwitch">
<input type="checkbox">
<span class="switch-track"></span>
<span class="switch-knob">
<span class="switch-icon">
<img src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTkgMTZIMTVWMTBIOVYxNloiIGZpbGw9IiM0YTkwZTIiLz4KPHBhdGggZD0iTTcgMTZIMTdWMTBIN1YxNloiIHN0cm9rZT0iIzRhOTBlMiIgc3Ryb2tlLXdpZHRoPSIyIiBmaWxsPSJub25lIi8+Cjwvc3ZnPgo=" alt="clipboard">
</span>
</span>
<span class="switch-labels">
<span class="text-system">System</span>
<span class="text-clipspace">Clipspace</span>
</span>
</label>
</div>
</div>
<!-- Sliders -->
<div class="test-section">
<h2>Sliders and Controls</h2>
<div class="painter-controls">
<div class="painter-slider-container">
<label>Opacity:</label>
<input type="range" min="0" max="100" value="50">
<span>50%</span>
</div>
<div class="painter-separator"></div>
<div class="painter-slider-container">
<label>Size:</label>
<input type="range" min="1" max="100" value="25">
<span>25px</span>
</div>
</div>
</div>
<!-- Container Examples -->
<div class="test-section">
<h2>Container Examples</h2>
<h3>Normal Container</h3>
<div class="painter-container" style="padding: 20px; margin: 10px 0;">
<p>This is a normal painter container</p>
<button class="painter-button">Button inside container</button>
</div>
<h3>Container with Focus</h3>
<div class="painter-container has-focus" style="padding: 20px; margin: 10px 0;">
<p>This container has focus (white border)</p>
<button class="painter-button primary">Focused container button</button>
</div>
<h3>Drag Over Container</h3>
<div class="painter-container drag-over" style="padding: 20px; margin: 10px 0;">
<p>This container is in drag-over state (green dashed border)</p>
<button class="painter-button">Drag target button</button>
</div>
</div>
<!-- Modal Example -->
<div class="test-section">
<h2>Modal and Dialog</h2>
<button onclick="showModal()" class="painter-button primary">Show Modal Example</button>
<h3>Dialog Example</h3>
<div class="painter-dialog" style="display: inline-block; margin: 10px 0;">
<h4>Sample Dialog</h4>
<p>Enter values:</p>
<input type="text" placeholder="Width" value="100">
<input type="text" placeholder="Height" value="100">
<br>
<button>OK</button>
<button>Cancel</button>
</div>
</div>
<!-- Hidden Modal -->
<div class="painter-modal-backdrop" id="testModal" style="display: none;">
<div class="painter-modal-content">
<div class="painterMainContainer">
<div class="painter-controls">
<button class="painter-button" onclick="hideModal()">Close Modal</button>
<button class="painter-button primary">Save</button>
<div class="painter-separator"></div>
<button class="painter-button">Option 1</button>
<button class="painter-button">Option 2</button>
</div>
<div class="painterCanvasContainer" style="padding: 20px; display: flex; align-items: center; justify-content: center;">
<div>
<h3>Modal Content Area</h3>
<p>This is the main content area of the modal.</p>
<div class="painter-button-group">
<button class="painter-button">Action 1</button>
<button class="painter-button">Action 2</button>
<button class="painter-button primary">Primary Action</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- This is where the tooltip will be rendered -->
<div class="painter-tooltip" id="live-tooltip" style="display: none;"></div>
<script>
// Toggle loading state for matting buttons
function toggleLoadingState() {
const mattingBtns = document.querySelectorAll('.matting-button');
mattingBtns.forEach(btn => {
btn.classList.toggle('loading');
});
}
// Toggle disabled state for all buttons
function toggleDisabledState() {
const buttons = document.querySelectorAll('.painter-button:not(.matting-button)');
buttons.forEach(btn => {
btn.disabled = !btn.disabled;
});
}
// Toggle clipboard switch
function toggleClipboardSwitch() {
const checkbox = document.querySelector('#clipboardSwitch input[type="checkbox"]');
checkbox.checked = !checkbox.checked;
}
// Show modal
function showModal() {
document.getElementById('testModal').style.display = 'flex';
}
// Hide modal
function hideModal() {
document.getElementById('testModal').style.display = 'none';
}
// --- Live Tooltip Logic ---
const tooltipButton = document.querySelector('button[title="Show shortcuts"]');
const tooltipContainer = document.getElementById('live-tooltip');
let shortcutsHtml = '';
// Pre-fetch the shortcuts content
fetch('src/templates/standard_shortcuts.html')
.then(response => response.text())
.then(html => {
shortcutsHtml = html;
})
.catch(error => {
console.error('Error fetching shortcuts:', error);
shortcutsHtml = '<p>Error loading shortcuts.</p>';
});
tooltipButton.addEventListener('mouseenter', (e) => {
if (!shortcutsHtml || !tooltipContainer) return;
tooltipContainer.innerHTML = shortcutsHtml;
tooltipContainer.style.visibility = 'hidden';
tooltipContainer.style.display = 'block';
const buttonRect = e.target.getBoundingClientRect();
const tooltipRect = tooltipContainer.getBoundingClientRect();
let left = buttonRect.left;
let top = buttonRect.bottom + 5;
// Adjust position to stay within viewport
if (left + tooltipRect.width > window.innerWidth) {
left = window.innerWidth - tooltipRect.width - 10;
}
if (top + tooltipRect.height > window.innerHeight) {
top = buttonRect.top - tooltipRect.height - 5;
}
if (left < 10) left = 10;
if (top < 10) top = 10;
tooltipContainer.style.left = `${left}px`;
tooltipContainer.style.top = `${top}px`;
tooltipContainer.style.visibility = 'visible';
});
tooltipButton.addEventListener('mouseleave', () => {
if (tooltipContainer) {
tooltipContainer.style.display = 'none';
}
});
// Close modal when clicking backdrop
document.getElementById('testModal').addEventListener('click', function(e) {
if (e.target === this) {
hideModal();
}
});
// --- Icon Loading and Interactive Logic ---
const icons = {
system: `data:image/svg+xml;charset=utf-8,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ffffff"><path d="M19 2h-4.18C14.4.84 13.3 0 12 0S9.6.84 9.18 2H5c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1zm5 15H7v-2h10v2zm0-4H7v-2h10v2zm0-4H7V7h10v2z"/></svg>')}`,
clipspace: `data:image/svg+xml;charset=utf-8,${encodeURIComponent('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="#ffffff"><path d="M17 7H7c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h10c1.1 0 2-.9 2-2V9c0-1.1-.9-2-2-2zm0 12H7V9h10v10z"/><path d="M19 3H9c-1.1 0-2 .9-2 2v2h2V5h10v10h-2v2h2c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2z"/></svg>')}`
};
function updateClipboardIcon(switchElement) {
const isChecked = switchElement.querySelector('input').checked;
const iconImg = switchElement.querySelector('.switch-icon img');
iconImg.src = isChecked ? icons.clipspace : icons.system;
}
document.addEventListener('DOMContentLoaded', () => {
const clipboardSwitch = document.getElementById('test-clipboard-switch');
if (clipboardSwitch) {
updateClipboardIcon(clipboardSwitch);
clipboardSwitch.querySelector('input').addEventListener('change', () => {
updateClipboardIcon(clipboardSwitch);
});
}
});
// Function to toggle mask controls in the test layout
function toggleTestMaskControls() {
const maskBtn = document.getElementById('test-mask-mode-btn');
const maskControlsContainer = document.getElementById('test-mask-controls');
const controls = maskControlsContainer.querySelectorAll('.mask-control');
const isActive = maskBtn.classList.toggle('primary');
controls.forEach(control => {
control.style.display = isActive ? 'flex' : 'none';
});
}
</script>
</body>
</html>