$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);