JSFiddle - React, Tailwind, and code Playground
by Nickolay Ilchenko
HTML
<h2>Расставьте супергероев по полю.</h2>
Требования:
<ol>
<li>Элементы с class="draggable" должно быть можно переносить.</li>
<li>Поддержка документов со скроллом.</li>
</ol>
<div id="field">
</div>
<div class="hero draggable" id="hero1"></div>
<div class="hero draggable" id="hero2"></div>
<div class="hero draggable" id="hero3"></div>
<div class="hero draggable" id="hero4"></div>
<div class="hero draggable" id="hero5"></div>
<div id="winnie" class="draggable"></div>
<img src="http://ru.lookatcode.com/show/744548496324569/ball.png" class="draggable">
<div style="clear:both"></div>
CSS
html, body {
margin: 0;
padding: 0;
}
.draggable
{
cursor: move !important;
}
#field {
background: url(http://ru.lookatcode.com/show/744548496324569/field.png);
width: 800px;
height: 600px;
float: left;
}
.hero {
background: url(http://ru.lookatcode.com/show/744548496324569/heroes.png);
width: 105px;
height: 128px;
float: left;
}
#hero1 {
background-position: 0 0;
}
#hero2 {
background-position: 0 -128px;
}
#hero3 {
background-position: -131px 0;
}
#hero4 {
background-position: -131px -128px;
}
#hero5 {
background-position: -236px 0;
width: 130px;
}
#winnie {
background: url(http://ru.lookatcode.com/show/744548496324569/winnie.png);
width: 115px;
height: 128px;
float: left;
}
.draggable {
cursor: pointer;
}
.dragging {
z-index: 1000;
position: absolute;
cursor: move;
}
JavaScript
var dragElem = document.querySelectorAll('.draggable');
console.log(dragElem[4]);
for(var i = 0; i < dragElem.length; i++) {
dragElem[i].onmousedown = function(event) {
var self = this,
coords = getCoords(self),
shiftX = event.pageX - coords.left,
shiftY = event.pageY - coords.top;
prepare();
moveAt(event);
document.onmousemove = function(event) {
moveAt(event);
}
document.onmouseup = function() {
document.onmouseup = document.onmousemove = null;
}
function prepare() {
self.style.position = 'absolute';
self.style.zIndex = '1000';
}
function moveAt(event) {
self.style.left = event.pageX - shiftX + 'px';
self.style.top = event.pageY - shiftY + 'px';
}
}
dragElem[i].ondragstart = function() {
return false;
}
}
/**
* Координаты элемента относительно документа.
* Могут быть дробными
* @param {Element} elem Элемент
* @return {object} {top: верхняя, left: левая}
*/
function getCoords(elem) {
var box = elem.getBoundingClientRect();
var body = document.body;
var docElem = document.documentElement;
var scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
var scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
var clientTop = docElem.clientTop || body.clientTop || 0;
var clientLeft = docElem.clientLeft || body.clientLeft || 0;
var top = box.top + scrollTop - clientTop;
var left = box.left + scrollLeft - clientLeft;
return { top: top, left: left };
}