Header Ads

CODEFLARE ADVERTISING
OPEN AD SPACE
Pasang Iklan di CodeFlare
Promosikan bisnis, produk, website atau layanan Anda.
SLOT TERSEDIA
PASANG IKLAN
  • NASA Planet Explorer untuk Blogger: Widget Gambar Planet Terbaru dari NASA

    NASA Planet Explorer widget gambar planet terbaru untuk Blogger

    NASA Planet Explorer adalah widget Blogger yang menampilkan gambar planet, Matahari, Bulan, asteroid, komet, galaksi, pesawat antariksa, dan objek luar angkasa lain dari NASA Image and Video Library. Widget ini dibuat dengan HTML, CSS, dan native JavaScript sehingga dapat dipasang langsung pada Blogger tanpa jQuery, tanpa Worker, dan tanpa proxy tambahan.

    Data gambar diambil langsung dari endpoint pencarian NASA Images API. Pengunjung dapat memilih kategori seperti Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Dwarf Planets, Asteroids & Comets, Universe, Spacecraft, Moon, hingga Exoplanets. Setiap kategori memakai satu feed engine yang sama, lalu hasilnya difilter, diurutkan berdasarkan tanggal, dan dibersihkan dari duplikat berdasarkan nasa_id.

    Informasi SingkatWidget menggunakan NASA Image and Video Library, native JavaScript, cache feed per kategori, lazy loading, preload gambar berikutnya, modal detail, swipe mobile, keyboard navigation, serta desain responsif.

    Apa Itu NASA Planet Explorer?

    NASA Planet Explorer dibuat untuk menampilkan koleksi gambar NASA dalam bentuk widget visual yang lebih nyaman dibanding membuka arsip gambar satu per satu. Ketika sebuah kategori dipilih, engine akan mengambil data dari NASA Images API kemudian mengubahnya menjadi slideshow, thumbnail, metadata, serta link menuju halaman sumber NASA.

    Konsepnya mirip widget data real-time yang sebelumnya pernah dibahas pada artikel Widget Gempa BMKG untuk Blogger dengan Data JSON Real-Time. Bedanya, widget ini memanfaatkan katalog gambar NASA dan membaginya berdasarkan objek tata surya maupun kategori astronomi.

    Tampilan internal NASA Planet Explorer untuk Blogger

    Fitur NASA Planet Explorer

    NASA Images APIGambar dan metadata diambil langsung dari NASA Image and Video Library.
    Banyak KategoriPlanet, Matahari, Bulan, asteroid, komet, universe, spacecraft, dan exoplanet.
    Native JavaScriptTidak membutuhkan jQuery, framework frontend, Worker, maupun proxy RSS.
    Feed Engine TunggalSeluruh kategori memakai satu engine dengan konfigurasi query berbeda.
    Cache & DedupeHasil kategori disimpan sementara dan duplikat disaring berdasarkan NASA ID.
    ResponsiveTampilan desktop dan mobile menyesuaikan secara otomatis.
    Swipe & KeyboardGambar dapat digeser di layar sentuh atau dinavigasi dengan tombol panah.
    Modal DetailJudul, tanggal, NASA ID, center, photographer, dan sumber asli dapat dilihat langsung.

    Kategori Gambar yang Tersedia

    Versi widget ini menyediakan kategori Latest, Sun, Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune, Moon, Dwarf Planets, Asteroids & Comets, Universe, Spacecraft, dan Exoplanets.

    Sun Mercury Venus Earth Mars Jupiter Saturn Uranus Neptune Moon Asteroids & Comets Universe

    Untuk pembaca yang ingin memahami perbedaan istilah astronomi yang sering muncul pada kategori tersebut, CodeFlare juga mempunyai artikel perbedaan asteroid, komet, dan meteor.

    Live Preview NASA Planet Explorer

    Di bagian berikut nantinya pengunjung dapat mencoba widget secara langsung. Pilih planet atau kategori lain, gunakan tombol previous/next, klik thumbnail, atau buka tombol Detail untuk melihat metadata gambar.

    NASA PLANET EXPLORER Latest images from NASA Image Library
    NASA FEED ONLINE Connecting...
    Loading NASA imagery... NASA Image and Video Library
    NASA Image Library Latest

    Cara Pasang NASA Planet Explorer di Blogger

    Widget dapat dipasang melalui gadget HTML/JavaScript, di dalam halaman statis, atau pada area HTML artikel jika template mengizinkannya. Untuk pemasangan melalui Tata Letak Blogger, lakukan langkah berikut.

    1. 1
      Buka Blogger

      Masuk ke Dashboard Blogger lalu pilih blog yang akan dipasangi widget.

    2. 2
      Buka Tata Letak

      Pilih lokasi widget, kemudian klik Tambahkan Gadget.

    3. 3
      Pilih HTML/JavaScript

      Buka gadget HTML/JavaScript agar kode dapat ditempel langsung.

    4. 4
      Copy Kode Widget

      Salin seluruh kode pada bagian Kode Lengkap di bawah.

    5. 5
      Simpan

      Simpan gadget, kemudian buka blog untuk memastikan gambar NASA berhasil dimuat.

    Font Awesome 7Widget menggunakan ikon Font Awesome. Jika template belum memuat Font Awesome 7, pasang library tersebut terlebih dahulu agar ikon dapat tampil dengan benar.

    Kode Lengkap NASA Planet Explorer

    Salin seluruh HTML, CSS, dan JavaScript widget tanpa memotong bagian engine. Kode final sebaiknya ditempatkan dalam satu gadget HTML/JavaScript supaya CSS dan JavaScript ikut dimuat bersama widget.

    <div class="cfNASAExplorer" data-cf-nasa>
    <div class="cfNASA-shell">

    <header class="cfNASA-head">
    <div class="cfNASA-brand">
    <span class="cfNASA-brandIcon"><i class="fa-solid fa-shuttle-space"></i></span>
    <div class="cfNASA-brandText">
    <b>NASA PLANET <em>EXPLORER</em></b>
    <small>Latest images from NASA Image Library</small>
    </div>
    </div>

    <div class="cfNASA-status">
    <span class="cfNASA-statusDot"></span>
    <div>
    <b>NASA FEED ONLINE</b>
    <small data-status>Connecting...</small>
    </div>
    </div>

    <button class="cfNASA-menuBtn" type="button" aria-label="Open NASA feeds">
    <i class="fa-solid fa-bars"></i>
    </button>
    </header>

    <nav class="cfNASA-tabs" aria-label="NASA image categories"></nav>

    <section class="cfNASA-stage">
    <div class="cfNASA-loading">
    <span class="cfNASA-spinner"></span>
    <b>Loading NASA imagery...</b>
    <small>NASA Image and Video Library</small>
    </div>

    <div class="cfNASA-hero" hidden>
    <img class="cfNASA-heroImg" alt="" decoding="async"/>
    <div class="cfNASA-overlay"></div>

    <button class="cfNASA-navBtn cfNASA-prev" type="button" aria-label="Previous image">
    <i class="fa-solid fa-chevron-left"></i>
    </button>

    <button class="cfNASA-navBtn cfNASA-next" type="button" aria-label="Next image">
    <i class="fa-solid fa-chevron-right"></i>
    </button>

    <div class="cfNASA-content">
    <span class="cfNASA-kicker">LATEST NASA IMAGE</span>
    <h2 class="cfNASA-title"></h2>
    <p class="cfNASA-desc"></p>

    <div class="cfNASA-meta">
    <span><i class="fa-regular fa-calendar"></i><b data-date>—</b></span>
    <span><i class="fa-solid fa-building"></i><b data-center>NASA</b></span>
    <span><i class="fa-solid fa-hashtag"></i><b data-nasaid>—</b></span>
    </div>

    <div class="cfNASA-actions">
    <button class="cfNASA-detailBtn" type="button">
    <i class="fa-solid fa-circle-info"></i> Detail
    </button>

    <a class="cfNASA-sourceBtn" href="#" target="_blank" rel="noopener nofollow">
    <i class="fa-solid fa-arrow-up-right-from-square"></i> NASA Source
    </a>
    </div>
    </div>

    <div class="cfNASA-counter">
    <b data-current>01</b><span>/</span><span data-total>00</span>
    </div>
    </div>
    </section>

    <div class="cfNASA-thumbs"></div>

    <footer class="cfNASA-foot">
    <span><i class="fa-solid fa-satellite-dish"></i> NASA Image Library</span>
    <span data-active-feed>Latest</span>
    </footer>

    </div>

    <div class="cfNASA-feedPanel" aria-hidden="true">
    <div class="cfNASA-panelCard">
    <div class="cfNASA-panelHead">
    <div>
    <b>ALL NASA FEEDS</b>
    <small>Select image category</small>
    </div>
    <button class="cfNASA-closePanel" type="button" aria-label="Close">
    <i class="fa-solid fa-xmark"></i>
    </button>
    </div>
    <div class="cfNASA-feedList"></div>
    </div>
    </div>

    <div class="cfNASA-modal" aria-hidden="true">
    <div class="cfNASA-modalCard">
    <button class="cfNASA-modalClose" type="button" aria-label="Close">
    <i class="fa-solid fa-xmark"></i>
    </button>

    <div class="cfNASA-modalImage"><img alt="" decoding="async"/></div>

    <div class="cfNASA-modalBody">
    <span class="cfNASA-modalLabel">NASA IMAGE LIBRARY</span>
    <h3></h3>
    <p class="cfNASA-modalDesc"></p>
    <div class="cfNASA-modalMeta"></div>

    <a class="cfNASA-modalLink" href="#" target="_blank" rel="noopener nofollow">
    View Original on NASA
    <i class="fa-solid fa-arrow-up-right-from-square"></i>
    </a>
    </div>
    </div>
    </div>
    </div>

    <style>
    .cfNASAExplorer{--cfNASA-panel:#0a1727;--cfNASA-panel2:#0d1e33;--cfNASA-line:#173a5d;--cfNASA-blue:#1f9dff;--cfNASA-cyan:#26ddff;--cfNASA-green:#21dc83;--cfNASA-text:#edf7ff;--cfNASA-muted:#8faac0;--cfNASA-radius:16px;position:relative;width:100%;font:15px/1.5 Roboto,Arial,sans-serif}
    .cfNASAExplorer *{box-sizing:border-box}
    .cfNASA-shell{position:relative;overflow:hidden;width:100%;border:1px solid rgba(54,162,240,.45);border-radius:var(--cfNASA-radius);background:radial-gradient(circle at 78% -10%,rgba(38,130,255,.21),transparent 35%),radial-gradient(circle at 15% 100%,rgba(40,219,255,.08),transparent 28%),linear-gradient(145deg,#071421,#030a13);box-shadow:0 18px 48px rgba(0,0,0,.25)}
    .cfNASA-head{min-height:78px;padding:13px 15px;display:flex;align-items:center;gap:13px;border-bottom:1px solid rgba(86,166,225,.18)}
    .cfNASA-brand{min-width:0;flex:1;display:flex;align-items:center;gap:11px}
    .cfNASA-brandIcon{flex:0 0 46px;width:46px;height:46px;display:grid;place-items:center;border-radius:50%;color:#fff;font-size:20px;background:radial-gradient(circle at 35% 30%,#32bdff,#0b3b84 68%);border:1px solid rgba(99,210,255,.7);box-shadow:0 0 20px rgba(25,161,255,.24)}
    .cfNASA-brandText{min-width:0}
    .cfNASA-brandText b{display:block;color:var(--cfNASA-text);font-size:20px;line-height:1.15;letter-spacing:.25px}
    .cfNASA-brandText em{color:var(--cfNASA-cyan);font-style:normal}
    .cfNASA-brandText small{display:block;margin-top:4px;color:var(--cfNASA-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
    .cfNASA-status{display:flex;align-items:center;gap:8px}
    .cfNASA-statusDot{width:9px;height:9px;border-radius:50%;background:var(--cfNASA-green);box-shadow:0 0 12px var(--cfNASA-green)}
    .cfNASA-status b{display:block;color:var(--cfNASA-green);font-size:12px}
    .cfNASA-status small{display:block;margin-top:2px;color:var(--cfNASA-muted);font-size:11px}
    .cfNASA-menuBtn{display:none;width:40px;height:40px;border:1px solid var(--cfNASA-line);border-radius:9px;background:var(--cfNASA-panel2);color:var(--cfNASA-cyan);cursor:pointer}
    .cfNASA-tabs{display:flex;align-items:stretch;overflow-x:auto;gap:4px;padding:7px;scrollbar-width:none;background:rgba(2,9,17,.75);border-bottom:1px solid rgba(73,150,205,.16)}
    .cfNASA-tabs::-webkit-scrollbar{display:none}
    .cfNASA-tab{flex:1 0 72px;min-width:72px;height:68px;padding:5px;border:1px solid transparent;border-radius:10px;background:transparent;color:#9db4c8;cursor:pointer;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;transition:.2s ease}
    .cfNASA-tab i{font-size:18px}
    .cfNASA-tab span{font-size:10px;white-space:nowrap}
    .cfNASA-tab:hover{color:#fff;background:rgba(23,105,170,.13)}
    .cfNASA-tab.is-active{color:#fff;background:linear-gradient(180deg,rgba(24,147,255,.26),rgba(13,78,131,.13));border-color:var(--cfNASA-blue);box-shadow:inset 0 0 18px rgba(22,144,255,.15),0 0 13px rgba(0,151,255,.14)}
    .cfNASA-tab.is-active i{color:var(--cfNASA-cyan)}
    .cfNASA-stage{position:relative;padding:9px;min-height:430px}
    .cfNASA-loading{position:absolute;inset:9px;z-index:20;min-height:410px;border-radius:13px;display:flex;flex-direction:column;align-items:center;justify-content:center;background:radial-gradient(circle at center,rgba(23,114,175,.17),transparent 43%),#06101b;color:#fff}
    .cfNASA-loading[hidden]{display:none}
    .cfNASA-loading small{margin-top:5px;color:var(--cfNASA-muted)}
    .cfNASA-spinner{width:38px;height:38px;margin-bottom:12px;border-radius:50%;border:3px solid rgba(76,179,255,.16);border-top-color:var(--cfNASA-cyan);animation:cfNASAspin .8s linear infinite}
    @keyframes cfNASAspin{to{transform:rotate(360deg)}}
    .cfNASA-hero{position:relative;overflow:hidden;height:410px;border-radius:13px;border:1px solid rgba(66,164,235,.31);background:#02070c}
    .cfNASA-hero[hidden]{display:none}
    .cfNASA-heroImg{display:block;width:100%;height:100%;object-fit:cover;transition:opacity .22s ease,transform .5s ease}
    .cfNASA-hero:hover .cfNASA-heroImg{transform:scale(1.015)}
    .cfNASA-overlay{position:absolute;inset:0;pointer-events:none;background:linear-gradient(90deg,rgba(1,8,15,.96) 0%,rgba(2,10,18,.75) 31%,rgba(2,9,16,.18) 64%,rgba(0,0,0,.3) 100%),linear-gradient(0deg,rgba(0,0,0,.48),transparent 47%)}
    .cfNASA-content{position:absolute;z-index:3;left:6%;top:50%;width:min(440px,48%);transform:translateY(-50%);color:var(--cfNASA-text)}
    .cfNASA-kicker{display:block;margin-bottom:8px;color:var(--cfNASA-cyan);font-size:12px;font-weight:700;letter-spacing:.75px}
    .cfNASA-title{margin:0 0 10px;padding:0;color:#fff;font-size:30px;line-height:1.12}
    .cfNASA-desc{margin:0 0 13px;color:#d2e3ef;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3;overflow:hidden}
    .cfNASA-meta{display:flex;flex-wrap:wrap;gap:9px 14px;margin-bottom:14px}
    .cfNASA-meta span{display:flex;align-items:center;gap:6px;color:#a8c2d6;font-size:11px}
    .cfNASA-meta i{color:var(--cfNASA-cyan)}
    .cfNASA-actions{display:flex;flex-wrap:wrap;gap:8px}
    .cfNASA-detailBtn,.cfNASA-sourceBtn{min-height:40px;padding:0 14px;border-radius:9px;display:inline-flex;align-items:center;justify-content:center;gap:7px;text-decoration:none;font:600 12px Roboto,Arial,sans-serif}
    .cfNASA-detailBtn{border:1px solid var(--cfNASA-blue);color:#fff;background:linear-gradient(135deg,#007ff1,#0757b3);cursor:pointer}
    .cfNASA-sourceBtn{border:1px solid rgba(100,183,241,.34);color:#eaf7ff;background:rgba(6,25,42,.67)}
    .cfNASA-navBtn{position:absolute;z-index:5;top:50%;transform:translateY(-50%);width:44px;height:44px;border:1px solid rgba(155,220,255,.72);border-radius:50%;background:rgba(4,17,30,.66);color:#fff;cursor:pointer;backdrop-filter:blur(7px)}
    .cfNASA-navBtn:hover{background:#0879d1}
    .cfNASA-prev{left:13px}.cfNASA-next{right:13px}
    .cfNASA-counter{position:absolute;z-index:4;right:17px;bottom:15px;display:flex;gap:4px;align-items:baseline;padding:5px 9px;border-radius:7px;background:rgba(0,0,0,.58);color:#b7ccdd;font-size:11px;backdrop-filter:blur(5px)}
    .cfNASA-counter b{color:var(--cfNASA-cyan);font-size:15px}
    .cfNASA-thumbs{display:flex;gap:8px;overflow-x:auto;padding:0 9px 10px;scrollbar-width:thin}
    .cfNASA-thumb{flex:0 0 124px;width:124px;padding:4px;border:1px solid #173952;border-radius:9px;background:#071420;color:#d9e9f5;cursor:pointer}
    .cfNASA-thumb.is-active{border-color:var(--cfNASA-cyan);box-shadow:0 0 12px rgba(36,225,255,.18)}
    .cfNASA-thumb img{width:100%;height:72px;object-fit:cover;display:block;border-radius:6px;background:#07111c}
    .cfNASA-thumb span{display:block;padding:5px 3px 2px;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;font-size:10px}
    .cfNASA-foot{min-height:40px;padding:8px 11px;display:flex;align-items:center;justify-content:space-between;gap:10px;border-top:1px solid rgba(60,141,201,.18);color:var(--cfNASA-muted);font-size:10px}
    .cfNASA-foot span{display:flex;align-items:center;gap:6px}
    .cfNASA-foot i{color:var(--cfNASA-cyan)}
    .cfNASA-feedPanel,.cfNASA-modal{position:fixed;inset:0;z-index:99999;display:none;align-items:center;justify-content:center;padding:17px;background:rgba(0,5,10,.77);backdrop-filter:blur(8px)}
    .cfNASA-feedPanel.is-open,.cfNASA-modal.is-open{display:flex}
    .cfNASA-panelCard{width:min(540px,100%);max-height:min(680px,90vh);overflow:hidden;border:1px solid #23567b;border-radius:15px;background:#081421;box-shadow:0 30px 80px rgba(0,0,0,.55)}
    .cfNASA-panelHead{display:flex;align-items:center;justify-content:space-between;padding:14px;border-bottom:1px solid #173650;color:#fff}
    .cfNASA-panelHead b,.cfNASA-panelHead small{display:block}
    .cfNASA-panelHead small{margin-top:2px;color:var(--cfNASA-muted)}
    .cfNASA-closePanel,.cfNASA-modalClose{width:38px;height:38px;border:0;border-radius:50%;background:#14293b;color:#fff;cursor:pointer}
    .cfNASA-feedList{max-height:570px;overflow:auto;padding:9px}
    .cfNASA-feedItem{width:100%;min-height:50px;padding:9px 11px;display:flex;align-items:center;gap:10px;border:1px solid transparent;border-radius:9px;background:transparent;color:#d9e9f4;cursor:pointer;text-align:left}
    .cfNASA-feedItem:hover,.cfNASA-feedItem.is-active{border-color:#245b84;background:#0d2235}
    .cfNASA-feedItem i{width:25px;text-align:center;color:var(--cfNASA-cyan)}
    .cfNASA-modalCard{position:relative;width:min(720px,100%);max-height:90vh;overflow:auto;border:1px solid #20557d;border-radius:15px;background:#071421;box-shadow:0 30px 80px rgba(0,0,0,.6)}
    .cfNASA-modalClose{position:absolute;z-index:3;top:10px;right:10px}
    .cfNASA-modalImage{aspect-ratio:16/9;overflow:hidden;background:#02070c}
    .cfNASA-modalImage img{width:100%;height:100%;object-fit:cover}
    .cfNASA-modalBody{padding:17px;color:#cfe0ec}
    .cfNASA-modalLabel{font-size:10px;font-weight:700;color:var(--cfNASA-cyan)}
    .cfNASA-modalBody h3{margin:7px 0 10px;color:#fff;font-size:23px;line-height:1.25}
    .cfNASA-modalDesc{margin:0 0 14px}
    .cfNASA-modalMeta{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:7px;margin-bottom:13px;padding:11px;border-radius:9px;background:#0c1d2c;font-size:11px}
    .cfNASA-modalLink{min-height:40px;padding:0 14px;display:inline-flex;align-items:center;gap:7px;border-radius:8px;color:#fff;background:#087ae0;text-decoration:none;font-weight:600}

    @media(max-width:800px){
    .cfNASA-status{display:none}
    .cfNASA-menuBtn{display:block}
    .cfNASA-brandText b{font-size:17px}
    .cfNASA-stage{min-height:390px}
    .cfNASA-hero{height:370px}
    .cfNASA-content{width:67%}
    .cfNASA-title{font-size:24px}
    }

    @media(max-width:600px){
    .cfNASA-shell{border-radius:13px}
    .cfNASA-head{min-height:60px;padding:9px}
    .cfNASA-brandIcon{width:38px;height:38px;flex-basis:38px;font-size:16px}
    .cfNASA-brandText b{font-size:14px}
    .cfNASA-brandText small{font-size:9px}
    .cfNASA-tabs{padding:5px}
    .cfNASA-tab{flex-basis:60px;min-width:60px;height:56px}
    .cfNASA-tab i{font-size:15px}
    .cfNASA-tab span{font-size:8px}
    .cfNASA-stage{padding:6px;min-height:425px}
    .cfNASA-loading{inset:6px;min-height:413px}
    .cfNASA-hero{height:413px}
    .cfNASA-heroImg{height:56%;object-position:center}
    .cfNASA-overlay{background:linear-gradient(0deg,rgba(1,7,13,.98) 0%,rgba(1,9,16,.84) 39%,rgba(1,7,13,.08) 73%)}
    .cfNASA-content{top:auto;left:15px;right:15px;bottom:16px;width:auto;transform:none}
    .cfNASA-kicker{font-size:9px}
    .cfNASA-title{font-size:21px;margin-bottom:7px}
    .cfNASA-desc{font-size:11px;-webkit-line-clamp:2}
    .cfNASA-meta{margin-bottom:10px}
    .cfNASA-meta span{font-size:9px}
    .cfNASA-actions{padding-right:54px}
    .cfNASA-detailBtn,.cfNASA-sourceBtn{min-height:35px;padding:0 10px;font-size:10px}
    .cfNASA-navBtn{width:36px;height:36px;top:27%}
    .cfNASA-prev{left:10px}.cfNASA-next{right:10px}
    .cfNASA-counter{right:11px;bottom:14px}
    .cfNASA-thumb{flex-basis:101px;width:101px}
    .cfNASA-thumb img{height:60px}
    .cfNASA-foot{font-size:9px}
    .cfNASA-modalMeta{grid-template-columns:1fr}
    }

    @media(prefers-color-scheme:light){
    .cfNASAExplorer{--cfNASA-text:#12283a;--cfNASA-muted:#617e93}
    .cfNASA-shell{background:radial-gradient(circle at 80% -10%,rgba(26,131,255,.11),transparent 35%),#f7fbfe}
    .cfNASA-head,.cfNASA-foot{background:#fff}
    .cfNASA-brandText b{color:#12283a}
    .cfNASA-tabs{background:#eef7fc}
    .cfNASA-tab{color:#587186}
    .cfNASA-tab:hover,.cfNASA-tab.is-active{color:#12324a}
    }
    </style>

    <script>
    (()=>{
    "use strict";

    const API="https://images-api.nasa.gov/search";
    const MAX_ITEMS=18;
    const THUMB_ITEMS=10;
    const GLOBAL_CACHE=window.__cfNASAFeedCache||(window.__cfNASAFeedCache=new Map());

    const FEEDS={
    latest:{label:"Latest",icon:"fa-house",q:"solar system planet"},
    sun:{label:"Sun",icon:"fa-sun",q:"sun solar"},
    mercury:{label:"Mercury",icon:"fa-circle",q:"Mercury planet"},
    venus:{label:"Venus",icon:"fa-circle",q:"Venus planet"},
    earth:{label:"Earth",icon:"fa-earth-americas",q:"Earth planet"},
    mars:{label:"Mars",icon:"fa-circle",q:"Mars planet"},
    jupiter:{label:"Jupiter",icon:"fa-circle",q:"Jupiter planet"},
    saturn:{label:"Saturn",icon:"fa-circle",q:"Saturn planet"},
    uranus:{label:"Uranus",icon:"fa-circle",q:"Uranus planet"},
    neptune:{label:"Neptune",icon:"fa-circle",q:"Neptune planet"},
    moon:{label:"Moon",icon:"fa-moon",q:"Moon lunar"},
    dwarf:{label:"Dwarf Planets",icon:"fa-circle-dot",q:"Pluto dwarf planet"},
    asteroid:{label:"Asteroids & Comets",icon:"fa-meteor",q:"asteroid comet"},
    universe:{label:"Universe",icon:"fa-star",q:"galaxy nebula universe"},
    spacecraft:{label:"Spacecraft",icon:"fa-satellite",q:"spacecraft mission"},
    exoplanet:{label:"Exoplanets",icon:"fa-earth-europe",q:"exoplanet"}
    };

    function init(root){
    if(root.dataset.ready==="1")return;
    root.dataset.ready="1";
    root.tabIndex=0;

    const tabs=root.querySelector(".cfNASA-tabs"),
    loading=root.querySelector(".cfNASA-loading"),
    hero=root.querySelector(".cfNASA-hero"),
    heroImg=root.querySelector(".cfNASA-heroImg"),
    title=root.querySelector(".cfNASA-title"),
    desc=root.querySelector(".cfNASA-desc"),
    thumbs=root.querySelector(".cfNASA-thumbs"),
    feedList=root.querySelector(".cfNASA-feedList"),
    panel=root.querySelector(".cfNASA-feedPanel"),
    modal=root.querySelector(".cfNASA-modal"),
    statusEl=root.querySelector("[data-status]"),
    dateEl=root.querySelector("[data-date]"),
    centerEl=root.querySelector("[data-center]"),
    nasaIdEl=root.querySelector("[data-nasaid]"),
    currentEl=root.querySelector("[data-current]"),
    totalEl=root.querySelector("[data-total]"),
    activeFeedEl=root.querySelector("[data-active-feed]"),
    sourceBtn=root.querySelector(".cfNASA-sourceBtn");

    let active="latest",items=[],index=0,touchStartX=0,controller=null,requestId=0;

    const esc=s=>String(s??"").replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""");
    const detailURL=id=>"https://images.nasa.gov/details/"+encodeURIComponent(id||"");

    function cleanText(v){
    if(!v)return"";
    const d=document.createElement("div");
    d.innerHTML=v;
    return(d.textContent||"").replace(/\s+/g," ").trim()
    }

    function formatDate(v){
    if(!v)return"NASA Archive";
    const d=new Date(v);
    if(Number.isNaN(d.getTime()))return"NASA Archive";
    return new Intl.DateTimeFormat("en",{year:"numeric",month:"short",day:"numeric"}).format(d)
    }

    function buildMenus(){
    const keys=Object.keys(FEEDS),main=keys.slice(0,10);

    tabs.innerHTML=main.map(id=>{
    const f=FEEDS[id];
    return'<button type="button" class="cfNASA-tab'+(id===active?' is-active':'')+'" data-feed="'+id+'"><i class="fa-solid '+f.icon+'"></i><span>'+esc(f.label)+'</span></button>'
    }).join("")+'<button type="button" class="cfNASA-tab" data-more="1"><i class="fa-solid fa-ellipsis"></i><span>More</span></button>';

    feedList.innerHTML=keys.map(id=>{
    const f=FEEDS[id];
    return'<button type="button" class="cfNASA-feedItem'+(id===active?' is-active':'')+'" data-feed="'+id+'"><i class="fa-solid '+f.icon+'"></i><span>'+esc(f.label)+'</span></button>'
    }).join("")
    }

    async function getFeed(id){
    if(GLOBAL_CACHE.has(id))return GLOBAL_CACHE.get(id);

    const feed=FEEDS[id]||FEEDS.latest;

    if(controller)controller.abort();
    controller=new AbortController();

    const url=API+"?media_type=image&q="+encodeURIComponent(feed.q);
    const res=await fetch(url,{signal:controller.signal,cache:"no-store"});
    if(!res.ok)throw new Error("NASA API "+res.status);

    const json=await res.json(),raw=json?.collection?.items||[],seen=new Set();

    const mapped=raw.map(item=>{
    const d=item?.data?.[0]||{},l=item?.links?.find(x=>x?.render==="image")||item?.links?.[0]||{};
    return{
    id:d.nasa_id||"",
    title:d.title||"NASA Image",
    desc:cleanText(d.description||d.description_508||""),
    date:d.date_created||"",
    center:d.center||"NASA",
    photographer:d.photographer||"",
    keywords:Array.isArray(d.keywords)?d.keywords:[],
    image:l.href||"",
    mediaType:d.media_type||"image"
    }
    }).filter(x=>{
    if(!x.image||!x.id||seen.has(x.id))return false;
    seen.add(x.id);return true
    }).sort((a,b)=>{
    const da=new Date(a.date).getTime()||0,db=new Date(b.date).getTime()||0;
    return db-da
    }).slice(0,MAX_ITEMS);

    GLOBAL_CACHE.set(id,mapped);
    return mapped
    }

    function fallback(){
    return[{id:"PIA02873",title:"NASA Planet Explorer",desc:"NASA imagery is temporarily unavailable. Please try again later.",date:"",center:"NASA",photographer:"",keywords:[],image:"https://images-assets.nasa.gov/image/PIA02873/PIA02873~orig.jpg"}]
    }

    function preloadNext(){
    if(items.length<2)return;
    const next=items[(index+1)%items.length];
    if(next?.image){const i=new Image();i.src=next.image}
    }

    function render(){
    if(!items.length)return;

    index=(index+items.length)%items.length;
    const item=items[index];

    heroImg.style.opacity="0";
    const img=new Image();

    img.onload=()=>{
    heroImg.src=item.image;
    heroImg.alt=item.title;
    heroImg.style.opacity="1"
    };

    img.onerror=()=>{
    heroImg.src="https://images-assets.nasa.gov/image/PIA02873/PIA02873~orig.jpg";
    heroImg.alt="NASA Planet Explorer";
    heroImg.style.opacity="1"
    };

    img.src=item.image;

    title.textContent=item.title;
    desc.textContent=item.desc||"NASA image from the NASA Image and Video Library.";
    dateEl.textContent=formatDate(item.date);
    centerEl.textContent=item.center||"NASA";
    nasaIdEl.textContent=item.id||"NASA";
    sourceBtn.href=detailURL(item.id);
    currentEl.textContent=String(index+1).padStart(2,"0");
    totalEl.textContent=String(items.length).padStart(2,"0");

    thumbs.innerHTML=items.slice(0,THUMB_ITEMS).map((x,i)=>
    '<button type="button" class="cfNASA-thumb'+(i===index?' is-active':'')+'" data-index="'+i+'" title="'+esc(x.title)+'"><img src="'+esc(x.image)+'" alt="'+esc(x.title)+'" loading="lazy" decoding="async"/><span>'+esc(x.title)+'</span></button>'
    ).join("");

    preloadNext()
    }

    async function load(id){
    if(!FEEDS[id])return;

    const thisRequest=++requestId;
    active=id;index=0;
    loading.hidden=false;
    hero.hidden=true;
    thumbs.innerHTML="";
    buildMenus();

    activeFeedEl.textContent=FEEDS[id].label;
    statusEl.textContent="Loading "+FEEDS[id].label+"...";

    try{
    const result=await getFeed(id);
    if(thisRequest!==requestId)return;
    items=result;
    if(!items.length)throw new Error("No NASA results");

    statusEl.textContent="Updated "+new Intl.DateTimeFormat("en",{hour:"2-digit",minute:"2-digit"}).format(new Date())
    }catch(err){
    if(err?.name==="AbortError")return;
    if(thisRequest!==requestId)return;
    console.info("[CodeFlare NASA Feed]",err.message||err);
    items=fallback();
    statusEl.textContent="NASA feed temporarily unavailable"
    }

    loading.hidden=true;
    hero.hidden=false;
    render()
    }

    function move(step){
    if(!items.length)return;
    index=(index+step+items.length)%items.length;
    render()
    }

    function openPanel(){
    panel.classList.add("is-open");
    panel.setAttribute("aria-hidden","false")
    }

    function closePanel(){
    panel.classList.remove("is-open");
    panel.setAttribute("aria-hidden","true")
    }

    function openModal(){
    const item=items[index];
    if(!item)return;

    const mimg=modal.querySelector(".cfNASA-modalImage img");
    mimg.src=item.image;
    mimg.alt=item.title;

    modal.querySelector("h3").textContent=item.title;
    modal.querySelector(".cfNASA-modalDesc").textContent=item.desc||"No description available.";
    modal.querySelector(".cfNASA-modalMeta").innerHTML=
    '<span><b>Date</b><br>'+esc(formatDate(item.date))+'</span>'+
    '<span><b>NASA ID</b><br>'+esc(item.id||"—")+'</span>'+
    '<span><b>Center</b><br>'+esc(item.center||"NASA")+'</span>'+
    '<span><b>Photographer</b><br>'+esc(item.photographer||"Not listed")+'</span>';

    modal.querySelector(".cfNASA-modalLink").href=detailURL(item.id);
    modal.classList.add("is-open");
    modal.setAttribute("aria-hidden","false")
    }

    function closeModal(){
    modal.classList.remove("is-open");
    modal.setAttribute("aria-hidden","true")
    }

    root.addEventListener("click",e=>{
    const tab=e.target.closest(".cfNASA-tab");
    if(tab){
    if(tab.dataset.more){openPanel();return}
    load(tab.dataset.feed);return
    }

    const feed=e.target.closest(".cfNASA-feedItem");
    if(feed){closePanel();load(feed.dataset.feed);return}

    const thumb=e.target.closest(".cfNASA-thumb");
    if(thumb){index=Number(thumb.dataset.index)||0;render();return}

    if(e.target.closest(".cfNASA-prev"))move(-1);
    if(e.target.closest(".cfNASA-next"))move(1);
    if(e.target.closest(".cfNASA-menuBtn"))openPanel();
    if(e.target.closest(".cfNASA-closePanel"))closePanel();
    if(e.target.closest(".cfNASA-detailBtn"))openModal();
    if(e.target.closest(".cfNASA-modalClose"))closeModal();
    if(e.target===panel)closePanel();
    if(e.target===modal)closeModal()
    });

    hero.addEventListener("touchstart",e=>{
    touchStartX=e.changedTouches[0].clientX
    },{passive:true});

    hero.addEventListener("touchend",e=>{
    const diff=e.changedTouches[0].clientX-touchStartX;
    if(Math.abs(diff)>45)move(diff>0?-1:1)
    },{passive:true});

    root.addEventListener("keydown",e=>{
    if(e.key==="ArrowLeft"){e.preventDefault();move(-1)}
    if(e.key==="ArrowRight"){e.preventDefault();move(1)}
    if(e.key==="Escape"){closePanel();closeModal()}
    });

    buildMenus();
    load("latest")
    }

    document.querySelectorAll("[data-cf-nasa]").forEach(init)
    })();
    </script>

    Bagaimana Feed Engine Widget Bekerja?

    Engine mempunyai daftar kategori seperti mars, jupiter, saturn, dan kategori lainnya. Masing-masing kategori hanya menyimpan nama, ikon, serta kata kunci pencarian. Saat pengunjung memilih tab, JavaScript membangun request ke endpoint https://images-api.nasa.gov/search dengan parameter media_type=image dan kata kunci kategori.

    Hasil dari API kemudian diproses menjadi data yang dibutuhkan widget: NASA ID, judul, deskripsi, tanggal, NASA center, photographer, dan URL gambar. Data yang tidak mempunyai gambar atau NASA ID akan dilewati. Item dengan NASA ID yang sama juga tidak akan ditampilkan dua kali.

    01
    Pilih KategoriPengunjung memilih planet atau kategori gambar.
    02
    Ambil Data NASAEngine meminta data gambar dari NASA Images API.
    03
    Sort & DedupeData diurutkan dan NASA ID ganda disaring.
    04
    Render WidgetGambar, metadata, dan thumbnail ditampilkan.

    Kenapa Tidak Menggunakan Worker atau Proxy?

    NASA Image and Video Library menyediakan endpoint JSON yang dapat dibaca langsung dari JavaScript. Karena itu widget tidak perlu mengubah RSS XML menjadi JSON melalui proxy dan tidak membutuhkan Worker hanya untuk menampilkan gambar. Pendekatan ini membuat kode lebih sederhana dan mengurangi ketergantungan pada layanan tambahan.

    Konsep penggunaan feed sebagai sumber widget juga pernah dibahas dalam daftar RSS feed dan cara mengecek feed serta tutorial membuat RSS Feed Widget Berita di Blogger. NASA Planet Explorer berbeda karena sumber utamanya sudah berupa JSON API.

    Cache dan Filter Duplikat

    Widget membuat cache dengan Map(). Setelah kategori seperti Jupiter berhasil dimuat, data tersebut disimpan selama halaman masih terbuka. Jika pengunjung berpindah ke Mars kemudian kembali ke Jupiter, engine dapat menggunakan data yang sudah ada tanpa melakukan request yang sama berulang kali.

    Filter duplikat memakai nasa_id. Teknik ini penting karena sebuah pencarian kadang dapat mengembalikan beberapa item yang merujuk pada aset NASA yang sama.

    Responsive untuk Desktop dan Mobile

    Pada desktop, gambar hero memenuhi area utama sementara judul, deskripsi, metadata, dan tombol ditampilkan di sisi gambar. Pada layar kecil, gambar dipindahkan ke bagian atas dan informasi berada di bawahnya agar teks tidak menutupi objek utama terlalu banyak.

    Thumbnail menggunakan horizontal scrolling sehingga jumlah gambar tidak membuat widget melebar keluar layar. Swipe juga tersedia pada perangkat sentuh, sedangkan pengguna desktop dapat memakai tombol previous/next atau tombol panah keyboard.

    NASA Images API dan Hak Penggunaan Gambar

    Widget hanya menampilkan data dari NASA Image and Video Library dan menyediakan link kembali ke halaman detail NASA. Setiap aset dapat mempunyai metadata, kredit, atau ketentuan tambahan masing-masing. Karena itu, jika sebuah gambar akan digunakan kembali di luar tampilan widget, periksa halaman sumber dan kredit yang tercantum pada aset tersebut.

    Widget Lain yang Bisa Dipasang di Blogger

    NASA Planet Explorer dapat dipasang bersama widget informatif lain selama halaman tidak memuat terlalu banyak request eksternal sekaligus. Untuk melihat pilihan lainnya, buka kumpulan widget Blogger responsive dan native JavaScript.

    Jika ingin membuat halaman informasi yang selalu berubah mengikuti sumber data, prinsip yang digunakan widget NASA ini juga dapat diterapkan pada feed berita, data cuaca, statistik, atau API publik lainnya: ambil data, normalisasi, cache, filter, lalu render hanya elemen yang dibutuhkan.

    Pertanyaan yang Sering Ditanyakan

    Apakah NASA Planet Explorer membutuhkan API key?

    Widget versi ini menggunakan NASA Image and Video Library Search API yang dapat diakses langsung oleh frontend tanpa memasukkan API key ke dalam kode widget.

    Apakah widget membutuhkan jQuery?

    Tidak. Seluruh navigasi, fetch data, modal, swipe, cache, dan rendering menggunakan native JavaScript.

    Apakah harus menggunakan Cloudflare Worker?

    Tidak. Versi ini mengambil JSON langsung dari NASA Images API.

    Apakah bisa dipasang lebih dari satu kali?

    Ya. Inisialisasi menggunakan atribut data-cf-nasa dan setiap instance mempunyai state tampilan sendiri, sedangkan cache data dapat dipakai bersama.

    Kenapa gambar pada suatu kategori kadang tidak persis berupa planet?

    NASA Images API menggunakan pencarian metadata. Kata kunci seperti Earth atau Mars dapat menemukan gambar misi, spacecraft, permukaan, atau objek terkait. Query kategori dapat diperketat jika diperlukan.

    Apakah widget cocok untuk sidebar?

    Bisa, tetapi desain hero lebih nyaman pada area artikel atau kolom yang cukup lebar. Untuk sidebar sempit, ukuran hero dan metadata sebaiknya disederhanakan.

    NASA Planet Explorer memberi cara yang lebih visual untuk menampilkan koleksi gambar NASA langsung di Blogger. Satu feed engine menangani banyak kategori, sementara cache, filter duplikat, lazy loading, preload, dan layout responsif menjaga widget tetap praktis digunakan.

    Karena sumber data berasal dari NASA Image and Video Library, isi widget dapat berubah mengikuti koleksi yang tersedia. Setelah kode dipasang, pengunjung dapat langsung berpindah antarplanet, membuka detail gambar, dan menjelajahi sumber NASA tanpa perlu memuat ulang halaman.

    No comments

    💬 Share Your Thoughts & Join the Hall of Fame!

    Punya pendapat atau tips tentang artikel ini? Tuliskan komentar kamu sekarang! 🚀

    💎 Komentar yang bermanfaat, relevan, dan positif berkesempatan tampil di CodeFlare Hall of Fame dan masuk ke Top Commentators Widget.

    👉 Comment now. Share your ideas. Get noticed on codeflare.net

    Post Top Ad

    Post Bottom Ad