@domchristie/turn

中文文档
3.1.1发布于 2023/09/20MITES Module零依赖近 30 天下载 8282

Animate page transitions in Turbo Drive apps.

原始使用文档
文档目录31 节
  1. Installation
  2. Usage
  3. Customizing Animations
  4. Custom Class Names
  5. Class List
  6. turn-view-transitions
  7. turn-no-view-transitions
  8. turn-advance
  9. turn-restore
  10. turn-replace
  11. turn-before-exit
  12. turn-exit
  13. turn-before-transition (if View Transitions supported & ena…
  14. turn-transition (if View Transitions supported & enabled)
  15. turn-enter
  16. Events
  17. turn:before-exit
  18. turn:before-transition
  19. turn:before-enter
  20. turn:enter
  21. Usage with Tailwind CSS
  22. Disabling Animations
  23. Tip & Tricks
  24. 1. Animate Changes
  25. 2. Nesting
  26. 3. Optimizing Animations
  27. 4. Loading Spinner
  28. Not seeing animations?
  29. How does it work?
  30. Credits
  31. License

Turn

Animate page transitions in Turbo Drive apps.

Installation

Install @hotwired/turbo, then

npm install @domchristie/turn

Usage

  1. Include Turbo, dist/turn.js and dist/turn.css however you build your JavaScript & CSS
  2. Add data-turn-enter and data-turn-exit to the elements you wish to animate (optional if you're only using View Transitions)
  3. import Turn from '@domchristie/turn' and call Turn.start() in your application JavaScript
  4. Navigate between pages … ✨

Customizing Animations

Turn adds turn-before-exit, turn-exit, and turn-enter classes to the HTML element at the appropriate times. Apply your own animations by scoping your animation rules with this selector. For example:

html.turn-advance.turn-exit [data-turn-exit] {
  animation-name: MY_ANIMATE_OUT;
  animation-duration: .3s;
  animation-fill-mode: forwards;
}

html.turn-advance.turn-enter [data-turn-enter] {
  animation-name: MY_ANIMATE_IN;
  animation-duration: .6s;
  animation-fill-mode: forwards;
}

@keyframes MY_ANIMATE_OUT {
  …
}

@keyframes MY_ANIMATE_IN {
  …
}

This is how turn.css is organized, so you may want to get rid of that file altogether. animation-fill-mode: forwards is recommended to prevent your transitions from jumping back.

Custom Class Names

The values set in the data-turn-exit and data-turn-enter attributes will be applied as class names to that element. This lets you customize animations for each element. Styles should still be scoped by html.turn-exit and html.turn-enter.

Class List

The following class names are added to the HTML element at various time during a navigation lifecycle.

turn-view-transitions

Added on start if the device supports View Transitions, and View Transitions are enabled.

turn-no-view-transitions

Added on start if the device does not support View Transitions, or View Transitions are disabled.

turn-advance

Added when a visit starts and the action is advance. You'll probably want to scope most animations with this class. Removed when the navigation has completed and all animations have ended.

turn-restore

Added when a visit starts and the action is restore. Given the number of ways it's possible to navigate back/forward (back button, swipe left/right, history.back()), it's generally recommended that restoration visits are not animated. Removed when the navigation has completed and all animations have ended.

turn-replace

Added when a visit starts and the action is replace. Removed when the navigation has completed and all animations have ended.

turn-before-exit

Added when a visit starts. Useful for optimising animations with will-change. (See turn.css for an example.) Removed when the exit animations start.

turn-exit

Added when a visit starts. Use this to scope exit animations. Removed when the exit animations complete.

turn-before-transition (if View Transitions supported & enabled)

Added after the exit animations and any request has completed, but before the View Transitions have taken their snapshot. Useful when combining View Transitions with custom exit/enter animations. To avoid a flash of content, use this class to target exited elements, and style them in their final "exit" state. (See turn.css for an example.) Removed when the transition starts.

turn-transition (if View Transitions supported & enabled)

Adding during a View Transition. Useful when combining View Transitions with custom exit/enter animations.

turn-enter

Added after any requests have completed and previous animations/transitions have completed. Removed once the animations have completed.

Events

event.details may contain:

  • action: the action of the visit (advance or restore)
  • initiator: the element the visit was triggered from (an a, form, or html element if a Back/Forward navigation)
  • referrer: the URL the page is transitioning from
  • url: the URL the page is transitioning to
  • newBody: the incoming <body> that will be transitioned to

turn:before-exit

Dispatched before exit animations are started. event.detail includes:

  • action
  • initiator
  • referrer
  • url

turn:before-transition

Dispatched before a View Transition is started (after exit animations if present). Ideal for setting up view-transition-names before the View Transition performs its capturing. event.detail includes:

  • action
  • initiator
  • newBody
  • referrer

turn:before-enter

Dispatched before enter animations are started (after Vire Transitions if present). event.detail includes:

  • action
  • initiator
  • newBody
  • referrer

turn:enter

Dispatched after the all transitions and animations have completed. event.detail includes:

  • action
  • referrer
  • url
  • timing: the visit's timing metrics

Usage with Tailwind CSS

Define animations in tailwind.config.js, and add a plugin that scopes the styles, e.g.:

const plugin = require('tailwindcss/plugin')

module.exports = {
  theme: {
    extend: {
      animation: {
        exit: 'fade-out-up 0.3s cubic-bezier(0.65, 0.05, 0.35, 1) forwards',
        enter: 'fade-in-up 0.6s cubic-bezier(0.65, 0.05, 0.35, 1) forwards'
      },
      keyframes: {
        'fade-out-up': {/* … */},
        'fade-in-up': {/* … */}
      }
    }
  },

  plugins: [
    plugin(function ({ addVariant }) {
      addVariant('turn-exit', 'html.turn-exit &')
      addVariant('turn-enter', 'html.turn-enter &')
    })
  ]
}

Then in your HTML:

<main data-turn-exit="turn-exit:animate-exit" data-turn-enter="turn-enter:animate-enter">
  <!-- … -->
</main>

Disabling Animations

Add data-turn="false" to the <body> to opt out of animations from that page.

(This currently rather basic, but is limited by the information available in Turbo events. Hopefully improvable if turbo:visit events are fired on the initiating element.)

Tip & Tricks

1. Animate Changes

Avoid animating the whole body. Animations should target elements that change on navigation. So avoid animating persistent headers and instead animate the main element or just the panels/cards within it.

2. Nesting

Nesting animating elements draws attention and brings screens to life. Add data-turn-exit/data-turn-enter attributes to elements such as headings and key images within an animating container. The compound animation effects means they'll exit faster, and enter slower than other elements. For example:

<main data-turn-exit data-turn-enter>
  <h1 data-turn-exit data-turn-enter>Hello, world!</h1>
</main>

3. Optimizing Animations

Jumpy exit animations can be prevented using the will-change CSS property. Turn adds a turn-before-exit class to the HTML element just before adding the exit classes. This provides an opportunity to notify the browser of upcoming changes. For example, by default turn.css does the following:

html.turn-before-exit [data-turn-exit],
html.turn-exit [data-turn-exit] {
  will-change: transform, opacity;
}

4. Loading Spinner

Exit animations on slow requests can leave users with a blank screen. Improve the experience with a loading spinner that appears a short time after the exit animation. For example, if your exit animation take 600ms, add a spinner that starts appearing 700ms after that by using transition-delay. This spinner can live permanently in the body and only transition when the turn-exit class is applied:

.spinner {
  position: fixed;
  top: 15%;
  left: 50%;
  transform: translateX(-50%);
  opacity: 0;
  transition: opacity 100ms;
}
html.turn-exit .spinner {
  opacity: 1;
  transition-delay: 700ms
}

Not seeing animations?

Check your device preferences to see if you have requested reduced motion. Turn will only animate transitions when the prefers-reduced-motion media query does not match reduce.

How does it work?

Turn adds exit and enter classes at the appropriate times like so:

  1. on turbo:visit add the exit classes
  2. pause turbo:before-render (wait for exit animations to complete before resuming)
  3. on turbo:render, remove exit classes and add the enter classes
  4. on turbo:load, wait for the enter animations to complete before removing the enter classes

Credits

Default fade in/out animations adapted from Jon Yablonski's Humane By Design.

License

Copyright © 2021+ Dom Christie and released under the MIT license.

版本与发布记录

@domchristie/turn 共发布 17 个版本,首次发布于 2022/10/10;过去 12 个月发布了 0 个版本。

版本发布日期距今
3.1.1latest2023/09/203 年前
3.1.02023/09/203 年前
3.0.02023/07/073 年前
2.1.02023/07/073 年前
2.1.0-22023/07/063 年前
2.1.0-12023/07/053 年前

关于 @domchristie/turn 的常见问题

@domchristie/turn 是什么?

Animate page transitions in Turbo Drive apps.

如何安装 @domchristie/turn?

在项目目录运行 npm install @domchristie/turn,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@hotwired/turbo(^7)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@domchristie/turn 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/domchristie__turn 是否存在。

@domchristie/turn 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@domchristie/turn 可以商用吗?

@domchristie/turn 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@domchristie/turn 的下载量有多少?

根据 npm 官方下载统计,@domchristie/turn 在 2026/10/13 – 2026/11/11 这 30 天内被下载 8,282 次,日均约 276 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@domchristie/turn 还在维护吗?

最新版本 3.1.1 发布于 2023/09/20(3 年前);至今共发布 17 个版本,其中过去 12 个月发布了 0 个;首次发布于 2022/10/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。