marp-cli icon indicating copy to clipboard operation
marp-cli copied to clipboard

[Experimental] Transitions for bespoke template (Second iteration)

Open yhatt opened this issue 3 years ago • 3 comments

Expreimental transitions are available in Marp CLI v2.0.0 and later + Google Chrome / Chromium 101 and later.

This issue is for tracking an experimental transitions support for bespoke template, and the content may change actively. Welcome your feedback about this experiment!

See "Guide" section of this issue for how to use transitions experiment. ⬇️

Quick look

https://marp-cli-page-transitions.glitch.me/ (Chrome 104+)

https://user-images.githubusercontent.com/3993388/169697466-283dd2f2-b6e5-4b33-86d4-b10cc0a6c3e9.mp4

Try this command to preview transitions on Marp CLI:

curl -o ./showcase.md https://gist.githubusercontent.com/yhatt/d9e86ee53eb8816aaf9c996e773b6f82/raw/transition-showcase.md
marp --bespoke.transition --preview ./showcase.md

Or see a transition showcase at Gist: https://gist.github.com/yhatt/d9e86ee53eb8816aaf9c996e773b6f82

Background

A slide transition is a very common feature in several full-featured presentation tools. However, handling transition tends to become complex due to rendering 2 pages while performing transitions.

Even in a simple case, where content fades from one screen to another, it means rendering your page with both states at once, performing a cross-fade, then removing the old state.

This is harder than it sounds. You need to make sure that the outgoing page can't receive additional interactions, and that the outgoing state doesn't jank the transition by updating its own state. You also need to ensure the presence of both states doesn't create a confusing experience for those using accessibility technology.

Smooth and simple page transitions with the shared element transition API - Chrome Developers

We believe that holding a complex logic makes hard to maintain the ecosystem, and will bring burnout eventually as like as a classic app. So we had ever not worked on transitions for Marp.

But it becomes a different story if provided a simple solution by the browser. Shared Element Transition API proposal provides a simple and high-level API for transition animations.

By using this proposal, transitions for Marp CLI bespoke template can get both of effective transitions for Marp slides and the ecosystem sustainability.

Helpful resources to know API

Guide

Prerequisite

The experimental transition feature is relied on Shared Element Transition API proposal. It is still early phase of proposal and not generally available in the most of browsers at this time.

