Experiments >

Code animation: Horizontal zooming

Experiment #12111th April, 2021by Joshua Nussbaum

This experiment is about how to zoom the timeline.

It uses an <input type=range/> to adjust the current zoom level.

<input type=range bind:value={zoom}/>

The scale factor is calculated as a reactive statement:

$: scale = zoom / 100

Then we can adjust the left and width position of each timeline element based on the scale factor:

<button class="step" style="width: {step.duration*scale}px; left: {step.offset*scale}px">
  <span>{step.label}</span>
</button>

Keyboard event

It also handles keyboard events:

  • CTRL+plus to zoom in.
  • CTRL+minus to zoom out.
  • CTRL+0 to zoom out.

All it took was handling on:keydown with <svelte:window>:

<svelte:window on:keydown={keydown}/>

And the keydown() function looks like this:

function keydown(event) {
  // handle CTRL+plus
  if (event.key == '+' && event.ctrlKey) {
    if (zoom + increment > max) {
      zoom = max
    } else {
      zoom += increment
    }
    
    event.preventDefault()
  }
  
  // handle CTRL+minus
  if (event.key == '-' && event.ctrlKey) {
    if (zoom - increment < min) {
      zoom = min
    } else {
      zoom -= increment
    }
    
    event.preventDefault()
  }
  
  // handle CTRL+0
  if (event.key == '0' && event.ctrlKey) {
    zoom = 100
    event.preventDefault()
  }
}

Text wrapping

One final touch was handling word wrapping. When the zoom level is very high, the text is chopped and ... is added. It’s great that there is a pure css solution for that. In the old days that would have required code.

.step {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

Code

https://svelte.dev/repl/266f525f77c647cb97c655608df4c56e?version=3.37.0

Demo

Notes

  • Figure out how to make this work for tick marks as well.
view all experiments

Stay tuned in

Learn how to add more experimentation to your workflow