Pixi.js Viewport 예제코드
20 Apr 2022 | javascript html5Pixi.js Viewport 예제코드
PixiView.vue
<template> <div id="container"> <canvas id="pixi-canvas"></canvas> </div> </template> <script> import "./js/pixi-app"; import { PixiApp } from "./js/pixi-app"; export default { mounted() { this.createPixiApp(); }, methods: { createPixiApp() { const app = new PixiApp(800, 600); const canvas = document.getElementById("pixi-canvas"); canvas.appendChild(app.view); console.log(`window size(${window.innerWidth}, ${window.innerHeight})`); console.log(`app size(${app.view.width}, ${app.view.height})`); }, }, }; </script> <style> #container { display: block; width: 100vw; height: 100vh; background: whitesmoke; } #pixi-canvas { display: block; margin: 5%; } </style>
js/pixi-app.js
import * as PIXI from "pixi.js-legacy"; import { Viewport } from "pixi-viewport"; class PixiApp extends PIXI.Application { constructor(width, height) { super({ width: width, height: height, backgroundColor: 0xffebee, antialias: true, }); const screenWidth = 800; const screenHeight = 600; const worldWidth = screenWidth * 2; const worldHeight = screenHeight * 2; const viewport = new Viewport({ screenWidth: screenWidth, screenHeight: screenHeight, worldWidth: worldWidth, worldHeight: worldHeight, interaction: this.renderer.plugins.interaction, }); this.stage.addChild(viewport); const grid = this.#createGrid(); viewport.addChild(grid); const boundary = this.#createBoundary(worldWidth, worldHeight); viewport.addChild(boundary); this.#registerViewportEventHandler(viewport); console.log(viewport); console.log(`Screen width: ${viewport.screenWidth}`); console.log(`World width: ${viewport.worldWidth}`); // World height, in pixels console.log( `Screen width in World pixels width(${viewport.screenWidthInWorldPixels})` ); // Get how many world pixels fit in screen's width console.log(`Screen World width(${viewport.screenWorldWidth})`); // World width in screen coordinates console.log(`World Screen width(${viewport.worldScreenWidth})`); // Screen width in world coordinates console.log(`Viewport Corner`, viewport.corner); // Screen width in world coordinates console.log(`Viewport Center`, viewport.center); // Screen width in world coordinates } #registerViewportEventHandler(viewport) { const screenWidth = 800; const screenHeight = 600; viewport .drag() .pinch() .wheel() .decelerate() .clamp({ direction: "all", underflow: "center", }) .clampZoom({ minWidth: screenWidth, minHeight: screenHeight, maxWidth: screenWidth * 3, maxHeight: screenHeight * 3, }) .clampZoom({ minScale: 0.5, maxScale: 2, }) .fit(); viewport.on("pointerup", (e) => { const x = e.data.global.x; const y = e.data.global.y; console.log(`point UP (${x}, ${y})`); // Viewport 좌표 console.log(`toScreen: `, viewport.toScreen(x, y)); console.log(`toWorld: `, viewport.toWorld(x, y)); console.log(`visibleBounds()`, viewport.getVisibleBounds()); }); } #createBoundary(width, height) { const container = new PIXI.Container(); const boundary = new PIXI.Graphics(); boundary.lineStyle(8, 0xff0000); boundary.drawRect(0, 0, width, height); container.addChild(boundary); return container; } #createGrid() { const container = new PIXI.Container(); const origin = this.#createCrossPoint({ x: 0, y: 0, color: 0xff0000, size: 50, fontsize: 14, }); container.addChild(origin); for (let row = 0; row <= 20; row++) { for (let col = 0; col <= 20; col++) { if (row == 0 && col == 0) continue; const p = this.#createCrossPoint({ x: col * 100, y: row * 100, }); container.addChild(p); } } return container; } #createCrossPoint({ x, y, color = 0x000000, size = 5, thickness = 1, fontsize = 8, }) { const container = new PIXI.Container(); const grid = new PIXI.Graphics(); grid.lineStyle(thickness, color); grid.moveTo(x - size, y); grid.lineTo(x + size, y); grid.moveTo(x, y - size); grid.lineTo(x, y + size); container.addChild(grid); const text = new PIXI.Text(`(${x},${y})`, { fontFamily: "Arial", fontSize: fontsize, fill: color, }); text.position.set(x + 3, y + 3); container.addChild(text); return container; } } export { PixiApp };
실행화면
화면의 각 위치를 터치해보고, 화면을 panning으로 이동 후 각 위치를 터치, Zoom 등으로 화면을 확대/축소하면서 각 위치를 터치하면서 좌표계를 확인해볼 수 있습니다.
각 이벤트를 거쳐 전달되는 좌표값은 Viewport 상의 좌표이며, 이를 World 좌표로 변환하면 각 오브젝트가 그려진 Canvas 상의 좌표라고 볼 수 있습니다.