Navigating from code
Everything a user does with clicks, you can do from code. Every method returns a promise that settles when the transition ends.
Use the buttons above the canvas. Each one turns on in the views where it applies.
The code
The buttons call the app directly:
<nav class="toolbar">
<button data-in="home" onclick="app.zoomTo('settings')">zoomTo('settings')</button>
<button data-in="profile" onclick="app.goTo('privacy', { mode: 'lateral' })">goTo('privacy', lateral)</button>
<button data-in="settings profile privacy" onclick="app.zoomOut({ to: 'home' })">zoomOut({ to: 'home' })</button>
<button onclick="app.back()">back()</button>
</nav>
const app = new Zumly({
mount: '.canvas',
initialView: 'home',
views: {
home: `<div class="z-view home" data-title="Home">
<h1>Home</h1>
<div class="zoom-me" data-to="settings">Settings</div>
</div>`,
settings: `<div class="z-view card" data-title="Settings">
<h2>Settings</h2>
<div class="zoom-me" data-to="profile">Profile</div>
<div class="zoom-me" data-to="privacy">Privacy</div>
</div>`,
profile: `<div class="z-view card" data-title="Profile"><h2>Profile</h2></div>`,
privacy: `<div class="z-view card" data-title="Privacy"><h2>Privacy</h2></div>`
}
})
// After every navigation: show where we are, enable the buttons that apply here
app.on('viewChanged', ({ viewName }) => {
document.querySelector('.path').textContent =
app.getViewStack().map(view => view.title).join(' › ')
document.querySelectorAll('[data-in]').forEach(button => {
button.disabled = !button.dataset.in.split(' ').includes(viewName)
})
})
// Optional: the URL hash follows navigation, and the browser back button goes back
app.use(Zumly.Router)
app.init()
Methods
| Method | Does |
|---|---|
zoomTo(name) | Zoom into a view from the center of the canvas. |
zoomIn(trigger) | Zoom in from a trigger element, as a click would. |
goTo(name, { mode: 'lateral' }) | Move to a sibling. Add props to pick one of several that share a view: { id: 'bedroom' }. |
zoomOut(), zoomOut(2), zoomOut({ to: 'home' }) | Zoom out one level, several, or up to an ancestor, in one transition. |
back() | Undo the last sideways move, or zoom out. |
getCurrentViewName(), getViewStack() | Where the user is, and the views from the root down with their titles. |
A call made while another navigation runs is ignored, so await the calls you chain:
await app.zoomTo('settings')
await app.goTo('privacy', { mode: 'lateral' })
await app.back()
Events
viewChanged fires after every navigation, including the first render. There are also beforeZoomIn, afterZoomOut, afterLateral and others; the API reference lists them all.
Router
app.use(Zumly.Router) writes the path to the hash (#/home/settings/profile) and makes the browser back button go back. A view opened from a trigger with data keeps it in the path: #/house/room?id=kitchen. Opening a deep URL directly is not supported: a zoom needs the trigger it comes from.
With a bundler there is no global Zumly: import { ZumlyRouter } from 'zumly' and app.use(ZumlyRouter).