{"id":2003,"date":"2025-06-09T02:45:12","date_gmt":"2025-06-09T02:45:12","guid":{"rendered":"https:\/\/homeqi.com.herbalshop.com\/?p=2003"},"modified":"2025-06-09T02:45:13","modified_gmt":"2025-06-09T02:45:13","slug":"coloring-for-fun","status":"publish","type":"post","link":"https:\/\/homeqi.com\/?p=2003","title":{"rendered":"Coloring for Fun"},"content":{"rendered":"<!-- The CSS is now inside <style> tags -->\r\n<style>\r\n    #app-container {\r\n        font-family: sans-serif;\r\n        text-align: center;\r\n        margin: 20px auto;\r\n        max-width: 850px; \/* Give the container a max-width *\/\r\n    }\r\n    \/* NEW: Styles for the Gallery View *\/\r\n    #gallery-view {\r\n        padding: 10px;\r\n    }\r\n    #gallery-grid {\r\n        display: grid;\r\n        grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\r\n        gap: 15px;\r\n    }\r\n    .gallery-thumbnail {\r\n        width: 100%;\r\n        height: auto;\r\n        border: 2px solid #ccc;\r\n        border-radius: 8px;\r\n        cursor: pointer;\r\n        transition: transform 0.2s, box-shadow 0.2s;\r\n    }\r\n    .gallery-thumbnail:hover {\r\n        transform: scale(1.05);\r\n        box-shadow: 0 4px 15px rgba(0,0,0,0.2);\r\n    }\r\n    \/* NEW: Class to hide\/show views *\/\r\n    .hidden {\r\n        display: none;\r\n    }\r\n    #controls {\r\n        display: inline-block;\r\n    }\r\n    #color-palette {\r\n        margin-bottom: 10px;\r\n    }\r\n    .color-box {\r\n        width: 30px;\r\n        height: 30px;\r\n        display: inline-block;\r\n        cursor: pointer;\r\n        border: 1px solid black;\r\n        vertical-align: middle;\r\n        transition: transform 0.2s;\r\n    }\r\n    .color-box.active {\r\n        border: 3px solid #007bff;\r\n        transform: scale(1.2);\r\n    }\r\n    #brush-controls {\r\n        margin-bottom: 10px;\r\n    }\r\n    .brush-btn {\r\n        padding: 8px 12px;\r\n        border: 1px solid #888;\r\n        background-color: #f0f0f0;\r\n        cursor: pointer;\r\n        margin: 0 3px;\r\n    }\r\n    .brush-btn.active {\r\n        background-color: #c0c0c0;\r\n        border-width: 2px;\r\n        border-color: #000;\r\n    }\r\n    #eraser-btn.active {\r\n        background-color: #add8e6;\r\n        border-color: #007bff;\r\n    }\r\n    #canvas-container {\r\n        position: relative;\r\n        width: 800px;\r\n        height: 700px;\r\n        margin: auto;\r\n        border: 1px solid black;\r\n        overflow: scroll; \/* Allow scrolling when zoomed *\/\r\n    }\r\n    #canvas-container canvas {\r\n        position: absolute;\r\n        top: 0;\r\n        left: 0;\r\n        cursor: crosshair;\r\n        -webkit-user-select: none;\r\n        -moz-user-select: none;\r\n        -ms-user-select: none;\r\n        user-select: none;\r\n        transform-origin: top left; \/* Scale from the top-left corner *\/\r\n    }\r\n<\/style>\r\n\r\n<!-- The HTML structure for your app -->\r\n<div id=\"app-container\">\r\n    \r\n    <!-- NEW: Gallery View -->\r\n    <div id=\"gallery-view\">\r\n        <h1>Choose a Coloring Page<\/h1>\r\n        <div id=\"gallery-grid\">\r\n            <!-- Thumbnails will be added here by JavaScript -->\r\n        <\/div>\r\n    <\/div>\r\n\r\n    <!-- MODIFIED: Coloring view, hidden by default -->\r\n    <div id=\"coloring-view\" class=\"hidden\">\r\n        <h1>Simple Coloring App<\/h1>\r\n        <div id=\"controls\">\r\n            <div id=\"color-palette\">\r\n                <div class=\"color-box active\" style=\"background-color: red;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: blue;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: green;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: yellow;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: orange;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: purple;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: black;\"><\/div>\r\n                <div class=\"color-box\" style=\"background-color: lightblue;\"><\/div>\r\n            <\/div>\r\n            <div id=\"brush-controls\">\r\n                <button class=\"brush-btn active\" data-size=\"6\">Small<\/button>\r\n                <button class=\"brush-btn\" data-size=\"15\">Medium<\/button>\r\n                <button class=\"brush-btn\" data-size=\"25\">Large<\/button>\r\n                <button id=\"eraser-btn\" class=\"brush-btn\">Eraser<\/button>\r\n                <button id=\"clear-btn\" class=\"brush-btn\">Clear All<\/button>\r\n                <button id=\"undo-btn\" class=\"brush-btn\">Undo<\/button>\r\n                <button id=\"save-btn\" class=\"brush-btn\">Save<\/button>\r\n                <button id=\"import-btn\" class=\"brush-btn\">Import Image<\/button>\r\n            <\/div>\r\n            <div id=\"zoom-controls\" style=\"margin-top: 10px;\">\r\n                <button id=\"zoom-out-btn\" class=\"brush-btn\">-<\/button>\r\n                <button id=\"reset-zoom-btn\" class=\"brush-btn\">Reset Zoom<\/button>\r\n                <button id=\"zoom-in-btn\" class=\"brush-btn\">+<\/button>\r\n            <\/div>\r\n        <\/div>\r\n        <div id=\"canvas-container\">\r\n            <canvas id=\"background-canvas\" width=\"800\" height=\"700\"><\/canvas>\r\n            <canvas id=\"drawing-canvas\" width=\"800\" height=\"700\"><\/canvas>\r\n        <\/div>\r\n        <input type=\"file\" id=\"image-loader\" accept=\"image\/*\" style=\"display:none;\">\r\n        <!-- NEW: Back to Gallery Button -->\r\n        <button id=\"back-to-gallery-btn\" class=\"brush-btn\" style=\"margin-top: 15px;\">Back to Gallery<\/button>\r\n    <\/div>\r\n<\/div>\r\n\r\n<!-- The JavaScript is now inside <script> tags -->\r\n<script>\r\n    (function() {\r\n        \/\/ --- Get All Elements ---\r\n        const galleryView = document.getElementById('gallery-view');\r\n        const galleryGrid = document.getElementById('gallery-grid');\r\n        const coloringView = document.getElementById('coloring-view');\r\n        const backToGalleryBtn = document.getElementById('back-to-gallery-btn');\r\n        \r\n        const backgroundCanvas = document.getElementById('background-canvas');\r\n        const backgroundCtx = backgroundCanvas.getContext('2d');\r\n        const drawingCanvas = document.getElementById('drawing-canvas');\r\n        const drawingCtx = drawingCanvas.getContext('2d');\r\n        \r\n        const colorPalette = document.getElementById('color-palette');\r\n        const brushControls = document.getElementById('brush-controls');\r\n        const eraserBtn = document.getElementById('eraser-btn');\r\n        const clearBtn = document.getElementById('clear-btn');\r\n        const undoBtn = document.getElementById('undo-btn');\r\n        const saveBtn = document.getElementById('save-btn');\r\n        const importBtn = document.getElementById('import-btn');\r\n        const imageLoader = document.getElementById('image-loader');\r\n        \r\n        const zoomInBtn = document.getElementById('zoom-in-btn');\r\n        const zoomOutBtn = document.getElementById('zoom-out-btn');\r\n        const resetZoomBtn = document.getElementById('reset-zoom-btn');\r\n\r\n        \/\/ --- State Variables ---\r\n        let currentColor = 'rgba(255, 0, 0, 0.6)';\r\n        let currentBrushSize = 10;\r\n        let isDrawing = false;\r\n        let isErasing = false;\r\n        let undoState = null;\r\n        let scale = 1.0;\r\n\r\n        \/\/ --- IMPORTANT: Add your image URLs here ---\r\n        const imageUrls = [\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page.jpg',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page01.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page02.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page03.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page04.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page05.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page06.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page07.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page08.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page09.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page10.png',\r\n\t\t\t'https:\/\/homeqi.com\/wp-content\/uploads\/2025\/06\/coloring-page11.png',\r\n            \/\/ Add as many image URLs as you want\r\n        ];\r\n\r\n        \/\/ --- INITIALIZATION ---\r\n        function buildGallery() {\r\n            galleryGrid.innerHTML = ''; \/\/ Clear existing gallery\r\n            imageUrls.forEach(url => {\r\n                const img = document.createElement('img');\r\n                img.src = url;\r\n                img.className = 'gallery-thumbnail';\r\n                img.dataset.fullSrc = url; \/\/ Store full image URL\r\n                galleryGrid.appendChild(img);\r\n            });\r\n        }\r\n\r\n        function loadColoringPage(imageUrl) {\r\n            \/\/ Switch views\r\n            galleryView.classList.add('hidden');\r\n            coloringView.classList.remove('hidden');\r\n\r\n            \/\/ Reset canvases and zoom for the new image\r\n            backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);\r\n            drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);\r\n            scale = 1.0;\r\n            applyScale();\r\n            undoState = null;\r\n            \r\n            \/\/ Load the selected image\r\n            const image = new Image();\r\n            image.src = imageUrl;\r\n            image.crossOrigin = \"anonymous\";\r\n            image.onload = () => {\r\n                backgroundCtx.drawImage(image, 0, 0, backgroundCanvas.width, backgroundCanvas.height);\r\n            };\r\n        }\r\n\r\n        window.onload = () => {\r\n            buildGallery(); \/\/ Build the gallery on page load\r\n            document.querySelector('.color-box[style*=\"red\"]').classList.add('active');\r\n        };\r\n\r\n        \/\/ --- HELPER AND ZOOM FUNCTIONS ---\r\n        function saveUndoState() {\r\n            undoState = drawingCtx.getImageData(0, 0, drawingCanvas.width, drawingCanvas.height);\r\n        }\r\n        \r\n        function applyScale() {\r\n            drawingCanvas.style.transform = `scale(${scale})`;\r\n            backgroundCanvas.style.transform = `scale(${scale})`;\r\n        }\r\n\r\n        function updateScale(delta) {\r\n            scale += delta;\r\n            scale = Math.max(0.2, Math.min(scale, 4));\r\n            applyScale();\r\n        }\r\n\r\n        \/\/ --- EVENT LISTENERS ---\r\n        galleryGrid.addEventListener('click', (e) => {\r\n            if (e.target.classList.contains('gallery-thumbnail')) {\r\n                loadColoringPage(e.target.dataset.fullSrc);\r\n            }\r\n        });\r\n\r\n        backToGalleryBtn.addEventListener('click', () => {\r\n            coloringView.classList.add('hidden');\r\n            galleryView.classList.remove('hidden');\r\n        });\r\n        \r\n        zoomInBtn.addEventListener('click', () => updateScale(0.1));\r\n        zoomOutBtn.addEventListener('click', () => updateScale(-0.1));\r\n        resetZoomBtn.addEventListener('click', () => {\r\n            scale = 1.0;\r\n            applyScale();\r\n        });\r\n        \r\n        \/\/ (Other listeners for controls remain the same)\r\n        colorPalette.addEventListener('click', (e) => {\r\n            if (e.target.classList.contains('color-box')) {\r\n                isErasing = false;\r\n                eraserBtn.classList.remove('active');\r\n                document.querySelector('.color-box.active')?.classList.remove('active');\r\n                e.target.classList.add('active');\r\n                const solidColor = window.getComputedStyle(e.target).backgroundColor;\r\n                const transparentColor = solidColor.replace('rgb', 'rgba').replace(')', ', 0.2)');\r\n                currentColor = transparentColor;\r\n            }\r\n        });\r\n\r\n        brushControls.addEventListener('click', (e) => {\r\n            const clickedButton = e.target.closest('.brush-btn:not(#eraser-btn):not(#clear-btn):not(#undo-btn):not(#save-btn):not(#import-btn)');\r\n            if (clickedButton) {\r\n                currentBrushSize = parseInt(clickedButton.dataset.size);\r\n                document.querySelector('#brush-controls .brush-btn.active')?.classList.remove('active');\r\n                clickedButton.classList.add('active');\r\n            }\r\n        });\r\n\r\n        eraserBtn.addEventListener('click', () => {\r\n            isErasing = true;\r\n            document.querySelector('#brush-controls .brush-btn.active')?.classList.remove('active');\r\n            eraserBtn.classList.add('active');\r\n            document.querySelector('.color-box.active')?.classList.remove('active');\r\n        });\r\n\r\n        clearBtn.addEventListener('click', () => {\r\n            saveUndoState();\r\n            drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);\r\n        });\r\n\r\n        undoBtn.addEventListener('click', () => {\r\n            if (undoState) {\r\n                drawingCtx.putImageData(undoState, 0, 0);\r\n                undoState = null;\r\n            }\r\n        });\r\n\r\n        saveBtn.addEventListener('click', () => {\r\n            try {\r\n                const tempCanvas = document.createElement('canvas');\r\n                const tempCtx = tempCanvas.getContext('2d');\r\n                tempCanvas.width = drawingCanvas.width;\r\n                tempCanvas.height = drawingCanvas.height;\r\n                tempCtx.drawImage(backgroundCanvas, 0, 0);\r\n                tempCtx.drawImage(drawingCanvas, 0, 0);\r\n                const link = document.createElement('a');\r\n                link.download = 'my-coloring-creation.png';\r\n                link.href = tempCanvas.toDataURL('image\/png');\r\n                document.body.appendChild(link);\r\n                link.click();\r\n                document.body.removeChild(link);\r\n            } catch (error) {\r\n                console.error(\"Error saving the image:\", error);\r\n            }\r\n        });\r\n\r\n        importBtn.addEventListener('click', () => {\r\n            imageLoader.click();\r\n        });\r\n\r\n        imageLoader.addEventListener('change', (e) => {\r\n            const file = e.target.files[0];\r\n            if (!file) { return; }\r\n            const reader = new FileReader();\r\n            reader.onload = function(event) {\r\n                const img = new Image();\r\n                img.crossOrigin = \"anonymous\";\r\n                img.onload = function() {\r\n                    backgroundCtx.clearRect(0, 0, backgroundCanvas.width, backgroundCanvas.height);\r\n                    drawingCtx.clearRect(0, 0, drawingCanvas.width, drawingCanvas.height);\r\n                    backgroundCtx.drawImage(img, 0, 0, backgroundCanvas.width, backgroundCanvas.height);\r\n                    undoState = null;\r\n                }\r\n                img.src = event.target.result;\r\n            }\r\n            reader.readAsDataURL(file);\r\n        });\r\n        \r\n        \/\/ --- DRAWING LOGIC (mostly unchanged) ---\r\n        drawingCanvas.addEventListener('mousedown', startDrawing);\r\n        drawingCanvas.addEventListener('mousemove', draw);\r\n        drawingCanvas.addEventListener('mouseup', stopDrawing);\r\n        drawingCanvas.addEventListener('mouseleave', stopDrawing);\r\n        drawingCanvas.addEventListener('touchstart', startDrawing, { passive: false });\r\n        drawingCanvas.addEventListener('touchmove', draw, { passive: false });\r\n        drawingCanvas.addEventListener('touchend', stopDrawing);\r\n\r\n        function startDrawing(e) {\r\n            e.preventDefault();\r\n            saveUndoState();\r\n            isDrawing = true;\r\n            draw(e);\r\n\r\n        }\r\n\r\n        function stopDrawing() {\r\n            isDrawing = false;\r\n            drawingCtx.beginPath();\r\n        }\r\n\r\n        function draw(e) {\r\n            if (!isDrawing) return;\r\n            e.preventDefault();\r\n            const rect = drawingCanvas.getBoundingClientRect();\r\n            let x, y;\r\n            if (e.touches && e.touches.length > 0) {\r\n                x = (e.touches[0].clientX - rect.left) \/ scale;\r\n                y = (e.touches[0].clientY - rect.top) \/ scale;\r\n            } else {\r\n                x = (e.clientX - rect.left) \/ scale;\r\n                y = (e.clientY - rect.top) \/ scale;\r\n            }\r\n\r\n            if (isErasing) {\r\n                drawingCtx.globalCompositeOperation = 'destination-out';\r\n            } else {\r\n                drawingCtx.globalCompositeOperation = 'source-over';\r\n                drawingCtx.strokeStyle = currentColor;\r\n            }\r\n            drawingCtx.lineWidth = currentBrushSize;\r\n            drawingCtx.lineCap = 'round';\r\n            drawingCtx.lineTo(x, y);\r\n            drawingCtx.stroke();\r\n            drawingCtx.beginPath();\r\n            drawingCtx.moveTo(x, y);\r\n        }\r\n    })();\r\n<\/script>\r\n\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-2003","post","type-post","status-publish","format-standard","hentry","category-real-estate"],"_links":{"self":[{"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/posts\/2003","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/homeqi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2003"}],"version-history":[{"count":1,"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/posts\/2003\/revisions"}],"predecessor-version":[{"id":2004,"href":"https:\/\/homeqi.com\/index.php?rest_route=\/wp\/v2\/posts\/2003\/revisions\/2004"}],"wp:attachment":[{"href":"https:\/\/homeqi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2003"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/homeqi.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2003"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/homeqi.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2003"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}