JSFiddle - React, Tailwind, and code Playground
by Kanatantsin
HTML
<div class="layout" id="layout">
<h2 class="layout__title">iLayout</h2>
<div class="layout__hint">Перетащите изображения в соответстующие части коллажа, нажмите на кнопку «Получить коллаж» и наслаждайтесь магией!</div>
<div class="layout__positions">
<div class="layout__item layout__item_left"></div>
<div class="layout__item layout__item_top"></div>
<div class="layout__item layout__item_bottom"></div>
</div>
<div class="layout__controls">
<button class="layout__button">Получить коллаж</button>
</div>
<textarea class="layout__result" readonly placeholder="Здесь будет размещён HTML-код вашего коллажа"></textarea>
</div>
CSS
body {
margin: 0;
font-family: Helvetica;
}
.layout {
padding: 10px;
box-sizing: border-box;
}
.layout__hint {
margin: 10px 0;;
}
.layout__positions {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-areas:
'left top'
'left bottom';
height: 50vh;
}
.layout__item {
box-sizing: border-box;
overflow: hidden;
position: relative;
}
.layout__controls {
margin: 10px 0;
}
.layout__button {
border-radius: 6px;
background: blue;
color: #fff;
border: none;
height: 40px;
width: 200px;
cursor: pointer;
font-size: 14px;
text-transform: uppercase;
}
.layout__result {
width: 100%;
height: 40px;
}
.layout__image {
position: absolute;
left: 0;
top: 0;
width: 100%;
}
.layout__item_active {
border: 4px dashed black;
}
.layout__item_left {
grid-area: left;
background: rgb(228, 228, 228);
}
.layout__item_top {
grid-area: top;
background: rgb(186, 196, 255);
}
.layout__item_bottom {
grid-area: bottom;
background: rgb(149, 188, 160);
}
JavaScript
const addClass = ( className, context ) => context.classList.add( className ),
removeClass = ( className, context ) => context.classList.remove( className ),
hasClass = ( className, context ) => context.classList.contains( className );
class iLayout {
constructor( container ) {
this.container = container;
this.positionsContainer = container.querySelector( '.layout__positions' );
this.actionButton = container.querySelector( '.layout__button' );
this.result = container.querySelector( '.layout__result' );
this.layout = {
left: document.querySelector('.layout__item_left'),
top: document.querySelector('.layout__item_top'),
bottom: document.querySelector('.layout__item_bottom')
};
this.canvas = document.createElement('canvas');
this.canvas.width = this.positionsContainer.getBoundingClientRect().width;
this.canvas.height = this.positionsContainer.getBoundingClientRect().height;
this.ctx = this.canvas.getContext('2d');
this.files = [];
this.registerEvents();
}
load(event) {
event.preventDefault();
event.target.innerHTML = '';
const file = event.dataTransfer.files[0],
img = document.createElement('img');
img.src = URL.createObjectURL(file);
img.classList.add('layout__image');
event.target.appendChild(img);
event.target.classList.remove('layout__item_active');
const iwidth = event.target.clientWidth,
iheight = event.target.clientHeight;
let ix = event.target.offsetLeft, iy = 0;
if (event.target === this.layout.bottom) {
iy = event.target.clientHeight - 1;
}
img.addEventListener('load', () => {
this.ctx.drawImage(img, 0, 0, iwidth, iheight, ix, iy, iwidth, iheight);
URL.revokeObjectURL(img.src);
})
}
generateImg(event) {
event.preventDefault();
this.result.value = `<img src="${this.canvas.toDataURL()}">`;
}
registerEvents() {
...