vue-collision
| Install | |
|---|---|
npm install vue-collision |
|
| Latest Version: | 2.0.2 |
| Vue: | 3 |
| Older releases: | 2 |
| License: | MIT |
| Last Updated: | Oct 13, 2026 |
| Links: | GitHub · npm |
vue-collision
Vue 3 directive that fires
collide/non-collideevents when an element enters or leaves the viewport, plus element-to-element group collision detection via AABB.
Features
- Viewport collision via
IntersectionObserver— zero-cost, edge-triggered - Element-to-element group collision via rAF + AABB overlap — groups any number of elements and checks every pair
- Fires native DOM
CustomEvents (collide,non-collide,collide-<group>,non-collide-<group>) - Grouping: place elements in named groups; any pair within a group is checked
.preventmodifier to opt out of viewport tracking- TypeScript source with
.d.tsdeclarations - Vue 3 only (v2.x); for Vue 2 use v1.x
Install
npm install vue-collision
Quick start
main.ts
import { createApp } from 'vue'
import VueCollision from 'vue-collision'
import App from './App.vue'
createApp(App)
.use(VueCollision, { globalTriggers: ['resize', 'scroll'] })
.mount('#app')
Component (<script setup>)
<script setup lang="ts">
const onCollide = (e: CustomEvent) => {
// e.detail is `window` for viewport events
console.log('in viewport', e.detail)
}
const onLeave = (e: CustomEvent) => {
console.log('left viewport')
}
const onGroupCollide = (e: CustomEvent<HTMLElement>) => {
// e.detail is the other element this element collided with
console.log('collided with', e.detail)
}
</script>
<template>
<!-- tracks viewport + 'groupA' element collisions -->
<div
v-collision="['groupA']"
@collide="onCollide"
@non-collide="onLeave"
@collide-groupA="onGroupCollide"
@non-collide-groupA="onGroupCollide"
/>
<!-- viewport only (no custom group) -->
<div v-collision @collide="onCollide" @non-collide="onLeave" />
<!-- groupA only, skip viewport tracking -->
<div
v-collision.prevent="['groupA']"
@collide-groupA="onGroupCollide"
/>
</template>
Directive reference
| Syntax | Behaviour |
|---|---|
v-collision |
Viewport group + IntersectionObserver |
v-collision.prevent |
Opt out of viewport group |
v-collision="['g1', 'g2']" |
Add to named groups (g1, g2) |
v-collision.prevent="['g1']" |
Named groups only, no viewport tracking |
Events
All events are native DOM CustomEvents. Read the collider from event.detail.
| Event | Fires when | event.detail |
|---|---|---|
collide |
Element enters the viewport | window |
non-collide |
Element leaves the viewport | window |
collide-<group> |
Element overlaps another in the same group | The other HTMLElement |
non-collide-<group> |
Element stops overlapping another in the same group | The other HTMLElement |
Plugin options
app.use(VueCollision, {
// Events that trigger element-group re-checks. Default: ['resize', 'scroll']
globalTriggers: ['resize', 'scroll'],
})
Migrating from v1 (Vue 2 → Vue 3)
v2.0.0 is a full Vue 3 rewrite. Key breaking changes:
-
Install — replace
Vue.use(...)withapp.use(...). -
Event delivery — events are now native DOM
CustomEvents, not Vue component events. The collider is onevent.detail, not the first argument:// v1 (Vue 2) onCollide(collider) { /* collider was the Vue instance */ } // v2 (Vue 3) onCollide(event) { const collider = event.detail } -
Listen with
@on a plain element —v-collisionmust be placed on a host element (<div>,<section>, etc.) not a component root. If your component exposes its root element, usev-bind="$attrs"to forward the listeners. -
Viewport detection — now uses
IntersectionObserverinstead ofrequestAnimationFramepolling (lower CPU, fires immediately). -
Element-group re-check timing — element-group collision is checked once per frame-request, triggered by mount,
updated, and the configuredglobalTriggers(default:resize,scroll). Pure CSS transforms or animations that move elements without triggering a scroll, resize, or Vue reactive update will not automatically re-check. Add a global trigger event or callwindow.dispatchEvent(new Event('resize'))to force a re-check if needed.
Development
npm install
npm run typecheck
npm run build
npm test
License
MIT
Related Packages
Trigger functions and events based on an element's position on screen — a tiny,...
Named, reactive, matchMedia-based viewport breakpoints for Vue 3 — a tiny plugin...
Version History
| Version | Released | Vue | License |
|---|---|---|---|
| 2.0.2 | ^3.0.0 | MIT | |
| 2.0.1 | ^3.0.0 | MIT | |
| 2.0.0 | ^3.0.0 | MIT | |
| 1.6.0 | ^2.0.1 | MIT | |
| 1.5.1 | ^2.0.1 | MIT | |
| 1.5.0 | ^2.0.1 | MIT | |
| 1.4.0 | ^2.0.1 | MIT | |
| 1.3.3 | ^2.0.1 | MIT | |
| 1.3.2 | ^2.0.1 | MIT | |
| 1.3.1 | ^2.0.1 | MIT | |
| 1.3.0 | ^2.0.1 | MIT | |
| 1.2.1 | ^2.0.1 | MIT | |
| 1.2.0 | ^2.0.1 | MIT | |
| 1.1.2 | ^2.0.1 | MIT | |
| 1.1.1 | ^2.0.1 | MIT | |
| 1.1.0 | ^2.0.1 | MIT | |
| 1.0.1 | ^2.0.1 | MIT | |
| 1.0.0 | ^2.0.1 | MIT | |
| 0.0.30 | ^2.0.1 | MIT | |
| 0.0.29 | ^2.0.1 | MIT | |
| 0.0.28 | ^2.0.1 | MIT | |
| 0.0.27 | ^2.0.1 | MIT | |
| 0.0.26 | ^2.0.1 | MIT | |
| 0.0.25 | ^2.0.1 | MIT | |
| 0.0.24 | ^2.0.1 | MIT | |
| 0.0.23 | ^2.0.1 | MIT | |
| 0.0.22 | ^2.0.1 | MIT | |
| 0.0.21 | ^2.0.1 | MIT | |
| 0.0.20 | ^2.0.1 | MIT | |
| 0.0.19 | ^2.0.1 | MIT |
Showing the latest 30 of 48. See every release on npm