UI events and interactions
Pose for Vue can be used to power and animate interactions. Currently, it supports the following events: drag, press, hover and focus.
In this tutorial, we’ll take a look at each.
Drag
With Pose for Vue, making an element draggable is as simple as passing draggable: true
to the config:
const Box = posed.div({
draggable: true
});
true
sets both axis to draggable, but we can select a single axis to drag by setting it to 'x'
or 'y'
.
Boundaries
We can add boundaries to the range of motion with the dragBounds
property.
It accepts top
, left
, bottom
and/or right
, measured in pixels or percentages:
const Box = posed.div({
draggable: 'x',
dragBounds: { left: '-100%', right: '100%' }
});
Poses
When a posed component is draggable, two new poses are fired.
While dragging is active, the drag
pose takes effect.
const Box = posed.div({
draggable: true,
init: { scale: 1 },
drag: { scale: 1.2 }
});
Note: A current limitation with the drag
pose is you must leave transition
undefined.
When dragging finishes, by default all values revert to their previous pose. Optionally, a dragEnd
pose can be defined:
const Box = posed.div({
draggable: true,
init: { scale: 1 },
drag: { scale: 1.2 },
dragEnd: { scale: 0.5 }
});
You can use this pose to animate x
and y
, too. For instance, you could make the object spring back to its origin:
const Box = posed.div({
draggable: true,
init: { scale: 1 },
drag: { scale: 1.2 },
dragEnd: {
x: 0,
y: 0,
transition: { type: 'spring' }
}
});
Events
We can respond to drag start, drag end, and value change events to trigger updates in our UI.
You can attach listeners for the drag-start
and drag-end
events, as well as a map of listeners for each animated property to on-value-change
:
<template>
<Box
class="box"
:on-value-change="{ x: log }"
v-on:drag-start="log"
v-on:drag-end="log"
/>
</template>
<script>
import posed from 'vue-pose';
export default {
methods: { log: console.log },
components: {
Box: posed.div({ draggable: true })
}
};
</script>
Press
With pressable
set to true
, you can respond to mouse and touch down events with the press
pose:
const Box = posed.div({
pressable: true,
init: { scale: 1 },
press: { scale: 0.8 }
});
By default, when pressing ends, values will return to their previous pose. You can optionally set a pressEnd
pose to override this.
Events
We can respond to press start and end events with the press-start
and press-end
listeners:
<template>
<Box class="box" v-on:press-start="log" v-on:press-end="log" />
</template>
<script>
import posed from 'vue-pose';
export default {
methods: { log: console.log },
components: {
Box: posed.div({
pressable: true,
init: { scale: 1 },
press: { scale: 0.8 }
})
}
};
</script>
You might prefer to use this over Vue’s in-built events because Pose’s event handling method avoids the annoying situation where a user presses an element, and only stops pressing once they’ve moved their pointer outside the element.
Those mouse-up
/touch-end
callbacks only fire if the pointer is still on the triggering element, whereas press-end
will fire anywhere in the page.
Hover
Components can respond to hovers by settings hoverable
to true
. This will enable use of the hover
pose:
const Box = posed.div({
hoverable: true,
init: {
scale: 1,
boxShadow: '0px 0px 0px rgba(0,0,0,0)'
},
hover: {
scale: 1.2,
boxShadow: '0px 5px 10px rgba(0,0,0,0.2)'
}
});
By default, when hovering ends, values will return to their previous pose. You can optionally set a hoverEnd
pose to override this.
Focus
Focusable elements can animate into the focus
pose by setting focusable: true
:
const Box = posed.input({
focusable: true,
init: {
color: '#aaa',
outlineWidth: '0px',
outlineOffset: '0px',
scale: 1
},
focus: {
color: '#000',
outlineWidth: '12px',
outlineOffset: '5px',
outlineColor: '#AB36FF',
scale: 1.2
}
});
By default, when hovering ends, values will return to their previous pose. You can optionally set a blur
pose to override this.