我想用api中的本地数组替换本地数组,同时在javascript中保持相同的功能。我该如何实现?

问题描述 投票:0回答:1

我已经实现了以下代码段中的功能,以拖动和交换本地照片,并且它的工作原理很吸引人。但是,现在我想用此URL https://picsum.photos/v2/list?page=2&amp中的图像替换本地数组,同时仍保持拖放功能。我该如何实现?

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&amp;limit=9';
 fetch(url)
 .then((response) => { return response.json(); })
 .then( data => {...} 
javascript arrays url iteration mapping
1个回答
0
投票

您需要将功能更改为异步,以便可以等待从API获取图像。根据您的需求映射数据。

样本:

(async function () {
      const url = 'https://picsum.photos/v2/list?page=2&amp;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&amp;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>
© www.soinside.com 2019 - 2024. All rights reserved.