monicaeverett

anitabi_api_test(HTML)

Oct 27th, 2024
127
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 5 5.31 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Anime Location Viewer</title>
  7.   <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
  8.   <script src="https://unpkg.com/lucide@latest/dist/lucide.min.js"></script>
  9. </head>
  10. <body class="min-h-screen bg-black text-white p-4">
  11.  
  12.   <div class="max-w-6xl mx-auto">
  13.     <h1 class="text-3xl font-bold mb-4">Anime Location Viewer</h1>
  14.  
  15.     <div class="mb-6">
  16.       <div class="flex gap-4 mb-4">
  17.         <select id="animeSelect" class="px-4 py-2 border rounded-lg bg-white text-black">
  18.           <option value="">Please select anime you want to view the location</option>
  19.           <option value="464376">負けヒロインが多すぎる!</option>
  20.           <option value="207195">ゆるキャン△</option>
  21.         </select>
  22.        
  23.         <button
  24.          id="loadButton"
  25.          class="bg-blue-500 text-white px-4 py-2 rounded-lg flex items-center gap-2 hover:bg-blue-600 transition-colors"
  26.          disabled
  27.        >
  28.           <i data-lucide="search"></i>
  29.           Load Locations
  30.         </button>
  31.       </div>
  32.     </div>
  33.  
  34.     <div id="error" class="hidden bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4"></div>
  35.  
  36.     <div id="animeContent" class="space-y-6"></div>
  37.   </div>
  38.  
  39.   <script>
  40.     const BangumiIds = {
  41.       "負けヒロインが多すぎる!": "464376",
  42.       "ゆるキャン△": "207195",
  43.     };
  44.  
  45.     const animeSelect = document.getElementById('animeSelect');
  46.     const loadButton = document.getElementById('loadButton');
  47.     const animeContent = document.getElementById('animeContent');
  48.     const errorDiv = document.getElementById('error');
  49.  
  50.     let expandedLocations = {};
  51.  
  52.     const fetchData = async (id) => {
  53.       animeContent.innerHTML = '';
  54.       errorDiv.classList.add('hidden');
  55.      
  56.       try {
  57.         const basicResponse = await fetch(`https://api.anitabi.cn/bangumi/${id}/lite`);
  58.         if (!basicResponse.ok) throw new Error('Failed to fetch basic data');
  59.         const basicData = await basicResponse.json();
  60.  
  61.         const detailResponse = await fetch(`https://api.anitabi.cn/bangumi/${id}/points/detail`);
  62.         if (!detailResponse.ok) throw new Error('Failed to fetch detailed data');
  63.         const detailData = await detailResponse.json();
  64.  
  65.         detailData.sort((a, b) => a.ep === 'OP' ? -1 : (parseInt(a.ep) - parseInt(b.ep)));
  66.  
  67.         displayAnimeData(basicData, detailData);
  68.       } catch (err) {
  69.         errorDiv.textContent = 'Failed to load anime location data. Please try again.';
  70.         errorDiv.classList.remove('hidden');
  71.       }
  72.     };
  73.  
  74.     const displayAnimeData = (animeData, detailData) => {
  75.       const animeInfo = `
  76.         <div class="bg-white text-black rounded-lg shadow p-6">
  77.           <div class="flex items-center gap-4">
  78.             <img src="${animeData.cover}" alt="${animeData.title}" class="w-[10vh] h-[50] object-cover rounded">
  79.             <div>
  80.               <div class="text-2xl font-bold">${animeData.title}</div>
  81.               <div class="text-gray-500">${animeData.city || 'N/A'}</div>
  82.             </div>
  83.           </div>
  84.         </div>
  85.       `;
  86.      
  87.       const locations = detailData.map(point => `
  88.         <div class="bg-white text-black rounded-lg shadow overflow-hidden">
  89.           <div class="relative h-48">
  90.             <img src="${point.image.replace('h160', 'h360')}" alt="${point.name}" class="w-full h-full object-cover">
  91.           </div>
  92.           <div class="p-4">
  93.             <h3 class="font-semibold mb-2">${point.name}</h3>
  94.             ${point.origin ? `<a href="${point.originURL}" target="_blank" class="text-blue-500 hover:text-blue-600">Source: ${point.origin}</a>` : ''}
  95.             <div class="flex items-center gap-4 text-sm text-gray-500">
  96.               <span>Episode ${point.ep || '-'}</span>
  97.               <span>${point.geo.map(coord => coord.toFixed(4)).join(', ')}</span>
  98.             </div>
  99.             ${point.moreImages ? `
  100.               <button onclick="toggleExpandLocation('${point.id}')" class="text-blue-500 mt-2">
  101.                 ${expandedLocations[point.id] ? 'Hide Images' : 'View More Images'}
  102.               </button>
  103.               <div id="extra-images-${point.id}" class="grid grid-cols-2 gap-2 mt-2 ${expandedLocations[point.id] ? '' : 'hidden'}">
  104.                 ${point.moreImages.map(img => `<img src="${img.replace('h160', 'h360')}" alt="Additional view" class="w-full h-24 object-cover">`).join('')}
  105.               </div>
  106.             ` : ''}
  107.           </div>
  108.         </div>
  109.       `).join('');
  110.  
  111.       animeContent.innerHTML = animeInfo + '<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">' + locations + '</div>';
  112.     };
  113.  
  114.     const toggleExpandLocation = (locationId) => {
  115.       expandedLocations[locationId] = !expandedLocations[locationId];
  116.       document.getElementById(`extra-images-${locationId}`).classList.toggle('hidden');
  117.     };
  118.  
  119.     animeSelect.addEventListener('change', (e) => {
  120.       loadButton.disabled = !e.target.value;
  121.     });
  122.  
  123.     loadButton.addEventListener('click', () => {
  124.       if (animeSelect.value) {
  125.         fetchData(animeSelect.value);
  126.       }
  127.     });
  128.  
  129.     lucide.createIcons();
  130.   </script>
  131. </body>
  132. </html>
  133.  
Tags: html
Advertisement
Add Comment
Please, Sign In to add comment