主页关于链接归档相册

通过 VSCO API 创建一个相册页面

代码

发现别人博客都有相册页,那我也整个。


一直是 VSCO 用户,虽然拍不出什么好照片也不会构图,但是 VSCO 的滤镜是真好用。
偶然间想起来@卜卜口的博客是有过 VSCO 页面的,不过年代久远估计也用不成,直接看看有没有官方 API 可以用。

API

答案是官方没有这种文档,但是确实有 API 能用,具体获取方法参考 vixalien 的文章

这里我又找到一个现成的网页端工具能直接获取到 JSON:Accessing VSCO's API - by @notlilj
根据网页提示填入用户名获取 site_id,再填入下面需要的位置就行。
修改 limit 参数可以控制获取的数量。

信息挺全的,主要的图片链接和大小都有,还有拍摄机型、光圈、ISO 之类的。

加个页面

Next.js 创建个新页面还是挺容易的。
就我的博客来说,首先引入布局和头部插件。

import Head from 'next/head';
import Layout from '../../components/layout';
export default function VSCO({ data }) {
  
  return (
    <Layout>
      <Head>
        <title>{`相册 - ${process.env.name}`}</title>
        <meta
          name="description"
          content={process.env.description}
        />
      </Head>
    </Layout>
  );
}

然后使用 getStaticProps 从 API 获取数据:

import Image from 'next/image'; // 不用白不用

export async function getStaticProps() {
    const res = await fetch('https://vsco.co/api/3.0/medias/profile?site_id={你的site_id}&limit=9', {
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json',
        'Authorization': 'Bearer 7356455548d0a1d886db010883388d08be84d0c9'
      }
    });
    const data = await res.json();
    return {
      props: {
        data
      }
    };
}

getStaticProps 是因为平时更新不多,每次构建时更新刚刚好,同时对性能影响也不大。

然后是展示,这里用一个经典的瀑布流布局。
上面我获取了九张照片,每 3 张分为一组,每一组内图片纵向排列,三个组再横向排列,类似这样:

┌────┐  ┌────┐  ┌────┐ 
│img1│  │img1│  │img1│ 
├────┤  ├────┤  ├────┤ 
│img2│  │img2│  │img2│ 
├────┤  ├────┤  ├────┤ 
│img3│  │img3│  │img3│ 
└────┘  └────┘  └────┘ 

那么最后大概就是这样:

export default function VSCO({ data }) {
  const groupedMedia = [];
  if (data) {
    for (let i = 0; i < data.media.length; i += 3) {
      groupedMedia.push(data.media.slice(i, i + 3));
    }
  }
  
  return (
    <Layout>
      <Head>
        <title>{`相册 - ${process.env.name}`}</title>
        <meta
          name="description"
          content={process.env.description}
        />
      </Head>
      <ul className="grid grid-cols-3 gap-3 py-6">
        {groupedMedia.map((group,index) => (
          <li className="flex flex-col gap-3" key={index}>
              {group.map((item) => (
                <a
                  href={item.image.permalink}
                  target="_blank"
                  rel="noopener"
                >
                  <Image
                  src={`https://${item.image.responsive_url}`}
                  alt={item.image.description}
                  width={item.image.width}
                  height={item.image.height}
                  quality={25}// 压缩强度按喜好调整
                  />
                </a>
              ))}
          </li>
        ))}
      </ul>
    </Layout>
  );
}

参考

the end.