Skip to content

Commit

Permalink
fixes and wording
Browse files Browse the repository at this point in the history
  • Loading branch information
martrapp committed Sep 6, 2024
1 parent e0cfdac commit ac2d176
Show file tree
Hide file tree
Showing 11 changed files with 150 additions and 67 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@types/node": "^22.5.4",
"@vtbag/inspection-chamber": "^1.0.11",
"astro": "^4.15.3",
"astro-vtbot": "^1.9.0",
"astro-vtbot": "^1.9.1",
"rehype-autolink-headings": "^7.1.0",
"rehype-external-links": "^3.0.0",
"rehype-slug": "^6.0.0",
Expand Down
2 changes: 1 addition & 1 deletion playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default defineConfig({
/* Opt out of parallel tests on CI. */
workers: process.env.CI ? 1 : 1,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: 'html',
reporter: 'list',
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
Expand Down
38 changes: 31 additions & 7 deletions src/content/docs/basics/examples.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,32 @@ description: Basic examples on how to use the View Transition API for same-docum

import DemoLink from "src/components/DemoLink.astro";

This page lists examples of view transitions, starting with the most basic settings and gradually adding more features. The tables provides a brief description of what makes each example unique and includes a link to the actual example with its code and detailed description.
This page references a series of view transition examples, starting with basic configurations and progressively incorporating more features. The tables below provide a brief description of what distinguishes each example and includes a link to the live example which also includes its code and a detailed explanation.

The View Transition API automatically applies two primary types of animations to your elements:

* Exit/Entry animations, which include an exit animation for the old image and an entry animation for the new image.
* Group (or Morph) animations, where the transition group animates changes in width, height, and position[^position] from the old image to the new one.


[^position]: Here, *position* is used for simplicity. The group animation actually refers to both position and all applied CSS transformations, such as those defined by `matrix3d` or its specialized forms like `rotate`.

By default, both types of animations occur simultaneously. However, they might not always be noticeable. For instance, if elements with the same view transition name have the same size and position before and after the transition, the group animation will result in no visible change. Similarly, if the old and new images are identical, only the group animation will be visible, while the exit/entry animations won't produce noticeable effects.[^plus-lighter]

[^plus-lighter]: The cross-fade effect is more intricate than it appears at first glance. It works so smoothly because the default animations also set the [ `mix-blend-mode` CSS property to `plus-lighter`](https://events-3bg.pages.dev/jotter/api/example/#the--new-and--old-image-animation)

The [first set of examples](#same-document-view-transitiom-examples) focuses on **exit and entry** animations for **same-document** view-transitions, animating a component directly on its page.

The [second set of examples](#cross-document-view-transition-examples) highlights **exit and entry** animations of **cross-document** view transitions. Those are triggered by following a link to a new page.

While the first two sets demonstrate exit and entry animations, the [Image Morph Set](#image-morph-examples) introduces group animations, starting with image morphs, which tend to be easier compared to morphs involving text.


For morphing text with view transitions, we explore two additional sets: the Little Fail Set, which demonstrates various common failures, and the Improved Set, which attempts to address and enhance those issues.

## Same-Document View Transition Examples

These examples revolve around a tab component where you can switch between different contents.
These examples focus on a tab component where you can switch between different content sections. When you click on the headers, the content in the main area of the tab changes, but the component itself remains in the same position. As a result, these examples demonstrate **exit and entry** animations of the content only.

<div title="Select a link from the table below">
<Card title="Same-Document 'Tabs' Example">
Expand Down Expand Up @@ -55,7 +76,8 @@ These examples revolve around a tab component where you can switch between diffe
I'm reading a book on anti-gravity.\
It's impossible to put down!
</div>
</Card>
<span style="color:green">*This is not yet the example, click a link from the left column in the table blow.*</span>
</Card>
</div>

| Name | Description |
Expand All @@ -66,7 +88,7 @@ These examples revolve around a tab component where you can switch between diffe

## Cross-Document View Transition Examples

These examples revolve around a picture component where you switch through different pictures.
These examples focus on a picture component where you navigate through individual pages, each displaying a different image. On every page, both the picture and the button that advances to the next page remain in the same position. While they move during the transition, these are purely **exit and entry** animations, with no morphing involved yet.

<div title="Select a link from the table below">
<Card title="Cross-Document 'Picture' Example">
Expand All @@ -93,6 +115,7 @@ These examples revolve around a picture component where you switch through diffe
alt="The Bag of Tricks"
/>
</div>
<span style="color:green">*This is not yet the example, click a link from the left column in the table blow.*</span>
</Card>
</div>

Expand All @@ -104,9 +127,9 @@ These examples revolve around a picture component where you switch through diffe

## Image Morph Examples

Morphing thumbnails into hero images is one of the classical use cases for view transition. The transition shows that the small thingy is a placeholder for the bigger one that now expands for you.

{" "}
Morphing thumbnails into hero images is a classic use case for view transitions. Morphing animations share the characteristic that the position and/or size of elements with the same view transition name differ before and after the transition. The animation visually connects the two, showing that the small thumbnail serves as a placeholder for the larger image.

<div title="Select a link from the table below">
<Card title="Thumbnail to Detail Morphs">
<style>{`
Expand Down Expand Up @@ -137,6 +160,7 @@ Morphing thumbnails into hero images is one of the classical use cases for view
<div class="portrait">![A Portrait](/portrait.webp)</div>
</div>
</div>
<span style="color:green">*This is not yet the example, click a link from the left column in the table blow.*</span>
</Card>
</div>

Expand All @@ -147,7 +171,7 @@ Morphing thumbnails into hero images is one of the classical use cases for view
| <DemoLink id="basicim3" href="/demo/BasicIM3/">Clipped overflow</DemoLink> | An alternative morph transition where images do not grow beyond the group outline |
| <DemoLink id="basicim4" href="/demo/BasicIM4/">Covered object fit</DemoLink> | A non-overflowing alternative for images with different aspect-ratio |

More to come. Especially morph animations.
More to come. Especially text morph animations.

import { Card } from "@astrojs/starlight/components";

Expand Down
2 changes: 1 addition & 1 deletion src/pages/crossing/plain/_PlainLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ const { title } = Astro.props;
</details>
<details open>
<summary>Group 4</summary>
<a href="/cross4ng/plain/1/">Page 1</a>
<a href="/crossing/plain/1/">Page 1</a>
<a href="/crossing/plain/2/">Page 2</a>
<a href="/crossing/plain/1/">Page 1</a>
<a href="/crossing/plain/2/">Page 2</a>
Expand Down
2 changes: 1 addition & 1 deletion src/pages/crossing/vanilla/_VanillaLayout.astro
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ const { title } = Astro.props;
</details>
<details open data-vtbag-x="#g4 @open">
<summary>Group 4</summary>
<a href="/cross4ng/vanilla/1/">Page 1</a>
<a href="/crossing/vanilla/1/">Page 1</a>
<a href="/crossing/vanilla/2/">Page 2</a>
<a href="/crossing/vanilla/1/">Page 1</a>
<a href="/crossing/vanilla/2/">Page 2</a>
Expand Down
21 changes: 21 additions & 0 deletions src/pages/tests/x.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
import Crossing from "astro-vtbot/components/ElementCrossing.astro";
---

<html>
<head>
<Crossing experimentalFeatures />
<title>Text X</title>
</head>
<body>
<button data-vtbag-x="#button &button">alert</button>
<script>
document
.querySelectorAll<HTMLButtonElement>("button")
.forEach((b) =>
b.addEventListener("click", () => (b.innerText = "" + new Date()))
);
</script>
<a href="/test/y/">goto y</a>
</body>
</html>
21 changes: 21 additions & 0 deletions src/pages/tests/y.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
import Crossing from "astro-vtbot/components/ElementCrossing.astro";
---

<html>
<head>
<Crossing experimentalFeatures />
<title>Text Y</title>
</head>
<body>
<span data-vtbag-x="#button &button">huch</span>
<a href="/test/x/">goto x</a>
<script>
document
.querySelectorAll<HTMLButtonElement>("button")
.forEach((b) =>
b.addEventListener("click", () => (b.innerText = "" + new Date()))
);
</script>
</body>
</html>
13 changes: 10 additions & 3 deletions src/styles/custom.css
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,16 @@ section.footnotes {
border-top: 1px solid var(--sl-color-gray-4);
}

h2 a,
h3 a,
h4 a {
a {
text-decoration: underline dotted;
}
:is(h1,h2,h3,h4,h5,h6) a {
text-decoration: none;
}
:is(nav,table,h1,h2,h3,h4,h5,h6) a {
text-decoration: none;
}
a.data-footnote-backref {
text-decoration: none;
}

Expand Down
107 changes: 58 additions & 49 deletions tests/01_crossing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,65 +7,74 @@ test('has title', async ({ page }) => {
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');
});

test('preserves DOM properties', async ({ page }) => {
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
await page.fill('#name', 'Jane Doe');
await page.selectOption('#gender', 'female');
await page.check('#interest1');
test.describe("vtbag", () => {
test('preserves DOM properties', async ({ page }) => {
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
await page.fill('#name', 'Jane Doe');
await page.selectOption('#gender', 'female');
await page.check('#interest1');

await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');
await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');

// @ts-expect-error
const nameValue = await page.$eval('#name', el => el.value);
// @ts-expect-error
const genderValue = await page.$eval('#gender', el => el.value);
// @ts-expect-error
const isCodingChecked = await page.$eval('#interest1', el => el.checked);
// @ts-expect-error
const nameValue = await page.$eval('#name', el => el.value);
// @ts-expect-error
const genderValue = await page.$eval('#gender', el => el.value);
// @ts-expect-error
const isCodingChecked = await page.$eval('#interest1', el => el.checked);

await expect(nameValue).toBe('Jane Doe');
await expect(genderValue).toBe('female');
await expect(isCodingChecked).toBe(true);
await expect(nameValue).toBe('Jane Doe');
await expect(genderValue).toBe('female');
await expect(isCodingChecked).toBe(true);

});
});

test('preserves class and CSS properties', async ({ page }) => {
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
const isDark1 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme1 = await page.$eval(':root', el => el.style.colorScheme);
test('preserves class and CSS properties', async ({ page }) => {
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
const isDark1 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme1 = await page.$eval(':root', el => el.style.colorScheme);

await page.click('#dl');
const isDark2 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme2 = await page.$eval(':root', el => el.style.colorScheme);
expect(isDark2).not.toBe(isDark1);
expect(colorScheme2).not.toBe(colorScheme1);
await page.click('#dl');
const isDark2 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme2 = await page.$eval(':root', el => el.style.colorScheme);
expect(isDark2).not.toBe(isDark1);
expect(colorScheme2).not.toBe(colorScheme1);

await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');
await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');

const isDark3 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme3 = await page.$eval(':root', el => el.style.colorScheme);
expect(isDark3).toBe(isDark2);
expect(colorScheme3).toBe(colorScheme2);
});
const isDark3 = await page.$eval(':root', el => el.classList.contains('dark'));
const colorScheme3 = await page.$eval(':root', el => el.style.colorScheme);
expect(isDark3).toBe(isDark2);
expect(colorScheme3).toBe(colorScheme2);
});


test('preserves animations and media timing', async ({ page }) => {
// todo: unable to get the video to play yet
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
await page.evaluate(async () => {
const video = document.querySelector("video");
video && video.play();
test('preserves animations and media timing', async ({ page }) => {
// todo: unable to get the video to play yet
await page.goto('http://localhost:4321/crossing/vanilla/1/');
await expect(page).toHaveTitle('Vanilla Element Crossing 1/2 | @vtbag');
await page.evaluate(async () => {
const video = document.querySelector("video");
video && video.play();
});
await new Promise(r => setTimeout(r, 1000));
const video1 = await page.$eval('video', el => el.currentTime);
console.log(video1);
await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');

const video2 = await page.$eval('video', el => el.currentTime);
console.log(video2);
});
await new Promise(r => setTimeout(r, 1000));
const video1 = await page.$eval('video', el => el.currentTime);
console.log(video1);
await page.click('text=Page 2');
await expect(page).toHaveTitle('Vanilla Element Crossing 2/2 | @vtbag');
});

const video2 = await page.$eval('video', el => el.currentTime);
console.log(video2);
test.describe("vtbot", () => {
test("astro integration", async ({ page }) => {
await page.goto('http://localhost:4321/tests/x/');
await expect(page).toHaveTitle('Test X');
});
});
1 change: 1 addition & 0 deletions tests/02_chamber.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ test.describe("controls", () => {
await page.click('#vtbag-ui-reopen');
await expect(page.locator('#vtbag-ui-reopen')).toBeHidden();
await page.click('#vtbag-ui-standby');
await expect(page.locator('#vtbag-ui-panel')).toBeHidden();
await expect(page.locator('#vtbag-ui-reopen')).toBeVisible();
})

Expand Down

0 comments on commit ac2d176

Please sign in to comment.