How to download customisable color change box as image with the background image?
Asked Answered
M

1

6

I have a box that can change color once you select the box and then select the color.

However, there is also a background image that shows the outline of the box. I have used HTML2canvas and jquery as libraries so I can download the customise color change box as an image, but it could only be downloaded locally if the image is hidden - as shown on the CSS.

My question is, how do I download the customisable color change box with the background outline box image? - or - Is there an alternative way to save the background image and the SVG locally with download button?

//////// 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>&#10094;</span></div>
      <div id="arrow-right" class="arrow"><span>&#10095;</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>
Mcavoy answered 13/8, 2021 at 10:20 Comment(7)
"how do I download the customisable color change box with the background outline box image." — It's not really understandable what you're trying to achieve. So you want to be able to download the given image first and once it has been changed to red, you want to be able to download that red square as an image file without showing the previous image at all?Indigestive
I want to be able to download the red square and the background image as a new image when click on the buttonMcavoy
But you want the background image always to be visible? So it's basically just the border that should turn from black to red, not the entire plane like it is in your demo right now?Indigestive
Yes, I want the background image border to be visible and the element square that change color, and then be able to download as an image.Mcavoy
But without showing the 10px black selection border? Could you add an image to your question with the expected output?Indigestive
The image is already there, but somehow its not display.Mcavoy
I mean a picture of the actual end result as you imagine it.Indigestive
A
1

If you want to download an image with the background changes that you have made then you first need to convert HTML(Image and the background together) into an image using libraries like HTML2Canvas.

Which would take a screenshot of the HTML that is changed on the page that you have then the image would be downloaded.

Amido answered 23/8, 2021 at 15:21 Comment(1)
I have tried to use HTML to Canvas, but somehow it doesn't include the background image, only color change.Mcavoy

© 2022 - 2024 — McMap. All rights reserved.