iwmlib/lib/pixi/coordinates.html

128 lines
5.2 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>PIXI Coordinates Doctest</title>
<link rel="stylesheet" href=".././3rdparty/highlight/styles/default.css">
<link rel="stylesheet" href="../../css/doctest.css">
<script src=".././3rdparty/highlight/highlight.pack.js"></script>
<script src="../../dist/iwmlib.3rdparty.js"></script>
<script src="../../dist/iwmlib.js"></script>
<script src="../../dist/iwmlib.pixi.js"></script>
</head>
<body onload="Doctest.run()">
<h1>
Coordinates
</h1>
<p>
To position objects in defined spatial relationships presupposes a clear understanding of the involved coordinate systems.
For DOM related coordinate systems see the
<a href="../lib/coordinates.html">Doctest in lib/coordinates.html</a>.
</p>
<p>
Here we adress the relationship between the PIXI view hierarchy and the DOM hierarchy. As noted in the above mentioned Doctest
we choose the page, i.e. the uttermost context, as the common global reference system. To support this we use two
PIXIApp methods, since the PIXIApp connects the DOM canvas and the PIXI stage. The methods follow the same signature
as the corresponding window methods but use PIXI DisplayObjects as nodes instead of DOM elements:
<ul>
<li>
<pre>app.convertPointFromPageToNode(displayObject, x, y)</pre>
</li>
<li>
<pre>app.convertPointFromNodeToPage(displayObject, x, y)</pre>
</li>
</ul>
</p>
<p>The following example shows the relationship between a PIXI object in a scatter application and two DOM elements, a DIV
and a CANVAS on top of the PIXI canvas.
</p>
<p>
Note that the red square is a PIXI graphics object that follows the local point in the women's image in the app.stage. The
blue square is a DOM div positioned by CSS top, left whereas the red circle follows the point in a second DOM canvas
on top of the PIXI canvas. Since the PIXI App has it's own resolution dependent coordinates app.convertPointFromPageToNode and app.convertPointFromNodeToPage
must obey the render resolution. Feel free to test this example with different screen resolutions.
</p>
<div style="position: relative; height: 500px;">
<canvas id="pixiCanvas" class="grayBorder interactive" style="position: absolute;">Canvas not supported</canvas>
<canvas id="domCanvas" width="640" height="480" style="z-index: 100000; pointer-events: none; position: absolute; border: 1px solid red;">
Canvas not supported.
</canvas>
<div id="domMarker" style="position: absolute; background-color: blue; width: 12px; height: 12px;"></div>
</div>
<script class="doctest">
class ScatterApp extends PIXIApp {
sceneFactory() {
return new ScatterContainer(this.renderer, { showBounds: true, showPolygon: true, app: this })
}
setup() {
super.setup()
let x = 30
let y = 30
let sprite = PIXI.Sprite.from('../examples/women.jpeg')
sprite.interactive = true
let scatter = new DisplayObjectScatter(sprite, this.renderer,
{
x: x, y: y,
startScale: 0.25,
minScale: 0.2,
maxScale: 1
})
this.scene.addChild(sprite)
scatter.zoom(0.5, { animate: 1.0 })
this.women = sprite
let graphics = this.marker = new PIXI.Graphics()
graphics.beginFill(0xFF0000)
graphics.drawRect(-3, -3, 6, 6)
graphics.endFill()
this.stage.addChild(graphics)
return this
}
followPoint() {
let context = domCanvas.getContext('2d')
let localPoint = { x: 100, y: 100 }
let globalPoint = this.convertPointFromNodeToPage(this.women, localPoint.x, localPoint.y)
let canvasPoint = convertPointFromPageToNode(domCanvas, globalPoint.x, globalPoint.y)
let pixiPoint = this.convertPointFromPageToNode(this.stage, globalPoint.x, globalPoint.y)
domMarker.style.left = canvasPoint.x + 'px'
domMarker.style.top = canvasPoint.y + 'px'
this.marker.position = pixiPoint
context.clearRect(0, 0, 640, 480)
context.strokeStyle = 'red'
context.beginPath()
context.arc(canvasPoint.x, canvasPoint.y, 12, 0, Math.PI * 2)
context.stroke()
requestAnimationFrame((dt) => {
this.followPoint()
})
}
run() {
this.followPoint()
return this
}
}
const app = new ScatterApp({
view: pixiCanvas,
autoResize: false,
width: 640 / window.devicePixelRatio,
height: 480 / window.devicePixelRatio
})
app.setup()
app.run()
</script>
</body>