Tengo un cuadro que puede cambiar de color una vez que seleccione el cuadro y luego seleccione el color.
Sin embargo, también hay una imagen de fondo que muestra el contorno de la caja. He usado HTML2canvas y jquery como bibliotecas para poder descargar el cuadro de cambio de color personalizado como una imagen, pero solo se puede descargar localmente si la imagen está oculta, como se muestra en el CSS.
Mi pregunta es, ¿cómo descargo el cuadro de cambio de color personalizable con la imagen del cuadro de contorno de fondo? - o - ¿Hay alguna forma alternativa de guardar la imagen de fondo y el SVG localmente con el botón de descarga?
//////// carousel //////// let sliderImages = document.querySelectorAll('.slide'), arrowLeft = document.querySelector('#arrow-left'), arrowRight = document.querySelector('#arrow-right'), current = 0; //Clear all images function reset() { for (let i = 0; i < sliderImages.length; i++) { sliderImages[i].style.display = 'none'; } } // initialize slider function startSlide() { reset(); sliderImages[0].style.display = "block"; } //show previous function slideLeft() { reset(); sliderImages[current - 1].style.display = "block"; current--; } //show next function slideRight() { reset(); sliderImages[current + 1].style.display = "block"; current++; } //left arrow click arrowLeft.addEventListener('click', function() { if (current === 0) { current = sliderImages.length; } slideLeft(); }); //right arrow click arrowRight.addEventListener('click', function() { if (current === sliderImages.length - 1) { current = -1; } slideRight(); }); startSlide(); const overlays = []; document.querySelectorAll(".product").forEach(function(path) { path.onclick = chooseProduct; }) function chooseProduct(e) { overlays.push(e.target); overlays.forEach((overlay) => overlay.classList.add('highlight')); } //////// remove highlight when clicking outside of image //////// var removeHighlight = function(e) { var products = document.querySelectorAll('.product'); if (!e.target.classList.contains('product') && !e.target.classList.contains('color')) { overlays.length = 0; document.querySelectorAll('.product').forEach(function(prod) { prod.classList.remove('highlight'); }); } } document.onclick = removeHighlight; //////// remove highlight of a specific shape //////// function chooseProduct(e) { for (let i = 0; i < overlays.length; i += 1) { let currentOverlay = overlays[i]; if (currentOverlay.isSameNode(e.target)) { overlays.splice(i, 1); e.target.classList.remove('highlight') return; } } overlays.push(e.target); overlays.forEach((overlay) => overlay.classList.add("highlight")); } //////// get and set colours //////// // Click on a color var el = document.getElementsByClassName("color"); for (var i = 0; i < el.length; i++) { el[i].onclick = changeColor; } function changeColor(e) { // get the hex color let hex = e.target.getAttribute("data-hex"); // set the hex color overlays.forEach((overlay) => overlay.style.fill = hex); } $(document).ready(function() { function saveScreenshot(canvas) { var downloadLink = document.createElement('a'); downloadLink.download = 'download.jpg'; canvas.toBlob(function(blob) { downloadLink.href = URL.createObjectURL(blob) downloadLink.click(); }); } $(".download-btn").on("click", function(e) { e.preventDefault(); html2canvas(document.querySelector(".download-container"), { scrollX: 0, scrollY: 0 }).then(function(canvas) { var image = canvas.toDataURL('image/jpeg'); document.getElementById("created-element").src = image; $(this).attr('href', image); saveScreenshot(canvas); }); }); }); .grid-container { display: grid; grid-template-columns: auto 5% 1fr auto 1fr; grid-template-rows: 128px auto 1fr auto auto auto auto 100px; gap: 0px 0px; grid-auto-flow: row; grid-template-areas: "header . . . ." "main main main color-select color-select" "main main main color-select color-select" "about about about about about" "howto howto howto howto howto" "faqs faqs faqs faqs faqs" "social social social social social" "footer footer footer footer footer"; } .header { grid-area: header; } .logo { display: inline-block; padding-top: 20px; padding-left: 65px; } .navbar { display: inline-block; padding-top: 50px; padding-right: 20px; font-family: 'Roboto Condensed', sans-serif; line-height: 38px; font-weight: 400; font-size: 18px; float: right; } .nav-link { margin: 18px; color: #212529; text-decoration: none; } .main { grid-area: main; background-color: #f8f8f8; padding-top: 20px; padding-bottom: 50px; display: flex; text-align: center; position: relative; margin-top: 2.5px; margin-left: 78px; } #slider, .wrap, .slide-content { max-width: 1000px; position: relative; margin: auto; } .slide-content { display: flex; flex-direction: column; justify-content: center; align-items: center; text-align: center; } .arrow { cursor: pointer; position: absolute; top: 101%; width: 60%; height: 0; z-index: 1; font-size: 20px; color: #cccccc; } #arrow-left { left: 0; } #arrow-right { right: 0; } /* Caption text */ .text { position: relative; color: #212529; font-size: 18px; top: 28px; width: 100%; text-align: center; font-family: 'Roboto Condensed', sans-serif; font-weight: 400; } .lion-number { color: #8f8f8f; } .color-select { display: flex; align-items: center; grid-area: color-select; background-color: #f8f8f8; margin-top: 2.5px; margin-right: 78px; padding: 10px; } body, html { margin: 0; padding: 0; height: 100%; width: 100%; } #container { width: 100%; height: auto; } #product-svg { position: absolute; z-index: 2; background-size: 100%; background-repeat: no-repeat; background-position: 50%; mix-blend-mode: multiply; width: 85%; height: auto; } path { fill: #8f8f8f; } .background-image { position: relative; z-index: 1; width: 85%; height: auto; } [data-test] { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: start; padding-left: 15px; padding-right: 15px; } [data-test] span.color { flex-shrink: 0; display: flex; flex-wrap: wrap; justify-content: center; width: 60px; padding-bottom: 9px; } [data-test] span.color span { height: 23px; width: 20px; background: var(--color); clip-path: polygon(50% 0, 100% 25%, 100% 75%, 50% 100%, 0 75%, 0 25%); margin-bottom: -6px; } [data-test] span.color span:first-child { margin-left: 1px; } .highlight { stroke-width: 10px; stroke: #000; } img { visibility: hidden; } button { font-size: 1.25em; padding: 1em; } <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.js" integrity="sha512-n/4gHW3atM3QqRcbCn6ewmpxcLAHGaDjpEBu4xZd47N0W2oQ+6q7oc3PXstrJYXcbNU1OHdQ1T7pAP+gi5Yu8g==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.2.2/html2canvas.js" integrity="sha512-Alb3nvf6wRVUhs6H8foMA8fuWAKFFretiYkk2WbrMSbAtTtNBOjKLbDIagmFVypIi4wT1pRhHwz+R/W7nU31wg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <div class="grid-container"> <header class="header"> <img class="logo" src="logo.png" alt=""> <nav class="navbar"> <a href=about.html class="nav-link">About</a> <a href=howto.html class="nav-link">How to</a> <a href=faqs.html class="nav-link">FAQs</a> <a href=contact.html class="nav-link">Contact</a> </nav> </header> </div> </div> <main class="main"> <div class="wrap"> <div id="arrow-left" class="arrow"><span>❮</span></div> <div id="arrow-right" class="arrow"><span>❯</span></div> <div id="slider"> <div class="slide slide1"> <div class="slide-content"> <div id="container"> <div class="download-container"> <svg id="product-svg" viewBox="0 0 256 256"> <path id="box1" class="product" d="M24 130.25L24 235L233 235L233 25.5L24 25.5L24 130.25Z" /> </svg> <img class="background-image" src="https://images.vexels.com/media/users/3/139342/isolated/lists/61cddf9cfe50f4baaa8f472c253d1cb4-basic-square-outline.png" alt=""> </div> </div> <div class="text">image1</div> </div> </div> <div class="slide slide1"> <div class="slide-content" <div id="container"> <div class="download-container"> <svg id="product-svg" viewBox="0 0 256 256"> <path id="box2" class="product" d="M24 130.25L24 235L233 235L233 25.5L24 25.5L24 130.25Z" /> </svg> <img class="background-image" src="https://images.vexels.com/media/users/3/139342/isolated/lists/61cddf9cfe50f4baaa8f472c253d1cb4-basic-square-outline.png" alt=""> </div> </div> <div class="text">image2</div> </div> </div> <button class="download-btn">Download element!</button> <img src="" id="created-element" /> </main> <section class="color-select"> <div data-test> <span class="color red"> <span class="color-selected" style="--color: #ff6666 " data-hex="#ff6666"></span> </span> </div> </section> </div>Si desea descargar una imagen con los cambios de fondo que ha realizado, primero debe convertir HTML (la imagen y el fondo juntos) en una imagen utilizando bibliotecas como HTML2Canvas.
Lo que tomaría una captura de pantalla del HTML que se cambia en la página que tiene, luego se descargaría la imagen.