我已经实现了以下代码段中的功能,以拖动和交换本地照片,并且它的工作原理很吸引人。但是,现在我想用此URL https://picsum.photos/v2/list?page=2&中的图像替换本地数组,同时仍保持拖放功能。我该如何实现?
Index.html(完整的CSS和javascript代码)
<html>
<head>
<title>Drag and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body { background: rgb(255, 246, 231); }
* { margin: 0; padding: 0; font-family: 'Roboto Slab', serif; }
.dd-vc { position: relative; top: 50%; transform: translateY(-50%); }
.dd-transition { transition: all 0.3s ease; }
.dd-shadow { box-shadow: 0 0 3px 1px rgba(0,0,0,0.3); }
#dragDrop { width: 1000px; margin: 20px auto 0; position: relative; }
.dd-slot { float: left; outline: 2px dashed rgba(54, 86, 132, 0.75); outline-offset: -15px; position: relative; pointer-events: none; }
.dd-slot-num { text-align: center; color: rgba(0,0,0,0.1); font-size: 40px; position: absolute; width: 100%; }
.dd-item { position: absolute; left: 0; top: 0; box-sizing: border-box; padding: 10px; cursor: pointer; }
.dd-item.dd-disabled { pointer-events: none; opacity: 0; }
.dd-item.dd-selected { z-index: 20; }
.dd-item-inner { background-repeat: no-repeat; background-size: cover; background-position: center; width: 100%; height: 100%; position: relative; }
.dd-item-panel { width: 80%; height: 35px; background: #fff; position: absolute; left: 10%; bottom: -15px; z-index: 5; }
.dd-item-title { font-size: 15px; color: #365684; text-align: center; line-height: 35px; }
</style>
</head>
<body>
<div id="dragDrop"></div>
<script>
(function () {
var _doc = window.document;
var _numOfImageSlots = 12,
_numOfImagesPerRow = 3,
_imageMarginBottom = 30;
var _imageAspectWidth = 1920,
_imageAspectHeight = 1080;
var _imageSlots = [],
_selectedImageElement = null,
_originalImageSlot = null,
_originalClickCoords = null,
_lastTouchedSlotId = null;
var _imageLibrary = [
{ id: 23, image: 'beach.jpg', title: 'Beach' },
{ id: 67, image: 'bridge.jpg', title: 'Bridge' },
{ id: 42, image: 'moon.jpg', title: 'Moon' },
{ id: 28, image: 'ocean.jpg', title: 'Paradise' },
{ id: 5567, image: 'sunrise.jpg', title: 'Sunrise' },
{ id: 879, image: 'tree.jpg', title: 'Tree' },
{ id: 314, image: 'waterfall.jpg', title: 'Waterfall' },
{ id: 57, image: 'winter.jpg', title: 'Winter' }
],
_listedImageIds = [ 23, 42, 5567, 57, 28, 879 ];
function init () {
addImageSlots();
drawImages();
_doc.getElementById('dragDrop').addEventListener('mousemove', imageMousemove);
}
function addImageSlots () {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
for ( ; i < len; i++ ) {
item = _doc.createElement('div');
item.setAttribute('class', 'dd-slot');
item.setAttribute('style', 'width:' + ( 100 / _numOfImagesPerRow ) + '%;padding-bottom:' + ( ( 100 / _numOfImagesPerRow ) * ( _imageAspectHeight / _imageAspectWidth ) ) + '%;margin-bottom:' + _imageMarginBottom + 'px;');
item.innerHTML = '<p class="dd-slot-num dd-vc">' + ( i + 1 ) + '</p>';
wrap.appendChild(item);
}
}
function drawImages () {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
var slot = _doc.getElementsByClassName('dd-slot')[0],
bounds = slot.getBoundingClientRect(),
itemWidth = bounds.width,
itemHeight = bounds.height;
var itemX,
itemY;
var imageId,
image;
for ( ; i < len; i++ ) {
imageId = _listedImageIds[i] || -1;
image = getImageById( imageId );
itemX = ( i % _numOfImagesPerRow ) * itemWidth;
itemY = Math.floor( i / _numOfImagesPerRow ) * ( itemHeight + _imageMarginBottom );
item = _doc.createElement('div');
item.setAttribute('class', 'dd-item dd-transition' + ( imageId < 0 ? ' dd-disabled' : '' ));
item.setAttribute('data-image-id', imageId);
item.setAttribute('style', 'width:' + itemWidth + 'px;height:' + itemHeight + 'px;transform:translate3d(' + itemX + 'px,' + itemY + 'px,0);' );
item.innerHTML = '<div class="dd-item-inner dd-shadow" style="' + ( image ? ( 'background-image:url(images/' + image.image + ')' ) : '' ) + '"><div class="dd-item-panel dd-shadow"><h3 class="dd-item-title">' + ( image ? image.title : '' ) + '</h3></div></div>';
wrap.appendChild(item);
item.addEventListener('mousedown', imageMousedown);
item.addEventListener('mouseup', imageMouseup);
_imageSlots[i] = { width: itemWidth, height: itemHeight, x: itemX, y: itemY };
}
}
function arrangeItems () {
var i = 0,
len = _listedImageIds.length,
slot,
ele;
for ( ; i < len; i++ ) {
slot = _imageSlots[i];
ele = _doc.querySelector('[data-image-id="' + _listedImageIds[i] + '"]');
ele.style.transform = 'translate3d(' + slot.x + 'px,' + slot.y + 'px,0)';
}
}
function imageMousedown ( event ) {
if ( !_selectedImageElement ) {
_selectedImageElement = event.currentTarget;
_originalClickCoords = { x: event.pageX, y: event.pageY };
_originalImageSlot = getIndexOfImageId( _selectedImageElement.getAttribute('data-image-id') );
_selectedImageElement.classList.add('dd-selected');
_selectedImageElement.classList.remove('dd-transition');
}
}
function imageMousemove ( event ) {
if ( _selectedImageElement ) {
var wrap = _doc.getElementById('dragDrop'),
bounds = wrap.getBoundingClientRect(),
left = bounds.left,
top = bounds.top;
var pageX = event.pageX,
pageY = event.pageY;
var clickX = pageX - left,
clickY = pageY - top,
hoverSlotId = getSlotIdByCoords( { x: clickX, y: clickY } );
var ele = _selectedImageElement,
imageId = ele.getAttribute('data-image-id'),
index = _originalImageSlot,
newIndex = getIndexOfImageId( imageId ),
x = _imageSlots[index].x,
y = _imageSlots[index].y;
var resultX = x + ( pageX - _originalClickCoords.x ),
resultY = y + ( pageY - _originalClickCoords.y );
if ( hoverSlotId != undefined && _lastTouchedSlotId != hoverSlotId ) {
_lastTouchedSlotId = hoverSlotId;
_listedImageIds.splice( hoverSlotId, 0, _listedImageIds.splice( newIndex, 1 )[0] );
arrangeItems();
}
ele.style.transform = 'translate3d(' + resultX + 'px,' + resultY + 'px,0)';
}
}
function imageMouseup () {
_selectedImageElement.classList.remove('dd-selected');
_selectedImageElement.classList.add('dd-transition');
_selectedImageElement = null;
_originalClickCoords = null;
arrangeItems();
}
function getSlotIdByCoords ( coords ) {
// Get the current slot being hovered over
for ( var id in _imageSlots ) {
var slot = _imageSlots[id];
if ( slot.x <= coords.x && coords.x <= slot.x + slot.width && slot.y <= coords.y && coords.y <= slot.y + slot.height )
return id;
}
}
function getImageById ( id ) {
return _imageLibrary.find(function (image) {
return image.id == id;
});
}
function getIndexOfImageId ( id ) {
var i = 0,
len = _listedImageIds.length;
for ( ; i < len; i++ )
if ( _listedImageIds[i] == id )
return i;
}
init();
})();
</script>
</body>
</html>
(我认为解决方案将看起来像这样)
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
fetch(url)
.then((response) => { return response.json(); })
.then( data => {...}
您需要将功能更改为异步,以便可以等待从API获取图像。根据您的需求映射数据。
样本:
(async function () {
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
const response = await fetch(url).then((response) => response.json())
const _imageLibrary = response.map(img => {
img.image = img.download_url
img.title = img.author
return img
})
<html>
<head>
<title>Drag and Drop</title>
<link href="https://fonts.googleapis.com/css?family=Roboto+Slab" rel="stylesheet">
<style>
body {
background: rgb(255, 246, 231);
}
* {
margin: 0;
padding: 0;
font-family: 'Roboto Slab', serif;
}
.dd-vc {
position: relative;
top: 50%;
transform: translateY(-50%);
}
.dd-transition {
transition: all 0.3s ease;
}
.dd-shadow {
box-shadow: 0 0 3px 1px rgba(0, 0, 0, 0.3);
}
#dragDrop {
width: 1000px;
margin: 20px auto 0;
position: relative;
}
.dd-slot {
float: left;
outline: 2px dashed rgba(54, 86, 132, 0.75);
outline-offset: -15px;
position: relative;
pointer-events: none;
}
.dd-slot-num {
text-align: center;
color: rgba(0, 0, 0, 0.1);
font-size: 40px;
position: absolute;
width: 100%;
}
.dd-item {
position: absolute;
left: 0;
top: 0;
box-sizing: border-box;
padding: 10px;
cursor: pointer;
}
.dd-item.dd-disabled {
pointer-events: none;
opacity: 0;
}
.dd-item.dd-selected {
z-index: 20;
}
.dd-item-inner {
background-repeat: no-repeat;
background-size: cover;
background-position: center;
width: 100%;
height: 100%;
position: relative;
}
.dd-item-panel {
width: 80%;
height: 35px;
background: #fff;
position: absolute;
left: 10%;
bottom: -15px;
z-index: 5;
}
.dd-item-title {
font-size: 15px;
color: #365684;
text-align: center;
line-height: 35px;
}
</style>
</head>
<body>
<div id="dragDrop"></div>
<script>
(async function () {
const url = 'https://picsum.photos/v2/list?page=2&limit=9';
const response = await fetch(url).then((response) => response.json())
console.log(response)
const _imageLibrary = response.map(img => {
img.image = img.download_url
img.title = img.author
return img
})
const _listedImageIds = _imageLibrary.map(({id}) => id)
var _doc = window.document;
var _numOfImageSlots = 12,
_numOfImagesPerRow = 3,
_imageMarginBottom = 30;
var _imageAspectWidth = 1920,
_imageAspectHeight = 1080;
var _imageSlots = [],
_selectedImageElement = null,
_originalImageSlot = null,
_originalClickCoords = null,
_lastTouchedSlotId = null;
function init() {
addImageSlots();
drawImages();
_doc.getElementById('dragDrop').addEventListener('mousemove', imageMousemove);
}
function addImageSlots() {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
for (; i < len; i++) {
item = _doc.createElement('div');
item.setAttribute('class', 'dd-slot');
item.setAttribute('style', 'width:' + (100 / _numOfImagesPerRow) + '%;padding-bottom:' + ((100 /
_numOfImagesPerRow) * (_imageAspectHeight / _imageAspectWidth)) + '%;margin-bottom:' +
_imageMarginBottom + 'px;');
item.innerHTML = '<p class="dd-slot-num dd-vc">' + (i + 1) + '</p>';
wrap.appendChild(item);
}
}
function drawImages() {
var i = 0,
len = _numOfImageSlots,
item;
var wrap = _doc.getElementById('dragDrop');
var slot = _doc.getElementsByClassName('dd-slot')[0],
bounds = slot.getBoundingClientRect(),
itemWidth = bounds.width,
itemHeight = bounds.height;
var itemX,
itemY;
var imageId,
image;
for (; i < len; i++) {
imageId = _listedImageIds[i] || -1;
image = getImageById(imageId);
itemX = (i % _numOfImagesPerRow) * itemWidth;
itemY = Math.floor(i / _numOfImagesPerRow) * (itemHeight + _imageMarginBottom);
item = _doc.createElement('div');
item.setAttribute('class', 'dd-item dd-transition' + (imageId < 0 ? ' dd-disabled' : ''));
item.setAttribute('data-image-id', imageId);
item.setAttribute('style', 'width:' + itemWidth + 'px;height:' + itemHeight +
'px;transform:translate3d(' +
itemX + 'px,' + itemY + 'px,0);');
console.log(image)
item.innerHTML = '<div class="dd-item-inner dd-shadow" style="' + (image ? (
'background-image:url(' +
image.image + ')') : '') + '"><div class="dd-item-panel dd-shadow"><h3 class="dd-item-title">' + (
image ? image.title : '') + '</h3></div></div>';
wrap.appendChild(item);
item.addEventListener('mousedown', imageMousedown);
item.addEventListener('mouseup', imageMouseup);
_imageSlots[i] = {
width: itemWidth,
height: itemHeight,
x: itemX,
y: itemY
};
}
}
function arrangeItems() {
var i = 0,
len = _listedImageIds.length,
slot,
ele;
for (; i < len; i++) {
slot = _imageSlots[i];
ele = _doc.querySelector('[data-image-id="' + _listedImageIds[i] + '"]');
ele.style.transform = 'translate3d(' + slot.x + 'px,' + slot.y + 'px,0)';
}
}
function imageMousedown(event) {
if (!_selectedImageElement) {
_selectedImageElement = event.currentTarget;
_originalClickCoords = {
x: event.pageX,
y: event.pageY
};
_originalImageSlot = getIndexOfImageId(_selectedImageElement.getAttribute('data-image-id'));
_selectedImageElement.classList.add('dd-selected');
_selectedImageElement.classList.remove('dd-transition');
}
}
function imageMousemove(event) {
if (_selectedImageElement) {
var wrap = _doc.getElementById('dragDrop'),
bounds = wrap.getBoundingClientRect(),
left = bounds.left,
top = bounds.top;
var pageX = event.pageX,
pageY = event.pageY;
var clickX = pageX - left,
clickY = pageY - top,
hoverSlotId = getSlotIdByCoords({
x: clickX,
y: clickY
});
var ele = _selectedImageElement,
imageId = ele.getAttribute('data-image-id'),
index = _originalImageSlot,
newIndex = getIndexOfImageId(imageId),
x = _imageSlots[index].x,
y = _imageSlots[index].y;
var resultX = x + (pageX - _originalClickCoords.x),
resultY = y + (pageY - _originalClickCoords.y);
if (hoverSlotId != undefined && _lastTouchedSlotId != hoverSlotId) {
_lastTouchedSlotId = hoverSlotId;
_listedImageIds.splice(hoverSlotId, 0, _listedImageIds.splice(newIndex, 1)[0]);
arrangeItems();
}
ele.style.transform = 'translate3d(' + resultX + 'px,' + resultY + 'px,0)';
}
}
function imageMouseup() {
_selectedImageElement.classList.remove('dd-selected');
_selectedImageElement.classList.add('dd-transition');
_selectedImageElement = null;
_originalClickCoords = null;
arrangeItems();
}
function getSlotIdByCoords(coords) {
// Get the current slot being hovered over
for (var id in _imageSlots) {
var slot = _imageSlots[id];
if (slot.x <= coords.x && coords.x <= slot.x + slot.width && slot.y <= coords.y && coords.y <= slot.y +
slot
.height)
return id;
}
}
function getImageById(id) {
return _imageLibrary.find(function (image) {
return image.id == id;
});
}
function getIndexOfImageId(id) {
var i = 0,
len = _listedImageIds.length;
for (; i < len; i++)
if (_listedImageIds[i] == id)
return i;
}
init();
})();
</script>
</body>
</html>