fxshelf

Card Orbit

适用于 React 与 Vue 的路径约束 3D 卡片轨道动效

路径约束的 3D 卡片轨道 —— 升起、弧线、飞出。

npm i @fxshelf/card-orbit · 坐标演示动画原理 →

Demo

路径约束的 3D 卡片 —— 升起、弧线、飞出。

按住拖动可 scrub,卡片不会离开轨道。

手写 requestAnimationFrame 与分段 cos/sin 路径,不依赖 Framer Motion / GSAP。

Card 1
Card 2
Card 3
Card 4
Card 5
Card 6
Card 7

简介

Card Orbit 是一套路径约束的 3D 卡片轨道动效:卡片沿固定轨迹升起、划弧、飞出。核心是手写 requestAnimationFrame 与数学路径,不依赖 Framer Motion / GSAP。

一套 core(路径 + 样式 + 动画驱动)配 React / Vue 两套薄封装。支持:

方式ReactVue
npm@fxshelf/card-orbit@fxshelf/card-orbit/vue
CDN <script>unpkg IIFE → 全局 CardOrbit暂无(SFC 源码)
复制源码src/core + src/reactsrc/core + src/vue

灵感与参考实现来自 tasteskill.dev

安装

npm install @fxshelf/card-orbit
  • React:peer react / react-dom ≥ 18
  • Vue:peer vue ≥ 3.3,且能编译 .vue(如 Vite)
  • 样式:import '@fxshelf/card-orbit/styles.css'

用法

React

import { CardOrbit, CardOrbitMobile } from '@fxshelf/card-orbit'
import '@fxshelf/card-orbit/styles.css'

const images = ['/a.webp', '/b.webp', '/c.webp']

export function Hero() {
  return (
    <>
      <CardOrbitMobile images={images} />
      <CardOrbit images={images} />
    </>
  )
}

Vue

Vue 入口是源码 .vue SFC,不会预编译进 dist。目标项目需要能编译 SFC(例如 Vite + @vitejs/plugin-vue)。

<script setup lang="ts">
import { CardOrbit, CardOrbitMobile } from '@fxshelf/card-orbit/vue'
import '@fxshelf/card-orbit/styles.css'

const images = ['/a.webp', '/b.webp', '/c.webp']
</script>

<template>
  <CardOrbitMobile :images="images" />
  <CardOrbit :images="images" />
</template>

CDN(React 18 UMD)

适合静态页或零构建场景。产物约 10 KB、零依赖,挂载全局 CardOrbit。需先加载 React 18.x UMD(React 19 起官方不再提供 UMD)。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <link rel="stylesheet" href="https://unpkg.com/@fxshelf/card-orbit/dist/index.css" />
</head>
<body>
  <div id="hero"></div>

  <script crossorigin src="https://unpkg.com/react@18.3.1/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18.3.1/umd/react-dom.production.min.js"></script>
  <script src="https://unpkg.com/@fxshelf/card-orbit/dist/card-orbit.iife.js"></script>

  <script>
    var images = ['/a.webp', '/b.webp', '/c.webp']
    ReactDOM.createRoot(document.getElementById('hero')).render(
      React.createElement(React.Fragment, null,
        React.createElement(CardOrbit.CardOrbitMobile, { images: images }),
        React.createElement(CardOrbit.CardOrbit, { images: images }),
      ),
    )
  </script>
</body>
</html>
  • 全局 CardOrbit 上有 CardOrbitCardOrbitMobile 及 core 工具(createOrbit / samplePath 等)。
  • 也可用 jsDelivr:https://cdn.jsdelivr.net/npm/@fxshelf/card-orbit/dist/card-orbit.iife.js
  • 生产环境建议锁定版本:@fxshelf/card-orbit@0.1.6/...
  • 顺序:React 必须在 card-orbit 之前加载。
  • 不要用 jsDelivr 的 gh/.../dist 直链(dist/ 不进 Git)。
  • 仓库内完整示例:CDN示例.html
  • Vue 暂无 script 直引;请用 npm 或下方复制源码。
  • 旧无 scope 包名 card-orbit 已迁移至 @fxshelf/card-orbit

复制源码(不经过 npm)

从仓库 packages/card-orbit/src(或已安装的 node_modules/@fxshelf/card-orbit/)拷贝:

src/core/     # 必拷
src/react/    # 仅 React 项目
src/vue/      # 仅 Vue 项目

建议放到例如 components/card-orbit/

components/card-orbit/
  core/
  react/   或  vue/
  1. 组件内相对路径已是 ../core/...,保持 corereact/vue 同级即可。
  2. 引入一次样式:import './core/styles.css'
  3. 当本地组件使用,不必跑本包的 build。

React

import { CardOrbit, CardOrbitMobile } from './components/card-orbit/react'
import './components/card-orbit/core/styles.css'

Vue

import { CardOrbit, CardOrbitMobile } from './components/card-orbit/vue'
import './components/card-orbit/core/styles.css'

组件与 props

组件作用
CardOrbit桌面 3D 轨迹(默认仅 lg+ / 1024px 显示)
CardOrbitMobile窄屏横向跑马灯(默认 lg+ 隐藏)

React / Vue props 名称一致。图片 URL 由调用方提供,包内不捆绑资源。典型搭配:二者同时挂载,靠内置 CSS 互斥显示。

CardOrbit

Prop默认说明
images图片 URL 数组(必填)
alts与图片一一对应的 alt
className / style根节点
stageClassName / cardClassName / imageClassName子节点 class
autoSpeed45e-6未拖动时自动推进
dragSensitivity8e-4指针拖动灵敏度
activeWindow0.72可见相位窗口 (0, 1)
perspective3400CSS perspective(px)
ariaLabel'Card orbit carousel'无障碍标签
desktopOnlytrue是否仅大屏显示

CardOrbitMobile

Prop默认说明
images / alts同桌面
className / style根节点
trackClassName / cardClassName / imageClassName子节点 class
hideOnDesktoptruelg+ 是否隐藏
durationSec28跑马灯一周时长(秒)

本页目录