$DragImage

by mtambulut

HTML

<div class="drop-it-hot" id="drop-area">
  <div class="circle">
    <svg fill="currentColor" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
      <path d="M0 0h24v24H0z" fill="none"/>
      <path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/>
  </svg>
  </div>
  <form class="choose-files">
    <div class="button-wrapper">
          <label class="label" for="fileElem">Drag image here to upload or</label>
      <button type="button" class="btn">Choose image</button>
      <input type="file" id="fileElem" multiple accept="image/*" onchange="handleFiles(this.files)">
    </div>
  </form>
  <div id="gallery"></div>
</div>

<div class="editor">
  <div class="range-wrapper">
    <label for="contrast">Contrast</label>
    <input class="range" name="contrast" value="100" type="range" min="0" max="200" value="0" data-unit="%">
  </div>
  <div class="range-wrapper">
    <label for="brightness">Brightness</label>
    <input class="range" name="brightness" value="100" type="range" min="0" max="200" data-unit="%">
  </div>
  <div class="range-wrapper">
    <label for="blur">Hue</label>
    <input class="range" name="hue-rotate" value="0" type="range" min="0" max="200" data-unit="deg">
  </div>
  <div class="range-wrapper">
    <label for="sepia">Sepia</label>
    <input class="range" name="sepia" value="0" type="range" min="0" max="200" data-unit="%">
  </div>
</div>

SCSS

:root {
  --contrast: 100%;
  --brightness: 100%;
  --hue-rotate: 0deg;
  --sepia: 0%;
  --accent: #4A90E2;
  --dark-accent: #3F7AC0;
  --gray: #E6E7F0;
  --dark-gray: #4E5056;
}

* {
  padding: 0;
  margin: 0;
}

body {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 100vh;
  width: 100vw;
  background-image: linear-gradient(0deg, #EBFCFF 0%, #FFFFFF 89%);
  font-family: Roboto, sans-serif;
}

// Drop area

.drop-it-hot {
  background-color: white;
  border-radius: 15px;
  width: 700px;
  height: 500px;
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 8px 15px 0 rgba(black, .1);
  overflow: hidden;
  
  &:after {
    content: '';
    position: absolute;
    width: calc(100% - 20px);
    height: calc(100% - 20px);
    border: 2px dashed var(--gray);
    border-radius: 5px;
    z-index: 0;
  }
  
  .circle {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    position: absolute;
    color: var(--accent);
    background-color: white;
    border: 3px solid var(--gray);
    width: 100px;
    height: 100px;
  }
}

.circle {
  transition: transform 150ms ease-in;
  z-index: 10;

  svg {
    width: 40px;
    height: 40px;
  }
  
  &:before {
    content: '';
    background-color: var(--accent);
    width: 130px;
    height: 130px;
    border-radius: 50%;
    position: absolute;
    opacity: 0;
    transition: transform 250ms ease-in, opacity 200ms ease-in;
    z-index: 0;
  }
  
  &:after {
    content: '';
    position: absolute;
    width: 100px;
    height: 100px;
    border-radius: 50%;
  }
  
  &:hover {
    transform: scale(1.2);
    opacity: .9;

    &:before {
      transform: scale(8);
      opacity: 1;
    }
    
    &:after {
      border: 3px solid white;
    }
    svg {
      color: white;
      z-index: 1;
    }
  }
}

.highlight { 

  &:before {
    transform: scale(8);
    opacity: 1;
  }
  
 ...

JavaScript

const dragEvents = ['dragenter', 'dragover', 'dragleave', 'drop'];
const dragHighlight = ['dragenter', 'dragover'];
const dragUnighlight = ['dragleave', 'drop'];
const inputRange = document.querySelectorAll('.editor input');

const dropArea = document.getElementById('drop-area');
const iconElement = document.querySelector('.circle');
const editorElement = document.querySelector('.editor');

const preventDefaults = (e) => {
  e.preventDefault();
  e.stopPropagation();
};

const highlight = () => {
  iconElement.classList.add('highlight');
};

const unhighlight = () => {
  iconElement.classList.remove('highlight');
};

const previewFile = (file) => {
  let reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onloadend = function() {
    let img = document.createElement('img');
    img.src = reader.result;
    document.getElementById('gallery').appendChild(img);
    editorElement.classList.add('is-visible');
  }
};

const handleFiles = (files) => {
  files = [...files];
  files.forEach(previewFile);
};

const handleDrop = (e) => {
  let dt = e.dataTransfer;
  let files = dt.files;
  
  console.log('files', files);

  handleFiles(files);
};

function handleUpdate() {
  console.log(this.value);
  const suffix = this.dataset.unit;
  document.documentElement.style.setProperty(`--${this.name}`, this.value + suffix);
}

inputRange.forEach(input => input.addEventListener('change', handleUpdate));
inputRange.forEach(input => input.addEventListener('mousemove', handleUpdate));

dragEvents.forEach(eventName => {
  dropArea.addEventListener(eventName, preventDefaults, false)
});

dragHighlight.forEach(eventName => {
  dropArea.addEventListener(eventName, highlight, false)
});

dragUnighlight.forEach(eventName => {
  dropArea.addEventListener(eventName, unhighlight, false)
});


dropArea.addEventListener('drop', handleDrop, false);