dream-machine-ai-studio / components /generator-panel.js
Mccscs2's picture
remove any references to Uncensord, and No filters. No restrictions. Pure creative freedom. in the display
0d19927 verified
class GeneratorControls extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.panel {
background: rgba(30, 41, 59, 0.4);
backdrop-filter: blur(12px);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 1rem;
padding: 1.5rem;
}
.input-group {
margin-bottom: 1rem;
}
.input-label {
display: block;
color: #94a3b8;
font-size: 0.875rem;
font-weight: 500;
margin-bottom: 0.5rem;
}
.cyber-input {
width: 100%;
background: rgba(15, 23, 42, 0.8);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 0.5rem;
padding: 0.75rem 1rem;
color: #f1f5f9;
font-size: 0.875rem;
transition: all 0.3s;
resize: vertical;
font-family: inherit;
}
.cyber-input:focus {
outline: none;
border-color: rgba(139, 92, 246, 0.6);
box-shadow: 0 0 0 3px rgba(139, 92, 246, 0.1);
}
.cyber-input::placeholder {
color: #475569;
}
.ratio-grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
gap: 0.5rem;
margin-top: 0.5rem;
}
.ratio-btn {
padding: 0.5rem;
background: rgba(30, 41, 59, 0.8);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 0.375rem;
color: #94a3b8;
font-size: 0.75rem;
cursor: pointer;
transition: all 0.2s;
text-align: center;
}
.ratio-btn:hover {
border-color: rgba(139, 92, 246, 0.4);
color: #c4b5fd;
}
.ratio-btn.active {
background: #7c3aed;
border-color: #7c3aed;
color: white;
}
.generate-btn {
width: 100%;
padding: 0.875rem;
background: linear-gradient(135deg, #7c3aed 0%, #6d28d9 100%);
border: none;
border-radius: 0.5rem;
color: white;
font-weight: 600;
font-size: 0.875rem;
cursor: pointer;
transition: all 0.3s;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
gap: 0.5rem;
}
.generate-btn:hover {
transform: translateY(-1px);
box-shadow: 0 10px 25px -5px rgba(124, 58, 237, 0.4);
}
.generate-btn:active {
transform: translateY(0);
}
.enhance-btn {
position: absolute;
right: 0.5rem;
top: 50%;
transform: translateY(-50%);
padding: 0.25rem 0.75rem;
background: rgba(6, 182, 212, 0.1);
border: 1px solid rgba(6, 182, 212, 0.3);
border-radius: 0.25rem;
color: #06b6d4;
font-size: 0.75rem;
cursor: pointer;
transition: all 0.2s;
}
.enhance-btn:hover {
background: rgba(6, 182, 212, 0.2);
}
.settings-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 1rem;
margin-top: 1rem;
}
.setting-item label {
display: block;
color: #64748b;
font-size: 0.75rem;
margin-bottom: 0.25rem;
}
.setting-item input {
width: 100%;
background: rgba(15, 23, 42, 0.6);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 0.25rem;
padding: 0.375rem;
color: #94a3b8;
font-size: 0.75rem;
}
.slider-container {
margin-top: 0.5rem;
}
.slider-label {
display: flex;
justify-content: space-between;
color: #64748b;
font-size: 0.75rem;
margin-bottom: 0.25rem;
}
input[type="range"] {
width: 100%;
height: 4px;
background: rgba(139, 92, 246, 0.2);
border-radius: 2px;
outline: none;
-webkit-appearance: none;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
width: 16px;
height: 16px;
background: #7c3aed;
border-radius: 50%;
cursor: pointer;
box-shadow: 0 0 10px rgba(124, 58, 237, 0.5);
}
.tag-suggestions {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 0.5rem;
}
.tag {
padding: 0.25rem 0.5rem;
background: rgba(139, 92, 246, 0.1);
border: 1px solid rgba(139, 92, 246, 0.3);
border-radius: 0.25rem;
color: #a78bfa;
font-size: 0.75rem;
cursor: pointer;
transition: all 0.2s;
}
.tag:hover {
background: rgba(139, 92, 246, 0.2);
transform: translateY(-1px);
}
</style>
<div class="panel">
<div class="input-group">
<label class="input-label flex justify-between">
Prompt
<span id="prompt-length" class="text-xs text-slate-500">0 chars</span>
</label>
<div style="position: relative;">
<textarea
id="prompt-input"
class="cyber-input"
rows="4"
placeholder="Describe what you want to see... (e.g., 'a cyberpunk street at night, neon lights, rain, 8k photorealistic')"
></textarea>
<button class="enhance-btn" title="Auto-enhance prompt">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" style="display: inline; margin-right: 4px;"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
Enhance
</button>
</div>
<div class="tag-suggestions">
<span class="tag" onclick="document.getElementById('prompt-input').value += (document.getElementById('prompt-input').value ? ', ' : '') + '8k photorealistic'">+ 8k</span>
<span class="tag" onclick="document.getElementById('prompt-input').value += (document.getElementById('prompt-input').value ? ', ' : '') + 'cinematic lighting'">+ cinematic</span>
<span class="tag" onclick="document.getElementById('prompt-input').value += (document.getElementById('prompt-input').value ? ', ' : '') + 'unreal engine 5'">+ UE5</span>
<span class="tag" onclick="document.getElementById('prompt-input').value += (document.getElementById('prompt-input').value ? ', ' : '') + 'highly detailed'">+ detailed</span>
</div>
</div>
<div class="input-group">
<label class="input-label">Negative Prompt</label>
<textarea
id="negative-prompt"
class="cyber-input"
rows="2"
placeholder="What to avoid... (e.g., 'blurry, low quality, distorted, ugly')"
></textarea>
</div>
<div class="input-group">
<label class="input-label">Aspect Ratio</label>
<div class="ratio-grid">
<button class="ratio-btn active" data-ratio="1:1">1:1</button>
<button class="ratio-btn" data-ratio="16:9">16:9</button>
<button class="ratio-btn" data-ratio="9:16">9:16</button>
<button class="ratio-btn" data-ratio="4:3">4:3</button>
<button class="ratio-btn" data-ratio="3:4">3:4</button>
</div>
</div>
<div class="slider-container">
<div class="slider-label">
<span>CFG Scale</span>
<span id="cfg-value">7.5</span>
</div>
<input type="range" min="1" max="20" step="0.5" value="7.5" data-setting="cfgScale" oninput="document.getElementById('cfg-value').textContent = this.value">
</div>
<div class="slider-container">
<div class="slider-label">
<span>Steps</span>
<span id="steps-value">30</span>
</div>
<input type="range" min="10" max="50" step="1" value="30" data-setting="steps" oninput="document.getElementById('steps-value').textContent = this.value">
</div>
<div class="settings-grid">
<div class="setting-item">
<label>Seed (-1 for random)</label>
<input type="number" value="-1" data-setting="seed">
</div>
<div class="setting-item">
<label>Model</label>
<select class="cyber-input" style="padding: 0.375rem; font-size: 0.75rem; height: auto;">
<option>SDXL Photorealistic</option>
<option>Uncensored V3</option>
<option>Realistic Vision</option>
<option>Epic Realism</option>
</select>
</div>
</div>
<button id="generate-btn" class="generate-btn" style="margin-top: 1.5rem;">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
Generate Image
</button>
</div>
`;
// Handle ratio button clicks
this.shadowRoot.querySelectorAll('.ratio-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
this.shadowRoot.querySelectorAll('.ratio-btn').forEach(b => b.classList.remove('active'));
e.target.classList.add('active');
});
});
}
}
class GeneratorPreview extends HTMLElement {
constructor() {
super();
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.preview-container {
background: rgba(15, 23, 42, 0.6);
border: 1px solid rgba(139, 92, 246, 0.2);
border-radius: 1rem;
min-height: 500px;
display: flex;
flex-direction: column;
overflow: hidden;
}
.preview-header {
padding: 1rem 1.5rem;
border-bottom: 1px solid rgba(139, 92, 246, 0.1);
display: flex;
justify-content: space-between;
align-items: center;
}
.preview-title {
color: #e2e8f0;
font-weight: 600;
font-size: 0.875rem;
}
.preview-content {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 1.5rem;
position: relative;
}
.empty-state {
text-align: center;
color: #475569;
}
.empty-icon {
width: 64px;
height: 64px;
margin: 0 auto 1rem;
opacity: 0.3;
}
.video-controls {
padding: 1rem 1.5rem;
background: rgba(15, 23, 42, 0.8);
border-top: 1px solid rgba(6, 182, 212, 0.2);
display: none;
}
.video-controls.active {
display: block;
}
.control-row {
display: flex;
gap: 1rem;
margin-bottom: 0.75rem;
}
.control-group {
flex: 1;
}
.control-label {
display: block;
color: #64748b;
font-size: 0.75rem;
margin-bottom: 0.25rem;
}
</style>
<div class="preview-container" id="preview-container">
<div class="preview-header">
<span class="preview-title">Preview</span>
<div class="flex gap-2">
<span class="text-xs text-slate-500 px-2 py-1 bg-slate-800 rounded">1024 × 1024</span>
</div>
</div>
<div class="preview-content">
<div class="empty-state">
<svg class="empty-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"/><circle cx="8.5" cy="8.5" r="1.5"/><polyline points="21 15 16 10 5 21"/></svg>
<p class="text-sm">Enter a prompt and click generate</p>
<p class="text-xs mt-2 opacity-50">Your creation will appear here</p>
</div>
</div>
<div class="video-controls" id="video-controls">
<div class="control-row">
<div class="control-group">
<label class="control-label">Motion Strength</label>
<input type="range" min="1" max="10" value="5" class="w-full" data-setting="motionStrength">
</div>
<div class="control-group">
<label class="control-label">Duration (seconds)</label>
<input type="range" min="2" max="10" value="4" class="w-full" data-setting="videoDuration">
</div>
</div>
<button id="generate-video-btn" class="w-full py-2 bg-secondary-600 hover:bg-secondary-500 text-white rounded-lg text-sm font-medium transition-colors flex items-center justify-center gap-2">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="23 7 16 12 23 17 23 7"/><rect x="1" y="5" width="15" height="14" rx="2" ry="2"/></svg>
Generate Video from Image
</button>
</div>
</div>
`;
}
}
customElements.define('generator-controls', GeneratorControls);
customElements.define('generator-preview', GeneratorPreview);