( ′∀`)σ≡σ☆))Д′)レ(゚∀゚;)ヘ=З=З=Зε≡(ノ´_ゝ`)ノ HEX
HEX
Server: Apache/2.4.58 (Ubuntu)
System: Linux mail.thebrand.ai 6.8.0-107-generic #107-Ubuntu SMP PREEMPT_DYNAMIC Fri Mar 13 19:51:50 UTC 2026 x86_64
User: www-data (33)
PHP: 8.3.6
Disabled: NONE
Upload Files
File: /var/www/html/tmpr/..//tmpr/../tmpr/..//tmpr/../tmpr/../wowZ/canvas-editor.php
<?php
// public/canvas-editor.php
session_start();
require_once 'config/database.php';

$themeid = $_GET['themeid'] ?? 1;
$pageId = $_GET['page_id'] ?? 0;
$userId = $_SESSION['user_id'] ?? 'guest_' . uniqid();
?>
<!DOCTYPE html>
<html>
<head>
    <title>Canvas Editor - Theme <?php echo $themeid; ?> Page <?php echo $pageId; ?></title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/5.3.0/fabric.min.js"></script>
    <script src="brandSync/js/canvas-sync.js"></script>
    <script src="brandSync/js/canvas-enhanced.js"></script>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: Arial, sans-serif; background: #f0f0f0; }
        
        .toolbar {
            background: #2c3e50; color: white; padding: 10px 20px;
            display: flex; gap: 10px; align-items: center;
        }
        .toolbar button {
            background: #3498db; color: white; border: none;
            padding: 8px 16px; border-radius: 4px; cursor: pointer;
            font-size: 14px;
        }
        .toolbar button:hover { background: #2980b9; }
        .toolbar button:disabled { background: #95a5a6; cursor: not-allowed; }
        
        .status {
            margin-left: auto; display: flex; gap: 10px; align-items: center;
        }
        .status-dot {
            width: 10px; height: 10px; border-radius: 50%; background: #e74c3c;
        }
        .status-dot.connected { background: #2ecc71; }
        
        .canvas-container {
            display: flex; justify-content: center; padding: 20px;
            background: #ecf0f1; min-height: calc(100vh - 60px);
        }
        #canvas { box-shadow: 0 0 10px rgba(0,0,0,0.1); }
        
        @keyframes slideIn {
            from { transform: translateX(400px); opacity: 0; }
            to { transform: translateX(0); opacity: 1; }
        }
        @keyframes slideOut {
            from { transform: translateX(0); opacity: 1; }
            to { transform: translateX(400px); opacity: 0; }
        }
    </style>
</head>
<body>
    <div class="toolbar">
        <button id="brand-json-save">💾 Save</button>
        <button id="undoBtn">↶ Undo</button>
        <button id="redoBtn">↷ Redo</button>
        <button id="addRectBtn">▭ Rectangle</button>
        <button id="addCircleBtn">● Circle</button>
        <button id="addTextBtn">T Text</button>
        <button id="exportBtn">📥 Export</button>
        <button id="clearBtn">🗑️ Clear</button>
        
        <div class="status">
            <span id="userCount">0 users</span>
            <div class="status-dot" id="statusDot"></div>
            <span id="statusText">Connecting...</span>
        </div>
    </div>
    
    <div class="canvas-container">
        <canvas id="canvas" width="2240" height="1260"></canvas>
    </div>

    <script>
        const canvas = new fabric.Canvas('canvas', {
            backgroundColor: '#ffffff',
            preserveObjectStacking: true
        });

        const collab = new EnhancedCanvasCollaboration(
            canvas,
            '<?php echo $userId; ?>',
            <?php echo $themeid; ?>,
            <?php echo $pageId; ?>
        );

        collab.loadFromBackend();

        // Status updates
        collab.ws.addEventListener('open', () => {
            document.getElementById('statusDot').classList.add('connected');
            document.getElementById('statusText').textContent = 'Connected';
        });

        collab.ws.addEventListener('close', () => {
            document.getElementById('statusDot').classList.remove('connected');
            document.getElementById('statusText').textContent = 'Disconnected';
        });

        // Toolbar
        document.getElementById('brand-json-save').addEventListener('click', async () => {
            const btn = document.getElementById('brand-json-save');
            btn.disabled = true;
            btn.textContent = '⏳ Saving...';
            await collab.manualSave();
            btn.disabled = false;
            btn.textContent = '💾 Save';
        });

        document.getElementById('undoBtn').onclick = () => collab.undo();
        document.getElementById('redoBtn').onclick = () => collab.redo();

        document.getElementById('addRectBtn').onclick = () => {
            canvas.add(new fabric.Rect({
                left: 100, top: 100, width: 150, height: 100,
                fill: '#3498db', id: 'rect_' + Date.now(),
                objectType: 'shape', layerType: 'layer'
            }));
        };

        document.getElementById('addCircleBtn').onclick = () => {
            canvas.add(new fabric.Circle({
                left: 150, top: 150, radius: 50, fill: '#e74c3c',
                id: 'circle_' + Date.now(), objectType: 'shape', layerType: 'layer'
            }));
        };

        document.getElementById('addTextBtn').onclick = () => {
            canvas.add(new fabric.IText('Edit me', {
                left: 200, top: 200, fontSize: 24, fill: '#2c3e50',
                id: 'text_' + Date.now(), objectType: 'text', layerType: 'layer'
            }));
        };

        document.getElementById('exportBtn').onclick = () => collab.exportAsImage('png', 1.0);
        document.getElementById('clearBtn').onclick = () => collab.clearCanvas();

        // Keyboard shortcuts
        document.addEventListener('keydown', (e) => {
            if (e.ctrlKey || e.metaKey) {
                if (e.key === 's') { e.preventDefault(); document.getElementById('brand-json-save').click(); }
                else if (e.key === 'z' && !e.shiftKey) { e.preventDefault(); collab.undo(); }
                else if (e.key === 'z' && e.shiftKey) { e.preventDefault(); collab.redo(); }
            }
            if (e.key === 'Delete' || e.key === 'Backspace') {
                const activeObjects = canvas.getActiveObjects();
                if (activeObjects.length > 0) {
                    activeObjects.forEach(obj => canvas.remove(obj));
                    canvas.discardActiveObject();
                    canvas.renderAll();
                }
            }
        });

        // User count updates
        collab.onUserJoined = (data) => {
            document.getElementById('userCount').textContent = data.count + ' users';
        };
        collab.onUserLeft = (data) => {
            document.getElementById('userCount').textContent = data.count + ' users';
        };

        window.addEventListener('beforeunload', () => collab.disconnect());
    </script>
</body>
</html>