使用neodb API 创建一个观影页面

前言

使用 neodb.social 的API算是多一种选择. 豆瓣数据的获取还是不太方便

获取neodb的token

使用mastodon账号登录 https://neodb.social/ 在右上角头像点击- 设置 - 找到更多设置

点击 查看已授权的应用程序

生成一个token即可

获取neodb API

在此使用项目 https://github.com/jkjoy/neodb-shelf-api 相比原项目我修改了封面显示的域名为neodb.prvcy.page 在国内访问得到了更好的体验. 可以部署在vercel上,过程就不赘述了,请参考Readme

使用

CSS

.masonry {
    display: flex;
    flex-wrap: wrap;
    gap: 5px; /* 设置项目之间的间距 */
}

.item {
    flex: 1 1 calc(25% - 20px); /* 默认每行显示 4 个项目 */
    position: relative;
    overflow: hidden;
    box-sizing: border-box;
}

@media (max-width: 1200px) {
    .item {
        flex: 1 1 calc(33.33% - 20px); /* 每行显示 3 个项目 */
    }
}

@media (max-width: 900px) {
    .item {
        flex: 1 1 calc(50% - 20px); /* 每行显示 2 个项目 */
    }
}

@media (max-width: 600px) {
    .item {
        flex: 1 1 100%; /* 每行显示 1 个项目 */
    }
}

.image-container {
    position: relative;
    width: 100%;
    padding-top: 150%; /* 2:3 宽高比 */
    overflow: hidden;
}

.image-container img {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    transition: transform 0.3s ease-in-out;
}

.item-content {
    position: absolute;
    font-size: 12px;
    bottom: 0;
    left: 0;
    width: auto;
    background-color: rgba(0, 0, 0, 0.7);
    color: white;
    padding: 10px;
    transform: translateY(100%);
    transition: transform 0.3s ease-in-out;
}

.item:hover .item-content {
    transform: translateY(0);
}

.item:hover .image-container img {
    transform: scale(1.1);
}

.item-title a {
    color: white;
    text-decoration: none;
    font-size: 20px;
}

.item-title a:hover {
    text-decoration: underline;
}

JS

function MovieItem(movie) {
    const commentText = movie.comment_text ? movie.comment_text : '暂无评论';
    const rating = movie.item.rating ? movie.item.rating : '暂无评分';
    return `
        <div class="item">
            <div class="image-container">
                <img src="${movie.item.cover_image_url}" 
                     alt="${movie.item.title}" 
                     onerror="this.onerror=null; this.src='placeholder.jpg';">
            </div>
            <div class="item-content">
                <div class="item-title">
                    <a href="${movie.item.id}" target="_blank" rel="noopener noreferrer">${movie.item.title}</a>
                </div>
                <div class="item-info">${commentText}</div>
              
                <div class="item-score">评分: ${rating}</div>
            </div>
        </div>
    `;
}

// 从API获取数据并渲染页面
async function fetchAndRenderMovies() {
    try {
        const response = await fetch('https://neodb.imsun.org/api?type=complete&category=movie');
        const data = await response.json();

        const container = document.getElementById('movieContainer');
        data.forEach(movie => {
            container.innerHTML += MovieItem(movie);
        });
    } catch (error) {
        console.error('Error fetching movie data:', error);
        document.getElementById('movieContainer').innerHTML = '<p>加载电影数据时出错,请稍后再试。</p>';
    }
}

// 页面加载时获取并渲染电影数据
fetchAndRenderMovies();

此处https://neodb.imsun.org为部署在vercel的地址

HTML

<link rel="stylesheet" href="/movies/movies.css">
<div class="masonry" id="movieContainer">
    <!-- 电影项目将被 JavaScript 动态添加到这里 -->
</div>
<script defer src="/movies/movies.js"></script>

演示效果

https://blog.loliko.cn/movies/

更新于
评论一下 ...