Testcomic / output_template /page_editable.html
3v324v23's picture
Update Comic123 with local comic folder files
83e35a7
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Interactive Comic Editor</title>
<link id="pageStyle" rel="stylesheet" href="page.css">
<link rel="stylesheet" href="bubble.css">
<style>
/* Additional styles for editing */
.bubble {
cursor: move;
transition: box-shadow 0.2s;
user-select: none;
}
.bubble:hover {
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.bubble.editing {
cursor: text;
}
.bubble textarea {
width: 100%;
height: 100%;
border: none;
background: transparent;
font-family: inherit;
font-size: inherit;
font-weight: inherit;
text-align: center;
resize: none;
outline: 2px solid #4CAF50;
padding: 5px;
box-sizing: border-box;
}
.edit-controls {
position: fixed;
bottom: 20px;
right: 20px;
background: rgba(0,0,0,0.85);
color: white;
padding: 15px 20px;
border-radius: 10px;
font-size: 14px;
z-index: 1000;
box-shadow: 0 4px 12px rgba(0,0,0,0.3);
}
.edit-controls h4 {
margin: 0 0 10px 0;
color: #4CAF50;
}
.edit-controls p {
margin: 5px 0;
opacity: 0.9;
}
.edit-controls button {
margin-top: 10px;
padding: 8px 16px;
border: none;
border-radius: 5px;
cursor: pointer;
font-weight: bold;
transition: all 0.2s;
}
.save-btn {
background: #4CAF50;
color: white;
margin-right: 10px;
}
.save-btn:hover {
background: #45a049;
}
.reset-btn {
background: #f44336;
color: white;
}
.reset-btn:hover {
background: #da190b;
}
</style>
<script src="page.js"></script>
<script src="page_place.js"></script>
</head>
<body>
<div class="button">
<button onclick="prevPage()"><img src="assets/backward.png" alt=""></button>
</div>
<div class="wrapper">
<div class="grid-container">
<div class="grid-item" id="_1"></div>
<div class="grid-item" id="_2"></div>
<div class="grid-item" id="_3"></div>
<div class="grid-item" id="_4"></div>
<div class="grid-item" id="_5"></div>
<div class="grid-item" id="_6"></div>
<div class="grid-item" id="_7"></div>
<div class="grid-item" id="_8"></div>
<div class="grid-item" id="_9"></div>
<div class="grid-item" id="_10"></div>
<div class="grid-item" id="_11"></div>
<div class="grid-item" id="_12"></div>
</div>
</div>
<div class="button">
<button onclick="nextPage()"><img src="assets/forward.png" alt=""></button>
</div>
<!-- Edit Controls -->
<div class="edit-controls">
<h4>✏️ Comic Editor</h4>
<p><strong>Drag</strong> speech bubbles to reposition</p>
<p><strong>Double-click</strong> to edit text</p>
<p><strong>Enter</strong> to save text</p>
<button class="save-btn" onclick="saveComic()">💾 Save Changes</button>
<button class="reset-btn" onclick="resetComic()">↩️ Reset</button>
</div>
<script>
// Interactive editing functionality
let currentEditBubble = null;
let draggedBubble = null;
let offset = {x: 0, y: 0};
// Wait for page to load
window.addEventListener('load', () => {
setTimeout(initializeEditor, 500);
});
function initializeEditor() {
// Find all speech bubbles
document.querySelectorAll('.bubble').forEach(bubble => {
// Make bubbles interactive
bubble.addEventListener('dblclick', (e) => {
e.stopPropagation();
editBubbleText(bubble);
});
bubble.addEventListener('mousedown', startDrag);
});
// Global mouse events
document.addEventListener('mousemove', drag);
document.addEventListener('mouseup', stopDrag);
// Load saved state if exists
loadSavedState();
}
function editBubbleText(bubble) {
if (currentEditBubble) return;
currentEditBubble = bubble;
bubble.classList.add('editing');
const text = bubble.innerText;
const textarea = document.createElement('textarea');
textarea.value = text;
bubble.innerHTML = '';
bubble.appendChild(textarea);
textarea.focus();
textarea.select();
textarea.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && !e.shiftKey) {
e.preventDefault();
saveBubbleText(bubble, textarea.value);
}
if (e.key === 'Escape') {
saveBubbleText(bubble, text);
}
});
textarea.addEventListener('blur', () => {
setTimeout(() => {
if (currentEditBubble === bubble) {
saveBubbleText(bubble, textarea.value);
}
}, 100);
});
}
function saveBubbleText(bubble, text) {
bubble.innerText = text;
bubble.classList.remove('editing');
currentEditBubble = null;
saveState();
}
function startDrag(e) {
if (e.target.tagName === 'TEXTAREA') return;
const bubble = e.target.closest('.bubble');
if (!bubble || currentEditBubble) return;
draggedBubble = bubble;
const rect = bubble.getBoundingClientRect();
offset.x = e.clientX - rect.left;
offset.y = e.clientY - rect.top;
bubble.style.opacity = '0.9';
bubble.style.zIndex = '100';
e.preventDefault();
}
function drag(e) {
if (!draggedBubble) return;
const parent = draggedBubble.parentElement;
const parentRect = parent.getBoundingClientRect();
let x = e.clientX - parentRect.left - offset.x;
let y = e.clientY - parentRect.top - offset.y;
// Keep within bounds
x = Math.max(0, Math.min(x, parentRect.width - draggedBubble.offsetWidth));
y = Math.max(0, Math.min(y, parentRect.height - draggedBubble.offsetHeight));
draggedBubble.style.left = x + 'px';
draggedBubble.style.top = y + 'px';
}
function stopDrag() {
if (draggedBubble) {
draggedBubble.style.opacity = '';
draggedBubble.style.zIndex = '';
saveState();
draggedBubble = null;
}
}
function saveState() {
const bubbles = [];
document.querySelectorAll('.bubble').forEach((bubble, index) => {
bubbles.push({
index: index,
text: bubble.innerText,
left: bubble.style.left,
top: bubble.style.top
});
});
localStorage.setItem('comicBubbles', JSON.stringify(bubbles));
}
function loadSavedState() {
const saved = localStorage.getItem('comicBubbles');
if (!saved) return;
try {
const bubbles = JSON.parse(saved);
const elements = document.querySelectorAll('.bubble');
bubbles.forEach((data, index) => {
if (elements[index]) {
elements[index].innerText = data.text;
if (data.left) elements[index].style.left = data.left;
if (data.top) elements[index].style.top = data.top;
}
});
} catch (e) {
console.error('Failed to load saved state:', e);
}
}
function saveComic() {
saveState();
alert('✅ Comic changes saved!\n\nYour edits are saved locally. To export the comic, use your browser\'s print function or take a screenshot.');
}
function resetComic() {
if (confirm('Reset all changes to original?')) {
localStorage.removeItem('comicBubbles');
location.reload();
}
}
</script>
</body>
</html>