116 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
			
		
		
	
	
			116 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			HTML
		
	
	
	
	
	
<!DOCTYPE html>
 | 
						|
<html lang="en">
 | 
						|
    <head>
 | 
						|
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 | 
						|
        <title>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>
 | 
						|
            function drawPolygons() {
 | 
						|
                canvas.width = main.getBoundingClientRect().width
 | 
						|
                let context = canvas.getContext('2d')
 | 
						|
                context.clearRect(0, 0, canvas.width, canvas.height)
 | 
						|
 | 
						|
                let stage = scatterContainer.polygon
 | 
						|
                stage.draw(context, { stroke: '#FF0000' })
 | 
						|
                for (let scatter of scatterContainer.scatter.values()) {
 | 
						|
                    let polygon = scatter.polygon
 | 
						|
                    polygon.draw(context, { stroke: '#FF0000' })
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            function animate(callback) {
 | 
						|
                requestAnimationFrame((dt) => {
 | 
						|
                    drawPolygons()
 | 
						|
                    callback()
 | 
						|
                    animate(callback)
 | 
						|
                })
 | 
						|
            }
 | 
						|
        </script>
 | 
						|
    </head>
 | 
						|
 | 
						|
    <body onload="Doctest.run()">
 | 
						|
        <h1><a href="index.html">lib.</a>Coordinates</h1>
 | 
						|
        <p>
 | 
						|
            To position objects in defined spatial relationships presupposes a clear understanding of the involved
 | 
						|
            coordinate systems. Unfortunately, several systems with several conventions are involved:
 | 
						|
            <a href="https://javascript.info/coordinates">DOM & CSS</a>,
 | 
						|
            <a href="https://www.sarasoueidan.com/blog/svg-coordinate-systems/SVG">SVG</a>,
 | 
						|
            <a href="https://www.w3schools.com/graphics/canvas_coordinates.asp">Canvas</a>
 | 
						|
        </p>
 | 
						|
        <p>
 | 
						|
            We need a common reference system to switch between these coordinate systems. As the uttermost context, the
 | 
						|
            browser page coordinate system is the most natural one. A simple API was long missing but has now been
 | 
						|
            established in most modern browsers with
 | 
						|
            <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/convertPointFromNoteToPage"
 | 
						|
                >window.convertPointFromNoteToPage</a
 | 
						|
            >
 | 
						|
            and the inverse
 | 
						|
            <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/convertPointFromPageToNode"
 | 
						|
                >window.convertPointFromPageToNode</a
 | 
						|
            >. Although MDN Web Docs warns about their Non-standard nature the methods work in browsers targeted by the
 | 
						|
            IWM Browser project. This doctest assures that this assumption can be tested.
 | 
						|
        </p>
 | 
						|
        <p>
 | 
						|
            Let's look at a scatter object with a rotatable local coordinate system. We try to follow a point in this
 | 
						|
            local coordinate system by showing a marker outside the scatter that follows the point.
 | 
						|
        </p>
 | 
						|
        <div id="main" class="grayBorder interactive" style="position: relative; width: 100%; height: 280px">
 | 
						|
            <!-- Note that we need to set draggable to false to avoid conflicts. The DOM elements
 | 
						|
    must also be positioned absolutely. -->
 | 
						|
            <img id="women" draggable="false" style="position: absolute" src="examples/women.jpeg" />
 | 
						|
 | 
						|
            <canvas
 | 
						|
                id="canvas"
 | 
						|
                height="280"
 | 
						|
                style="z-index: 100000; pointer-events: none; position: absolute; border: 1px solid red"
 | 
						|
            >
 | 
						|
                Canvas not supported.
 | 
						|
            </canvas>
 | 
						|
        </div>
 | 
						|
 | 
						|
        <script class="doctest">
 | 
						|
            let dx = 44
 | 
						|
 | 
						|
            let app = new App()
 | 
						|
            let scatterContainer = new DOMScatterContainer(main)
 | 
						|
            let angle = 15
 | 
						|
            let image = document.getElementById('women')
 | 
						|
            // The DOMScatter needs initial width and height. Therefore we
 | 
						|
            // define the scatter when the image size is known, i.e. after loading...
 | 
						|
            image.onload = (e) => {
 | 
						|
                let scatter = new DOMScatter(image, scatterContainer, {
 | 
						|
                    x: dx,
 | 
						|
                    y: 44,
 | 
						|
                    width: e.target.naturalWidth,
 | 
						|
                    height: e.target.naturalHeight,
 | 
						|
                    rotationDegrees: angle,
 | 
						|
                    throwVisibility: 88,
 | 
						|
                    minScale: 0.5,
 | 
						|
                    maxScale: 1.5
 | 
						|
                })
 | 
						|
                dx += 300
 | 
						|
                angle = -angle
 | 
						|
            }
 | 
						|
 | 
						|
            app.run()
 | 
						|
 | 
						|
            function followPoint() {
 | 
						|
                let context = canvas.getContext('2d')
 | 
						|
                let localPoint = { x: 100, y: 100 }
 | 
						|
                let globalPoint = convertPointFromNodeToPage(image, localPoint.x, localPoint.y)
 | 
						|
                let canvasPoint = convertPointFromPageToNode(canvas, globalPoint.x, globalPoint.y)
 | 
						|
 | 
						|
                context.strokeStyle = 'red'
 | 
						|
                context.beginPath()
 | 
						|
                context.arc(canvasPoint.x, canvasPoint.y, 12, 0, Math.PI * 2)
 | 
						|
                context.stroke()
 | 
						|
            }
 | 
						|
            animate(followPoint)
 | 
						|
        </script>
 | 
						|
    </body>
 | 
						|
</html>
 |