DEV Community

Abdeldjalil Hebal
Abdeldjalil Hebal

Posted on

Using SVG <symbol> as a Camera (Danganronpa Back and Forth)

I like SVG. I like Danganronpa. I tried to recreate a Danganronpa-like camera panning effect in SVG.

Demo

TLDR:
We can use SVG <symbol> and <use> elements to create a camera, similar to the ones you may find in video editors, game engines, and the like (After Effects, Unity, and Blender, to name a few).
The goal was to recreate a panning effect as seen in Danganronpa games or fan projects.

PS: This is not a step-by-step tutorial.

  • This is mostly a proof of concept.
  • I will provide a high-level overview, mention specific implementation details, and link to further readings.
  • I assume you are somewhat familiar with CSS animations and SVG.

The idea

Danganronpa panning effect

In official Danganronpa games and fan projects: Danganronpa F: Shattered Hope (made in After Effects), Project: Eden's Garden (made in Unity), and even some memes/remixes.

If I recall correctly, in Danganronpa 2, the following sequence happens:

  • At the start of the animation, blur all characters except the active speaker.
  • Move the camera to the active speaker.
  • At the end of the animation, unblur all characters.

We could try to recreate that.

We also could make it more like Danganronpa F:

  • Make it 2.5D (3D transforms of 2D sprites).
  • Add depth of vision effect.
  • Add motion blur effect.
  • Etc.

But let's focus on camera panning for now.

Danganronpa F tutorial

drf-cancel
Danganronpa F: Cancel.
Notice that there are two cameras: A complete view of the stage and a close-up view of the active speaker (again, same stage).

One of Danganronpa F's creators made a video tutorial about it.
They use After Effects, but their techniques can be employed in other contexts, like Web technologies.

See Panning and Camera - Fanganronpa Tutorial (AE) | YouTube.

Essentially, they:

  • Set up the composition or world (background and characters).
  • Use a camera (Camera 1) to show the entire composition, covering the entire screen.
  • Draw a semi-transparent overlay.
  • Use another camera (Camera 2) to show a close-up view of the composition.
  • Update Camera 2's position (x, y, and z) to switch focus between characters... Panning.

Main layers and the main idea

drv3-letsgo-1
Danganronpa V3: World.


drv3-letsgo-2
Danganronpa V3: World + overlay.


drv3-letsgo-3
Danganronpa V3: World + overlay + close-up camera + UI.
Notice that the girl wearing a hat (Himiko) is still visible behind the overlay.

Translating concepts

Naming things is hard. So, let's reuse terms commonly found in game dev: scene, UI, world, and camera. (These will be our variables or element IDs.)

They are comparable to concepts found in game engines (e.g. Unity or Ren'Py), video editing software (e.g. After Effects), or 3D animation software (e.g. Blender).

Elements:

  • The scene is the whole composition.
  • The world contains "game" objects (the background, characters, items, etc.).
  • The camera defines a viewport or perspective on the world.
  • The UI acts as an overlay on top of the world and includes textboxes and whatnot.

Pseudocode

<svg id="scene">
    <g id="world">
        <image id="background" />
        <image id="nagito" />
        <image id="hajime" />
    </g>

    <symbol id="camera" viewBox="...">
        <use href="#world" />
    </symbol>
    <use href="#camera" />

    <rect id="overlay" />

    <g id="ui">
        <text id="speaker">???</text>
        <text id="dialog">No, that's wrong!</text>
    </g>
</svg>
Enter fullscreen mode Exit fullscreen mode

Impl details

Suppose this is our world and we want to change the camera focus from Nagito (blue rect) to Hajime (red rect):
Inkscape

To animate the symbol's viewBox, we could use GSAP or a similar library, but since the animation is basic, I decided to use only the <animate> element.

Alternating: SVG does not have something similar to CSS animation-direction: alternate. To recreate it, we have to define two animations and make each one start at the end of the other. To start this loop, we also set one of them (toHajime) to start at 0s in the document's timeline (i.e. once the document loads).

<!-- From Nagito to Hajime and then back to Nagito -->
<animate id="toHajime" begin="0s; toNagito.end" />
<animate id="toNagito" begin="toHajime.end" />
Enter fullscreen mode Exit fullscreen mode

Delaying: We want the camera to pause for a brief moment (say, 1s) at each sprite before moving to the other.
Turns out, we can write something like toNagito.end + 1s to delay the execution of the animation, relative to another event.
We also use fill="freeze" to keep the animation's last frame's state, similar to CSS animation-fill-mode: forwards.

2.5D or 3D perspective: Sadly, SVG does not support 3D transforms. That's why everything is 2D.

Custom easing: Check oak's post.
Easing function used: easeInOutQuint (cubic-bezier(0.86,0,0.07,1)). See https://easings.co.

Conclusion

???

Takeaways:

  • Transferable knowledge and whatnot.
  • SVG is cool.

Further reading

Top comments (0)