This API requires Chromium 101 and later, with enabled documentTransition API experiment (chrome://flags/#document-transition or Origin Trials).

You can try experimental transitions easily by using Marp CLI preview window (--preview). The preview window will turn on a depending experiment automatically.

Enable experimental transitions

Add --bespoke.transition option.

marp --bespoke.transition --preview slide.md

The transition feature is bespoke template specific so it would not work in non-HTML format and other templates like bare template.

If you are using a custom engine which have supported transition custom directive like reveal.js based Marpit engine, the output HTML may break due to an overridden directive definition by a CLI option.

transition local directive

To use transition animations, you have to choose a transition effect for slide(s) by defining transition local directive in your Markdown.

---
transition: fade
---

# Slide

As same as other local directives like header and class, you can change the kind of transition in the middle of slides by defining the transition directive through HTML comment, or apply a specific transition into a single slide by using a scoped local directive (_transition: as known as spot directive).

---
transition: fade
---

# Fade transition

---

<!-- transition: cover -->

Changed the kind of transition to `cover`.

---

<!-- _transition: none -->

Disabled transition for this slide.

---

Got back cover transition.

transition directive will set the animation for "the next boundary between slides" (in another words "the next ruler ---"). It also means setting transition directive at the last slide would have no meaning.

Built-in effects

  • clockwise
  • counterclockwise
  • cover
  • coverflow
  • cube
  • cylinder
  • diamond
  • drop
  • explode
  • fade
  • fade-out
  • fall
  • flip
  • glow
  • implode
  • in-out
  • iris-in
  • iris-out
  • melt
  • overlap
  • pivot
  • pull
  • push
  • reveal
  • rotate
  • slide
  • star
  • swap
  • swipe
  • swoosh
  • wipe
  • wiper
  • zoom

Check the video at the top section of this issue.

You also can turn off the transition effect by setting none.

Set custom duration

The default duration of transition is 0.5s in all transitions, but you can set custom duration by adding a space-separated parameter to transition directive definition.

transition: fade 1s

Custom duration should have a unit s or ms.

Custom transition 🌠

In the second iteration of transition experiment, you can define the custom transition through CSS. You can make your own transition effect just by declaring animation keyframes.

@keyframes marp-incoming-transition-triangle {
  from { clip-path: polygon(0% 0%, 0% 0%, 0% 0%); }
  to { clip-path: polygon(0% 0%, 200% 0%, 0% 200%); }
}

@keyframes marp-incoming-transition-backward-triangle {
  from { clip-path: polygon(100% 100%, 100% 100%, 100% 100%); }
  to { clip-path: polygon(-100% 100%, 100% -100%, 100% 100%); }
}

This is very exciting and so creative feature! We are using exist CSS @keyframes declarations and never adding Marp specific syntax to CSS, so there should be no CSS complexity losing too. You also can tweak animation of built-in transitions by overloading keyframes.

We are really looking forward to what creative transitions our community will create!!

:arrow_right: See blog article: "Marp CLI Experimental: How to make custom transition"

Features from Shared Element Transition proposal

Transition with shared elements (v2.0.2 and later)

By using page-transition-tag CSS property, you can make the specific elements move individually during transition, just like as PowerPoint Morph and Keynote Magic Move.

In a below example, the first <h1> element in each slide page and the image <img> that has shared space-separated keyword in alt attribute are marked as shared elements. If there were a pair of tagged elements with the same name in the outgoing slide and incoming slide, these will have a morph animation during transition.

---
theme: gaia
_class: lead
transition: slide 1s
style: |
  section > h1:first-of-type {
    contain: paint;
    page-transition-tag: title;
  }
  img[alt~="shared"] {
    contain: paint;
    page-transition-tag: image;
  }
---

![shared w:400](https://marp.app/assets/marp.svg)

# Transition with shared elements

---

# It's a Magic! 🪄

![shared w:500](https://media1.giphy.com/media/ujUdrdpX7Ok5W/giphy.gif)

Currently contain: paint; is also required to work the morph animation.

Please note that the tagged element with the same name should have determined uniquely for each slide. If there are duplicate elements in the same slide, the whole of transition animation will fail due to the runtime error.

For marking page-transition-tag with more flexibility, you can also use the <span> element with a custom class by enabling HTML tag rendering through --html option.

---
transition: cube 1s
style: |
  .shared-title {
    display: inline-block;
    contain: paint;
    page-transition-tag: shared-title;
  }
---

# <span class="shared-title">Shared</span> Element Transition

---

![bg left](https://images.unsplash.com/photo-1651597966373-11423151d07f?crop=entropy&cs=tinysrgb&fit=crop&fm=jpg&h=720&q=80&w=640)

## <span class="shared-title">Morphed!</span>

Reference: https://github.com/WICG/shared-element-transitions/blob/main/explainer.md#via-css

Opt-out transitions

Of course, not everyone is fun of dizzy animation from a transition effect. Transitions in the presentation often may have too much movings, and someone may feel it like as motion sickness.

So we respect prefers-reduced-motion media query in the converted HTML, to be able to make the slide viewer opt-out transition animations. If a user preference in response to prefers-reduced-motion has set, all kind of transitions are forced to a constant dissolve effect as same as fade built-in transition. Shared elements defined by author have no animations too.

Status in Marp ecosystem

In Marp CLI, --bespoke.transition is going to keep experimental and optional until Shared Element Transition API proposal makes stable and generally available in at least one of major browsers.

If become stable, we are going to add support of transitions for downstream tools too. (e.g. auto-complete of transition directive in Marp for VS Code)

Known topics

  • Don't forget this is cutting edge of Chrome currently. Sometimes you might meet not working transition or crashed tab.
  • [as-designed] Animation for transition is targeting to whole of the view that includes slide letterbox / pillarbox.
  • ~~[enhancement] A local-scoped keyframes set by <style scoped> cannot use as transition keyframes.~~
    • Fixed in v2.0.2: #456

Changelog

See #382 to see about previous iteration.

yhatt avatar May 14 '22 20:05 yhatt

Is this transition can used for vscode extention?

tianfanghan avatar Jun 03 '22 12:06 tianfanghan

@tianfanghan Not yet. Please read "Status in Marp ecosystem" section.

If become stable, we are going to add support of transitions for downstream tools too. (e.g. auto-complete of transition directive in Marp for VS Code)

yhatt avatar Jun 03 '22 12:06 yhatt

Hi yhatt, I just wanted to say a big thank you to you and the team for this long awaited transition feature! I've tried in Ubuntu and Arch Linux and it works like a charm with the provided instructions and the downloaded marp-cli binary. Great work :)

arseru avatar Jul 09 '22 11:07 arseru

PSA: the viewTransition.domUpdated promise is now viewTransition.updateCallbackDone.

Hopefully that'll be our last rename on the road to shipping! https://groups.google.com/a/chromium.org/g/blink-dev/c/AJJiH6Pjr50

— https://twitter.com/jaffathecake/status/1616422515684810753

This property is not referenced by bespoke transition plugin in reality, so (probably) there is nothing to worry about breaking transitions in exist slides. On the other hand, we may have to modify a defined type interface and unit testing. https://github.com/search?q=repo%3Amarp-team%2Fmarp-cli%20domUpdated&type=code

yhatt avatar Jan 20 '23 16:01 yhatt

Thank you for all your work on this! Are there any plans to allow transitions such as "fade" to also work with .pptx exports?

ntjess avatar Jan 29 '23 21:01 ntjess

Thanks for your feedback! We have thought that transition effects can be applied to PPTX if Markdown is using the built-in effect that is compatible with PPTX. Actually I have already tried the implementation for getting transition effects in PDF, and worked well. However, I've postponed PDF transition effects due to lacked support in Acrobat Reader for Mac

At this moment, it's difficult to implement transition effects to PPTX shortly, because PptxGenJS (a presentation generation library Marp is using) has no support about slide transitions, and I'm not familiar with a specification of PPTX file format.

If received more feedbacks, we consider to work on the transition support for other file formats. Of course, we are welcome to contribute from community.

yhatt avatar Jan 29 '23 23:01 yhatt