Gestures
Gesture states are overlays, not replacements. WhileHover,
WhileTap, WhileFocus, WhileDrag and
WhileInView layer on top of whatever Animate is currently showing and
revert themselves the moment the gesture ends - so you never write the "back to normal"
animation, and overlapping gestures resolve without any state of your own.
Hover and tap
The two workhorses. Both take an ordinary target, so anything animatable is fair game -
here a lift with a coloured shadow, and a press that scales down. Tap is
keyboard-accessible out of the box: give the element focus and
Enter or Space presses and releases it exactly like a pointer,
WhileTap included. Natively focusable elements get this for free; anything
else needs tabindex="0", as the first stage does.
Focus
WhileFocus plays while the element or any of its descendants holds focus. It is the accessible half of a hover effect: keyboard users get the same affordance pointer users do, without a second code path.
Pan
A pan is a pointer drag reported rather than applied: OnPan hands you
a BmPanInfo - the pointer position, the delta since the last event, the
total offset since the gesture began and the current velocity in pixels per second - and
leaves the element where it is. That is the hook for building your own drag behaviour
(a custom slider, a swipe-to-dismiss threshold) on top of the same gesture plumbing
Drag uses.
Gesture events
Every gesture also reports itself as a callback, so an animation can be paired with real
work. Note the ordering below: TapCancel fires instead of Tap when
the pointer leaves the element before release - which is what makes a press cancellable, and
why you should act on OnTap rather than OnTapStart.
Nested gestures
Pointer gestures bubble, so a tappable button inside a tappable card presses both. That is
usually right - a card that reacts to being pressed anywhere feels alive - but not when the
inner control has its own meaning. GesturePropagation="false" on the child
stops its tap and pan from reaching gesture-enabled ancestors, exactly as
DragPropagation does for drag. Press each button and watch the card behind it.
Hover is unaffected either way: pointerenter and pointerleave do
not bubble, so a child's hover was never its parent's problem.
Owning the transform string
Bmotion composes one transform from every animated component, in a fixed order.
TransformTemplate hands that string back to you before it is written -
useful when the element already needs a transform of its own that the animation must not
clobber. The classic case is an element centred on its own anchor with
translate(-50%, -50%): leave it in the CSS and the animation overwrites it,
so put it in the template instead and it survives every frame.