Исходя из вашего кода, вы должны:
- клонировать
cam1
при mousedown. - Добавить верхний и левый свойства
cam1
к клонированному объекту. - Добавьте к телу, затем переместите клонированный объект и добавьте к нему соответствующие события.
Я буду использовать jQuery, поскольку он включен во фрагмент выше.
Изменить:
Код ниже для перетаскивания всех изображений не только cam1
:
// 1 - wall, 0 - free/street
const map1 = [
[1, 1, 1, 1],
[0, 0, 0, 0],
[1, 0, 1, 1],
[1, 0, 0, 0]
];
const city = map1;
const size = 41;
window.onload = function() {
const canvas = document.getElementById("canvas");
const ctx = canvas.getContext("2d");
//draw images
const p = ctx.lineWidth; //padding
for (let i = 0; i < city.length; i++) {
for (let j = 0; j < city[i].length; j++) {
const x = i * size;
const y = j * size;
const img = new Image();
img.onload = function() {
ctx.drawImage(img, x, y, size + p * 2, size + p * 2);
};
img.src = city[i][j] == 0 ? "images/white.png" : "images/black.png";
}
}
};
$(document).ready(function() {
let currentDroppable = null, clone;
function moveAt(pageX, pageY, shiftX, shiftY) {
clone.style.left = pageX - shiftX + 'px';
clone.style.top = pageY - shiftY + 'px';
}
function onMouseMove(event) {
moveAt(event.pageX, event.pageY, 0, 0);
clone.hidden = true;
let elemBelow = document.elementFromPoint(event.clientX, event.clientY);
clone.hidden = false;
if (!elemBelow) return;
let droppableBelow = elemBelow.closest('#canvas');
if (currentDroppable != droppableBelow) {
if (currentDroppable) { // null when we were not over a droppable before this event
leaveDroppable(currentDroppable);
}
currentDroppable = droppableBelow;
if (currentDroppable) { // null if we're not coming over a droppable now
// (maybe just left the droppable)
enterDroppable(currentDroppable);
}
}
}
$(document).on('mousedown', '.drag', function(e){
var tmp = $(this).clone().removeClass("drag");
$(tmp).css({position: 'absolute', top: $(this).offset().top + "px", left: $(this).offset().left + "px", opacity: 1, 'z-index': 1000});
$('body').append($(tmp));
clone = $(tmp)[0];
let shiftX = event.clientX - clone.getBoundingClientRect().left;
let shiftY = event.clientY - clone.getBoundingClientRect().top;
moveAt(event.pageX, event.pageY, shiftX, shiftY);
document.addEventListener('mousemove', onMouseMove);
clone.onmouseup = function() {
document.removeEventListener('mousemove', onMouseMove);
clone.onmouseup = null;
};
});
function enterDroppable(elem) {
elem.style.background = 'blue';
}
function leaveDroppable(elem) {
elem.style.background = '';
}
cam1.ondragstart = function() {
return false;
};
});
body {
color: #000;
}
h1,
footer {
text-align: center;
margin-top: 10px;
}
#game {
border: 1px solid #666;
position: relative;
width: 600px;
height: 450px;
margin: 0 auto;
z-index: 1;
background-color: gold;
}
.drag {
cursor: pointer;
}
#canvas {
cursor: pointer;
}
.cameras {
position: absolute;
flex-direction: column;
flex-wrap: wrap;
right: 0;
top: 0;
z-index: 200;
display: flex;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>cameras of the city</title>
<link rel="stylesheet" href="js/jquery-ui-1.12.1/jquery-ui.min.css">
<link rel="stylesheet" href="styles.css">
<script src="js/jquery-3.4.1.js"></script>
<script src="js/jquery-ui-1.12.1/jquery-ui.min.js"></script>
</head>
<body>
<header>
<h1>cameras of the city</h1>
</header>
<div id="game">
<canvas height="450px" width="450px" id="canvas"></canvas>
<div class="cameras">
<img id="cam1" class="drag" src="images/camera1.png">
<img id="cam2" class="drag" src="images/camera2.png">
<img id="cam3" class="drag" src="images/camera3.png">
<img id="cam4" class="drag" src="images/camera4.png">
</div>
</div>
<footer>
created:
</footer>
<script src="js/core.js"></script>
</body>
</html>