Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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>
like image 953
user8 Avatar asked Nov 14 '22 19:11

user8


1 Answers

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.

  • Libarary: https://github.com/niklasvh/html2canvas
  • Tutorial: https://codepedia.info/convert-html-to-image-in-jquery-div-or-table-to-jpg-png

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

like image 150
Ninz Avatar answered Dec 08 '22 00:12

Ninz