Quasar is a popular Vue UI library for developing good looking Vue apps.
In this article, we’ll take a look at how to create Vue apps with the Quasar UI library.
Touch Pan Directive
We can listen to touch pan events with the v-touch
directive.
For example, we can write:
<!DOCTYPE html>
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
rel="stylesheet"
type="text/css"
/>
<link
href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body class="body--dark">
<script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
<div id="q-app">
<div class="q-pa-md">
<q-card
v-touch-pan.prevent.mouse="handlePan"
class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
>
<div v-if="info" class="custom-info">
<pre>{{ info }}</pre>
</div>
<div v-else class="text-center">
<q-icon name="arrow_upward"></q-icon>
<div class="row items-center">
<q-icon name="arrow_back"></q-icon>
<div>Pan in any direction</div>
<q-icon name="arrow_forward"></q-icon>
</div>
<q-icon name="arrow_downward"></q-icon>
</div>
<div v-show="panning" class="touch-signal">
<q-icon name="touch_app"></q-icon>
</div>
</q-card>
</div>
</div>
<script>
new Vue({
el: "#q-app",
data: {
info: null,
panning: false
},
methods: {
handlePan({ evt, ...info }) {
this.info = info;
if (info.isFirst) {
this.panning = true;
} else if (info.isFinal) {
this.panning = false;
}
}
}
});
</script>
</body>
</html>
We add the v-touch-pan
directive to the element we want to watch the touch and pan events for.
Then we get the event info from the first parameter of the event listener.
We get the distance, duration, offset, position, and more with the parameter.
isFirst
indicates whether it’s the start of mouse drag or touch pan.
And isFinal
indicates whether it’s the end of the mouse drag or touch pan.
We can restrict the direction of panning that’s detected for horizontal directions only with the horizontal
modifier:
<!DOCTYPE html>
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
rel="stylesheet"
type="text/css"
/>
<link
href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body class="body--dark">
<script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
<div id="q-app">
<div class="q-pa-md">
<q-card
v-touch-pan.horizontal.prevent.mouse="handlePan"
class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
>
<div v-if="info" class="custom-info">
<pre>{{ info }}</pre>
</div>
<div v-else class="text-center">
<div class="row items-center">
<q-icon name="arrow_back"></q-icon>
<div>Pan left or right</div>
<q-icon name="arrow_forward"></q-icon>
</div>
</div>
<div v-show="panning" class="touch-signal">
<q-icon name="touch_app"></q-icon>
</div>
</q-card>
</div>
</div>
<script>
new Vue({
el: "#q-app",
data: {
info: null,
panning: false
},
methods: {
handlePan({ evt, ...info }) {
this.info = info;
if (info.isFirst) {
this.panning = true;
} else if (info.isFinal) {
this.panning = false;
}
}
}
});
</script>
</body>
</html>
Also, we can change the modifier to vertical
to watch up and downward panning only:
<!DOCTYPE html>
<html>
<head>
<link
href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons"
rel="stylesheet"
type="text/css"
/>
<link
href="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.min.css"
rel="stylesheet"
type="text/css"
/>
</head>
<body class="body--dark">
<script src="https://cdn.jsdelivr.net/npm/vue@^2.0.0/dist/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/quasar@1.12.13/dist/quasar.umd.min.js"></script>
<div id="q-app">
<div class="q-pa-md">
<q-card
v-touch-pan.vertical.prevent.mouse="handlePan"
class="custom-area cursor-pointer bg-primary text-white shadow-2 relative-position row flex-center"
>
<div v-if="info" class="custom-info">
<pre>{{ info }}</pre>
</div>
<div v-else class="text-center">
<div class="row items-center">
<div>Pan up or down</div>
</div>
</div>
<div v-show="panning" class="touch-signal">
<q-icon name="touch_app"></q-icon>
</div>
</q-card>
</div>
</div>
<script>
new Vue({
el: "#q-app",
data: {
info: null,
panning: false
},
methods: {
handlePan({ evt, ...info }) {
this.info = info;
if (info.isFirst) {
this.panning = true;
} else if (info.isFinal) {
this.panning = false;
}
}
}
});
</script>
</body>
</html>
Conclusion
We can watch touch pan events with the v-touch-pan
directive.