Vue createRenderer for PixiJS
- ๐ Lightweight and flexible Vue 3 library for creating PixiJS applications.
- โ๏ธ Provides a Custom Vue Renderer that creates PixiJS objects instead of HTML elements.
- ๐ฆ Supports all PixiJS objects, such as
Filter
,Container
,Sprite
,Graphics
,Text
, etc - ๐งโ๐ป Support specifying
texture
paths in templates to load texture objects - โจ All events emitted by PixiJS objects are supported
- ๐๏ธ Offers Assets component for bundling assets and Feature Rich Composition Utilities.
- ๐ซ Create different transition effects in conjunction with @vue3-pixi-transition.
# with pnpm
pnpm add vue3-pixi
# with yarn
yarn add vue3-pixi
The <Stage>
component can be used to embed a pixi app into an existing vue app.
<script setup lang="ts">
import { Stage } from "vue3-pixi";
import textureUrl from "@/assets/myTexture.png";
const hitArea = new Rectangle(0, 0, 64, 64);
function onClick() {
console.log('sprite clicked!');
}
</script>
<template>
<Stage :width="640" :height="480">
<container>
<sprite :texture="textureUrl" :hit-area="hitArea" @click="onClick" />
</container>
</Stage>
</template>
The vite plugin adds the ability to specify texture paths on sprites & other components that use textures, the same way as the src
attribute on an image.
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { compilerOptions, transformAssetUrls } from 'vue3-pixi'
export default defineConfig({
plugins: [
vue({
template: {
// remove the unknown element warnings
compilerOptions,
// support for asset url conversion
transformAssetUrls,
},
}),
],
})
The Vue Plugin detects any texture props containing the path to an image and replaces it with a reference to a texture object:
<sprite texture="@/assets/myTexture.png" />
- Container
- Sprite
- Graphics
- Text
- BitmapText
- AnimatedSprite
- SimpleMesh
- SimplePlane
- TilingSprite
- NineSlicePlane
- SimpleRope
- Mesh
Most props will work just as the properties on the corresponding PixiJS objects. in addition, They can also be used with X/Y suffix
<container :scale-x="10" :skew-y="0.5" />
All events emitted by pixi objects are supported. Some of vue's event modifiers will work, like @click.left
.
adding an event listener to an element will currently automatically set the element's
eventMode
tostatic
.
When using <grahpics />
there is a special @draw
event.
This will set up a watchEffect
internally that will automatically call the event handler again if any dependencies on the draw method have changed.
<script setup lang="ts">
import { Graphics } from "pixi.js";
const props = defineProps<{
x: number
y: number
width: number
height: number
}>()
function draw(g: Graphics) {
g.clear()
g.lineStyle(3, 0xffffff)
const { x, y, width, height } = props
g.drawRoundedRect(x, y, width, height, 5)
}
</script>
<template>
<graphics @draw="draw" />
</template>
To use filter
, you need to place the Filter tag under the <Container>
that sets the filter. Currently, the following filters are supported by default:
Example of using BlurFilter
with a Container:
<script setup>
const showBlur = ref(true)
</script>
<container>
<blur-filter :quality="3" :blur="5" v-if="showBlur" />
</container>
To use other filters, you can use the is attribute of <Filter>
. For example, to use the ShockwaveFilter
in pixi-filters:
<script setup>
import { ShockwaveFilter } from 'pixi-filters'
function renderShockwaveFilter(props: any) {
return new ShockwaveFilter(
props.center,
{
radius: props.radius,wavelength: props.wavelength,
amplitude: props.amplitude, speed: props.speed,
},
props.time,
)
}
const time = ref(0)
const center = ref([20, 30])
</script>
<sprite texture="@/assets/background.png">
<filter :is="renderShockwaveFilter" :center="center" :time="time" />
</sprite>
To avoid conflicts with other tags, such as <filter>
, you can use the pixi-
prefix or capitalize the first letter with <Filter>
.
<Filter /> <!-- or --> <pixi-filter />
Other components also support the
pixi-
prefix, so you can choose according to you personal preference.
vue3-pixi
provides a special component for bundling resources and obtaining resources from plugins.
<script setup lang="ts">
import { Assets, AssetsResolvers } from "vue3-pixi";
const resolves: AssetsResolvers = {
flowerTop: import('./examples/assets/flowerTop.png'),
eggHead: import('./examples/assets/eggHead.png'),
bunny: 'https://pixijs.io/examples/examples/assets/bunny.png'
}
</script>
<template>
<Assets :resolves="resolves" #default="{ textures, progress }">
<container v-if="textures">
<sprite :texture="textures.flowerTop" />
</container>
<text v-else>
Loading...
</text>
</Assets>
</template>
You can also use the resolved
and fallback
slots separately to handle successful and loaded content independently:
<Assets :resolves="resolves">
<template #resolved="{ textures }"><!-- ... --></template>
<template #fallback="{ progress }"><!-- ... --></template>
</Assets>
vue3-pixi
provides a set of composable hooks for operating a Pixi application.
This composable hook adds a ticker to the Pixi application during mounting and returns a stop function.
<script setup lang="ts">
import { StageInst, Stage, tryMountTicker } from "vue3-pixi";
tryMountTicker((delta) => {
// ...
})
</script>
<template>
<Stage :width="640" :height="480">
<!-- ... -->
</Stage>
</template>
This composable hook is used to obtain the current Pixi application instance.
<script setup lang="ts">
import { StageInst, Stage, useApplication } from "vue3-pixi";
import { onMounted } from 'vue'
const pixiApp = useApplication()
onMounted(() => {
pixiApp.value.ticker // { ... }
})
</script>
<template>
<Stage :width="640" :height="480">
<!-- ... -->
</Stage>
</template>
You can pass a ref
to specify a PIXI application. By default, it will automatically look for the nearest PIXI application in the current hierarchy.
<script setup lang="ts">
const stageRef = ref()
const pixiApp = useApplication(stageRef)
</script>
<template>
<Stage ref="stageRef" :width="640" :height="480">
<!-- ... -->
</Stage>
</template>
obtain responsive screen
information of pixiApp.screen
<script setup lang="ts">
const screen = useScreen()
</script>
<template>
<sprite :x="screen.width / 2" :texture="textures.flowerTop" />
</template>
Using the custom renderer inside vue3-pixi
import { appInjectKey, createApp } from 'vue3-pixi'
import { Application } from 'pixi.js'
import App from './App.vue'
const pixiApp = new Application({
resizeTo: window,
antialias: true,
})
document.body.appendChild(pixiApp.view as HTMLCanvasElement)
const app = createApp(App)
app.provide(appInjectKey, pixiApp)
app.mount(pixiApp.stage)