Skip to content

Commit

Permalink
+ cam-shaft
Browse files Browse the repository at this point in the history
  • Loading branch information
martrapp committed Oct 4, 2024
1 parent 97a63a5 commit 5cd0dbf
Show file tree
Hide file tree
Showing 28 changed files with 1,983 additions and 334 deletions.
6 changes: 4 additions & 2 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,8 @@ function sidebar() {
items: [
{ label: 'Inspection Chamber', link: "/tools/inspection-chamber/" },
{ label: 'Element Crossing', link: "/tools/element-crossing/" },
{ label: 'Turn-Signal', link: "/tools/turn-signal/", badge: { text: 'new', variant: 'tip' } as Badge },
{ label: 'Turn-Signal', link: "/tools/turn-signal/" },
{ label: 'Cam-Shaft', link: "/tools/cam-shaft/", badge: { text: 'new', variant: 'tip' } as Badge },
],
}, {
label: 'Basics',
Expand All @@ -107,7 +108,8 @@ function sidebar() {
items: [
{ label: 'Where to place the CSS', link: "/tips/css/" },
{ label: "Flickering during morph animations?", link: "tips/over-exposure/" },
{ label: "Avoid Pointer Flickering", link: "tips/pointer/" }
{ label: "Avoid Pointer Flickering", link: "tips/pointer/" },
{ label: "Pseudo-smooth-scrolling?", link: "tips/pseudo-smooth-scrolling/" }
]
}];
}
505 changes: 193 additions & 312 deletions package-lock.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,18 @@
"test": "npx playwright test"
},
"devDependencies": {
"@astrojs/check": "^0.9.3",
"@astrojs/check": "^0.9.4",
"@astrojs/starlight": "^0.28.2",
"@playwright/test": "^1.47.2",
"@splidejs/splide": "^4.1.4",
"@types/node": "^22.7.0",
"@types/node": "^22.7.4",
"@vtbag/element-crossing": "^1.0.1",
"@vtbag/inspection-chamber": "^1.0.14",
"@vtbag/inspection-chamber": "^1.0.15",
"@vtbag/turn-signal": "^1.0.1",
"astro": "^4.15.9",
"astro": "^4.15.11",
"astro-breadcrumbs": "^3.2.0",
"astro-d2": "^0.5.1",
"astro-vtbot": "^1.10.2",
"astro-d2": "^0.5.2",
"astro-vtbot": "^1.10.3",
"rehype-autolink-headings": "^7.1.0",
"rehype-external-links": "^3.0.0",
"rehype-slug": "^6.0.0",
Expand Down
Binary file removed public/chamber.png
Binary file not shown.
1 change: 1 addition & 0 deletions public/chamber.png
Binary file removed public/crossing.png
Binary file not shown.
1 change: 1 addition & 0 deletions public/crossing.png
1 change: 1 addition & 0 deletions public/shaft.png
Binary file removed public/signal.png
Binary file not shown.
1 change: 1 addition & 0 deletions public/signal.png
Binary file added src/assets/cards/shaft.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/fi.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/shaft.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 changes: 76 additions & 0 deletions src/content/docs/tips/pseudo-smooth-scrolling.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
---
title: "Pseudo-Smooth-Scrolling"
description: "Instant scrolling on a page with view transition might lead to an unexpected smooth-scrolling effect. "
---

Pseudo-smooth-scrolling is an effect that looks like smooth-scrolling, but in fact is the result of the browser’s default morph animation. It happens when a navigation involves instant scrolling and tall transitions groups.

Take a look at the image below, showing an abstract website layout with a light blue header, a blue navigation panel, and a light yellow content area. The content area has a `view-transition-name` applied. If you scroll down and then navigate to another page, you might notice something strange: while the scrollbar jumps instantly, the content scrolls smoothly. What's going on here?


<svg width="300px" height="150px" viewBox="0 0 300 150" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<rect fill="none" stroke="#aaa" x="0" y="0" width="300" height="150"></rect>
<rect fill="lightblue" stroke="#aaa" x="0" y="0" width="300" height="30"></rect>
<rect fill="steelblue" stroke="#aaa" x="0" y="30" width="70" height="120"></rect>
<rect fill="gray" stroke="#aaa" x="290" y="30" width="10" height="120"></rect>
<rect fill="white" stroke="#aaa" x="290" y="100" width="10" height="30"></rect>
<rect fill="lightyellow" stroke="#aaa" x="70" y="30" width="220" height="120"></rect>
</svg>

Only part of the content element is visible at a time, as it's much taller than the screen. For simplicity, let's assume the content element is the same size on both the old and new pages. However, different sections of it are displayed. On the old page, the purple section at the bottom is visible.
<svg width="300px" height="250px" viewBox="0 -100 300 250" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<rect fill="none" stroke="#aaa" x="0" y="0" width="300" height="150"></rect>
<rect fill="lightblue" stroke="#aaa" x="0" y="0" width="300" height="30"></rect>
<rect fill="steelblue" stroke="#aaa" x="0" y="30" width="70" height="120"></rect>
<rect fill="gray" stroke="#aaa" x="290" y="30" width="10" height="120"></rect>
<rect fill="white" stroke="#aaa" x="290" y="100" width="10" height="30"></rect>
<rect fill="lightyellow" stroke="#aaa" x="70" y="-100" width="220" height="250"></rect>
<rect fill="none" stroke="darkslateblue" stroke-width="3" x="70" y="32" width="220" height="116"></rect>
</svg>

On the new page, the top part of the content element is visible, which is the dark green section.

When you select the new page from the navigation panel, the scrollbar instantly jumps to the top, and the view transition kicks in. Through the default group animation applied to the content element, the browser initially shows the purple-bordered section, then smoothly transitions to the green-bordered area. During this process, it cross-fades between the old and new content.

<svg width="300px" height="280px" viewBox="0 0 300 280" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

<rect fill="none" stroke="#aaa" x="0" y="0" width="300" height="150"></rect>
<rect fill="lightblue" stroke="#aaa" x="0" y="0" width="300" height="30"></rect>
<rect fill="steelblue" stroke="#aaa" x="0" y="30" width="70" height="120"></rect>
<rect fill="gray" stroke="#aaa" x="290" y="30" width="10" height="120"></rect>
<rect fill="white" stroke="#aaa" x="290" y="30" width="10" height="30"></rect>
<rect fill="lightyellow" stroke="#aaa" x="70" y="30" width="220" height="250"></rect>
<rect fill="none" stroke="darkolivegreen" stroke-width="3" x="70" y="32" width="220" height="116"></rect>
<rect fill="none" stroke="darkslateblue" stroke-width="3" x="70" y="160" width="220" height="118"></rect>
</svg>

So, it’s not the scrollbar slider that smoothly moves from the lower to the upper position, but rather the view transition images that slide down through the viewport.

## Interactive Demo
[Explore an interactive demo of the effect](/shaft-demo/1/)



## How to Avoid?

The pseudo-smooth-scrolling effect can be quite appealing if the pages are not too lengthy and you intend to use it deliberately. However, it might also occur unintentionally, especially if you specifically want to avoid smooth scrolling on your pages.
There are two ways to avoid the effect.

### Just Animate the Root
The pseudo-smooth-scrolling effect only occurs when the `view-transition-name` is applied to an HTML element other than the top-level `<html>` element. The View Transition API [treats the `:root` element differently](https://drafts.csswg.org/css-view-transitions-1/#capture-the-image). The old and new images of the document element are always constrained to the size of the viewport, meaning the default group animation doesn’t transform the position and no scrolling happens at all.

If possible, resist the temptation to apply a view transition name to large content elements. Instead, use the `root` transition group on the `<html>` element to achieve the desired effect. If you fear that your root group now obscures header, footer, and navbar, you can always assign view transition names to those elements, allowing them to enter the view transition layer and [cover portions of the root images](/basics/pseudos/#rendering-pseudo-elements) as needed.

### Make Use of the Cam-Shaft



If using the root transition group doesn't meet your design objectives, you can turn to the [`@vtbag/cam-shaft`](/tools/cam-shaft/) script to adjust the images into their proper positions, compensating for the scroll delta. This approach eliminates sliding viewports and the pseudo-smooth-scroll effect. Just identify the transition groups that need adjustments, and let the script take care of the rest.

<style>{`
svg {
margin: 0 auto;
}
`}</style>
115 changes: 115 additions & 0 deletions src/content/docs/tools/cam-shaft.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
---
title: The Cam-Shaft
description: "Bump your view transition images into position to avoid that unexpected pseudo-smooth-scrolling."
---
import { Steps } from "@astrojs/starlight/components";

<div style="display:flex">
<div id="logo" style="flex:1; margin: 3ex">
![The Cam-shaft](../../../assets/shaft.png)
</div><div style="flex:3">

Bump your view transition images into position to avoid that unexpected pseudo-smooth-scrolling.

The Cam-Shaft is about an issue we already resolved for Astro's ViewTransitions (see [here](https://events-3bg.pages.dev/jotter/starlight/inner-workings/transitions/#the-pseudo-scrolling-main-area) and [here](https://events-3bg.pages.dev/library/PageOffset/)), but it still requires support for browser-native cross-document view transitions.

</div>
</div>
<style>{`
#logo img {
view-transition-name: logo;
mask-image: radial-gradient(
ellipse at center,
white 35%,
transparent 71%
);
}
`}</style>


## PREREQUISITE

:::tip[View Transition API]
The Camshaft is designed to address an issue with browser-native cross-document view transitions. In browsers that haven't implemented the API yet, it simply does nothing, as there's no problem to solve.
:::


## What is it?

This tools is intended to avoid the [pseudo-smooth-scroll effect](/tips/pseudo-smooth-scrolling/).

See the [interactive demo of the effect](/shaft-demo/1/) and the [interactive demo of the solution using the cam-shaft](/shaft-demo2/1/).


## Installation
:::tip
If you want to use the Cam-Shaft with an Astro project, see [astro-vtbot](https://events-3bg.pages.dev/library/CamShaft/) for reusable components you can easily use in your project.
:::

To use the Cam-Shaft, you can install the npm package in your project. Alternatively you can load the script from one of the global content delivery networks that provide npm packages.

import { Tabs, TabItem } from "@astrojs/starlight/components";

<Tabs>
<TabItem label="Using the npm package" icon="seti:npm">
<Steps>
1. Install `@vtbag/cam-shaft@latest` from npm.
2. In your project, add `@vtbag/cam-shaft/index.js` as an inline script at the beginning of the `<head>` element on all pages of your site.
</Steps>

Details depend on your project setup and the frameworks used, but it can be as simple as:

```jsx
import shaft from "@vtbag/cam-shaft?url";
<html>
<head>
<script src={shaft} />
...
</head>
...
</html>;
```
</TabItem>
<TabItem label="Loading the script from a CDN" icon="cloudflare">

You can load the script from CDNs such as jsdelivr.net or unpkg.com. Place the script inline at the beginning of the `<head>` element on all pages where you need avoid pseudo-smooth-scrolling.

Using `jsdeliver.net`:

```html
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/@vtbag/cam-shaft" />
...
</head>
...
</html>
```
or alternatively using `unpkg.com`:
```html
<html>
<head>
<script src="https://unpkg.com/@vtbag/cam-shaft" />
...
</head>
...
</html>
```
</TabItem>
</Tabs>
## Configuration and Usage
The Cam-Shaft script needs to know which view transition name's images it should bump and nudge. By default, it assumes it should handle `::view-transition-group(main)`.
If you need to target a different view transition name, you can use the `data-view-transition-names` attribute in the script tag. For example, the following will instruct the script to handle images for `::view-transition-group(content)`:
```html
<script src=... data-view-transition-names="content"/>
```
As you may have guessed from the plural form, you can specify multiple view transition names by separating them with spaces, allowing the script to manage several groups.
4 changes: 4 additions & 0 deletions src/content/docs/tools/foo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<svg width="300" height="300" viewBox="0 0 300 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">


</svg>
4 changes: 2 additions & 2 deletions src/content/docs/tools/inspection-chamber/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Steps } from "@astrojs/starlight/components";
The Inspection Chamber allows you to examine the details of view transitions. It’s designed for use during development and supports both same-document and cross-document view transitions.

Place your pages in the Inspection Chamber and put the view transitions through their paces.
You can thoroughly examine each transition: play it in slow motion, examine timings step-by-step, disable transitions or highlight the pseudo elements &mdash; everything is easily achievable here.
You can thoroughly examine each transition: play it in slow motion, examine timings and CSS values step-by-step, disable transitions or highlight the pseudo elements &mdash; everything is easily achievable here.

</div>
</div>
Expand Down Expand Up @@ -191,7 +191,7 @@ Extra: click the <kbd>new</kbd> and <kbd>old</kbd> buttons above the name list t
## Animation Panel
Each of the pseudo-elements introduced by the view transition API may feature multiple animations, either automatically generated by the browser or defined using CSS. Here, you can see them all. Dive into the details or disable specific animations to understand how each one contributes to the overall effect.
Each of the pseudo-elements introduced by the view transition API may feature multiple animations, either automatically generated by the View Transition API, defined by your CSS, or started via JavaScript on fulfillment of the `viewTransition.ready` promise. Here, you can see them all. Dive into the details or disable specific animations to understand how each one contributes to the overall effect.
<div class="light:sl-hidden">
![Animation panel](dark-animation.png)
</div><div class="dark:sl-hidden">
Expand Down
45 changes: 36 additions & 9 deletions src/content/docs/tools/turn-signal.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -126,22 +126,49 @@ There are no configuration options and the `forced-traversal` script does not ta
## Configuration and Usage
`@vtbag/turn-signal` main script accepts several config options. Those are specified as data* attributes on the `<script>` element. They are all optional. If used without any parameters, the TTurn-Signal detects backwards history traversals and sets the `backward` view transition type for those. Navigation to the current page sets the `same` type. For all other navigation, the `forward` type is set.
`@vtbag/turn-signal` main script accepts several config options. Those are specified as `data-*` attributes on the `<script>` element. They are all optional. If used without any parameters, the Turn-Signal detects backwards history traversals and sets the `backward` view transition type for those. Navigation to the current page sets the `same` type. For all other navigation, the `forward` type is set.
You can use this to style different animations dependent on the direction of the navigation:
You can use these view transition types to style different animations dependent on the direction of the navigation
### CSS for Reverse Animation
Chances are more often then not that you can not simply revert the direction of your animation for the `backward` effect. Assume you have `slideOutToLeft` for the old image and `slideInFromRight` for the new image.
```css
::view-transition-old(root) {...}
::view-transition-new(root) {...}
::view-transition-old(main) {
animation-name: slideOutToLeft;
}
::view-transition-new(main) {
animation-name: slideInFromRight;
}
:active-view-transition-type(backward) {
&::view-transition-old(root),
&::view-transition-new(root) {
animation-direction: reverse;
@keyframes slideOutToLeft {
to {
transform: translateX(-100%);
}
}
}
@keyframes slideInFromRight {
from {
transform: translateX(100%);
}
}
```
Just changing the direction of the animations would lead to something best named `slideInFromLeft` for the old image and `slideOutToRight` for the new image. While the animations are about right, just setting `animation-direction: reverse` would apply them to the wrong images. You do not want to slide in the old image or slide out the new image. So better you swap the keyframes, too &hellip;
```css
:active-view-transition-type(backward) {
&::view-transition-old(main) {
animation-name: slideInFromRight;
animation-direction: reverse;
}
&::view-transition-new(main) {
animation-name: slideOutToLeft;
animation-direction: reverse;
}
} }
```
&hellip; or even explicitly define keyframes for slideOutToRight and slideInFromLeft if you feel that is clearer.
### Config Options
|Config option|Type|Effect|
|--|--|--|
|data-selector|a CSS selector|<p>If your site has a concept of _previous_ and _next_ page, use this to tell the Turn-Signal about your pages and their order. One selector _to find them all_.</p><p>The selector should return one element per page of your site, and each element must have an href attribute. Typically, you would select `<a>` elements from your navigation bar, such as `data-selector="nav a"`.</p><p>If your site doesn't already have a suitable structure, consider generating a list of pages in a non-intrusive way. For example, you could use `<a>` elements inside a `<template>` element or `<link>` elements with a custom `rel` attribute.</p><p> The sequence of selected URLs is used to derive the navigation direction. Navigation to a page that comes later in the sequence of selected URLs will be a _forward_ navigation. Navigation to a page that comes earlier in the sequence of selected URLs will be a _backward_ navigation.</p>|
Expand Down
4 changes: 2 additions & 2 deletions src/content/docs/vtbag.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ description: What are those Bags of Tricks?

@vtbag is a comprehensive suite of tools, tips, and tricks to make your experience with the View Transition API smoother and more efficient.

You’re getting an early view at the site in its infancy, starting with the first tool in the suite: the [Inspection Chamber](/tools/inspection-chamber/), which now got company in form of the [Element-Crossing](/tools/element-crossing/).
You’re getting an early view at this site with the first tools in the suite: the [Inspection Chamber](/tools/inspection-chamber/), the [Element-Crossing](/tools/element-crossing/) and the most recent addition, the [TurnSignal](/tools/turn-signal/).

More tools are in the pipeline, and I’m eager to hear your feedback and learn what would be most valuable to you.
More tools are in the pipeline, and I’m eager to hear your feedback and learn [what would be most valuable to you]().

If you're new to view transitions, be sure to [check out the view transition examples](/basics/examples/) on this site to get started.

Expand Down
Loading

0 comments on commit 5cd0dbf

Please sign in to comment.