Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A Flipping Book Magic #11

Open
9am opened this issue Apr 10, 2023 · 1 comment
Open

A Flipping Book Magic #11

9am opened this issue Apr 10, 2023 · 1 comment
Assignees
Labels
animation Animation css CSS javascript JavaScript

Comments

@9am
Copy link
Owner

9am commented Apr 10, 2023

After 12 years, I did it again. But with HTML/CSS/JS!

flipping-book

hits

@9am
Copy link
Owner Author

9am commented Apr 10, 2023

13 years ago, I just started my career at a startup company. We were building a social APP running on Adobe Flash runtime, which is written in ActionScript3. At that time, web technology is not ready for an RIA(rich interact application), so many things are missing(transition, rotation...) if you want to build something fancy(right in the middle of the Browser Chaos), Flash is the only way to keep the consistency of your app among those browsers.

After 1 year of using the fantastic ActionScript3, I decided to make something outside of work using it. This is my habit of learning a new skill: I will come up with an idea. To fulfill that idea, the proportion of skills I already know to skills I don't know is about 80/20. So after this project, I will test the 80% I've learned and learn 20% new.

The idea to test my ActionScript3 at that time was a Flipping Book.

Flipping Book is an interactive animation that simulates a 3d book flipping effect using 2d programming.
flipr-ss

After 12 years, flash is dead, and the web has evolved a lot in a way I can't even imagine. So same old trick but new technology, I'll build it again. And I know for sure I will learn something new and have some fun during the process. Let's Go!

The Goals

  1. 4 trigger areas at the corner of the book, activate the animation after the mouse enters, and take a drag&drop action to turn the page to the next or previous one.
  2. Make a dynamic shadow effect.
  3. Render the page content from an HTML template.

The Geometry

The geometry is simple as in the old days, take the right top trigger area as an example:

  1. For each frame of the animation, draw a line segment(MR) from the Mouse to the Root corner of the active trigger area.
  2. Draw the perpendicular bisector line of MR as PB.
  3. Find the intersection points of PB and the book boundary lines [i0, i1, i2, i3]
  4. The polygon [R0, R1, i2, i0] will be the mask of the page after the next.
  5. Get the reflection polygon by PB, which will be the mask of the next page.
  6. To make the page looks real, we need to restrain the position of the Mouse. It can not be outside those two circles since one side of the page is stuck to the middle of the book.

Although there are so many details to consider, this model is good enough, to begin with.
flipr 001

The Technical Bricks

1. Draw the polygons, HTML, SVG, or Canvas?

In 2023, we have so many choices to do this. SVG has been there for a while and Canvas also provides a bunch of drawing APIs. A normal HTML tag seems to be the last one we consider. It's pretty hard to draw a random polygon with only HTML and CSS. With the old border trick, a triangle is the best we can get.

But to consider actual content in the book, Canvas can only draw an HTMLImageElement. And SVG can only work with its own elements. It would be really nice if we could find a way to draw the polygons using only a normal HTML tag and CSS.

Leave this challenge to the next section, we can build our first implementation with Canvas.
polygon

2. Build a mask

As you can see in the GIF, for the next or previous page, we can only see part of the page content. So we need to figure out how to "block" things out.

Canvas provide an API to clip the context CanvasRenderingContext2D.clip(). SVG gives us a <clipPath> element to do the trick. And as for CSS, we have clip-path and mask now.

At this point, everything comes to the right place. We can render any HTML content to the page, and use CSS to transition: rotate() the element and clip-path the area to any path we want.
clip

2. A shadow to fool the eyes

We need shadows, without them the book will be like this:
shadow-no

SVG and Canvas have filter to make this happen. Lucky for us, CSS gives us linear-gradient and filter too.

To make it even better, we can use CSS custom properties to update the depth of the shadow as we drag the page.
shadow-only

@9am/flipr

With all of those in mind, I build a lib. Feel free to try it~
@9am/flipr 📖
npm

npm install @9am/flipr

Edit random-image

What are the new things I've learned from building this?

  • I use Rxjs to get the mouse movement and DnD process, it's a new way of thinking user interaction for me.
  • Have a better understanding of transform, clip-path, and gradient.
  • And.... inevitably, I build it with typescript.

Well, hope you enjoy it. I'll see you next time.


@9am 🕘

@9am 9am added javascript JavaScript css CSS animation Animation labels Apr 10, 2023
@9am 9am self-assigned this Apr 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
animation Animation css CSS javascript JavaScript
Projects
None yet
Development

No branches or pull requests

1 participant