index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | index.html | 89 | ||||
-rw-r--r-- | index.js | 40 | ||||
-rw-r--r-- | style.css | 28 |
3 files changed, 81 insertions, 76 deletions
@@ -101,45 +101,6 @@ </p> </template> - <div id="debug"> - <fieldset name="point"> - <legend>hex</legend> - <div> - <label>translatex <input name="translateX" type="number" value="0" /></label> - <label>translatey <input name="translateY" type="number" value="0" /></label> - <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> - <label>scale <input name="scale" type="number" step="0.1" value="1" /></label> - </div> - </fieldset> - <fieldset name="points"> - <legend>grid</legend> - <div> - <label>translatex <input name="translateX" type="number" value="0" /></label> - <label>translatey <input name="translateY" type="number" value="0" /></label> - <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> - <label>scale <input name="scale" type="number" step="0.1" value="1" /></label> - </div> - </fieldset> - <fieldset name="map2"> - <legend>map2</legend> - <div> - <label>translatex <input name="translateX" type="number" value="0" /></label> - <label>translatey <input name="translateY" type="number" value="0" /></label> - <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> - <label>scale <input name="scale" type="number" step="0.1" value="1" /></label> - </div> - </fieldset> - <fieldset name="map3"> - <legend>map3</legend> - <div> - <label>translatex <input name="translateX" type="number" value="0" /></label> - <label>translatey <input name="translateY" type="number" value="0" /></label> - <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> - <label>scale <input name="scale" type="number" step="0.1" value="1" /></label> - </div> - </fieldset> - </div> - <div id="map-container"> <div id="toggle-firing-arc-vis"> <div>davion</div> @@ -147,6 +108,50 @@ <div>liao</div> <input type="checkbox" data-allegiance="liao" /> </div> + + <div id="panel"> + <fieldset name="point"> + <legend>hex</legend> + <div> + <label>translateX <input name="translateX" type="number" step="0.1" value="0" /></label> + <label>translateY <input name="translateY" type="number" step="0.1" value="0" /></label> + <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> + <label>scaleX <input name="scaleX" type="number" step="0.1" value="1" /></label> + <label>scaleY <input name="scaleY" type="number" step="0.1" value="1" /></label> + </div> + </fieldset> + <fieldset name="points"> + <legend>grid</legend> + <div> + <label>translateX <input name="translateX" type="number" step="0.1" value="0" /></label> + <label>translateY <input name="translateY" type="number" step="0.1" value="0" /></label> + <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> + <label>scaleX <input name="scaleX" type="number" step="0.1" value="1" /></label> + <label>scaleY <input name="scaleY" type="number" step="0.1" value="1" /></label> + </div> + </fieldset> + <fieldset name="map2"> + <legend>map2</legend> + <div> + <label>translateX <input name="translateX" type="number" step="0.1" value="0" /></label> + <label>translateY <input name="translateY" type="number" step="0.1" value="0" /></label> + <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> + <label>scaleX <input name="scaleX" type="number" step="0.001" value="1" /></label> + <label>scaleY <input name="scaleY" type="number" step="0.001" value="1" /></label> + </div> + </fieldset> + <fieldset name="map3"> + <legend>map3</legend> + <div> + <label>translateX <input name="translateX" type="number" step="0.1" value="0" /></label> + <label>translateY <input name="translateY" type="number" step="0.1" value="0" /></label> + <label>rotate <input name="rotate" type="number" step="0.1" value="0" /></label> + <label>scaleX <input name="scaleX" type="number" step="0.001" value="1" /></label> + <label>scaleY <input name="scaleY" type="number" step="0.001" value="1" /></label> + </div> + </fieldset> + </div> + <svg viewbox="-49 -40 2390 3163" xmlns="http://www.w3.org/2000/svg"> <defs> <polygon id="point" points="0,10 8.66,5 8.66,-5 0,-10 -8.66,-5 -8.66,5" /> @@ -197,8 +202,8 @@ <rect id="background" x="-1" y="-1" width="2287" height="3087" /> <g id="image-maps"> - <image id="map2" class="map-scans" href="scans/map2.jpg" width="2284" height="1518" x="2" y="2" /> - <image id="map3" class="map-scans" href="scans/map3.jpg" width="2284" height="1518" x="4" y="1564" /> + <image id="map2" class="map-scans" href="scans/map2.jpg" width="2284" height="1518" /> + <image id="map3" class="map-scans" href="scans/map3.jpg" width="2284" height="1518" /> </g> <g id="firing-arcs"> @@ -217,8 +222,6 @@ <use href="#n2" x="19" y="-40" opacity="0.5" /> <use href="#n3" x="36" y="-40" opacity="0.5" /> <use href="#n4" x="54" y="-40" opacity="0.5" /> - - <!-- <rect id="debug-view-box" x="-100" y="-100" width="3400" height="4500" /> --> </svg> <div id="status"> @@ -294,10 +294,11 @@ if (recVis == 'false') { let info = document.getElementById('status'); -// Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => { -[].forEach(fieldset => { +Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => { +// [].forEach(fieldset => { + const identityMtx = [1, 0, 0, 1, 0, 0]; const target = document.getElementById(fieldset.name); - const transform = getComputedStyle(target).transform.match(/-?\d+\.?\d*/g); + const transform = getComputedStyle(target).transform.match(/-?\d+\.?\d*/g) || identityMtx; const inputs = fieldset.querySelectorAll('input'); if (transform) { @@ -310,7 +311,8 @@ let info = document.getElementById('status'); const scaleY = Math.sqrt(b**2 + d**2); let values = { - scale: Math.round(scaleX * 10) / 10, + scaleX: Math.round(scaleX * 1000) / 1000, + scaleY: Math.round(scaleY * 1000) / 1000, translateX: e, translateY: f, rotate: Math.round(radToDeg((Math.acos(a / scaleX) + Math.asin(b / scaleY)) / 2) * 10) / 10 @@ -323,12 +325,13 @@ let info = document.getElementById('status'); input.addEventListener('pointerenter', e => e.target.focus()); input.addEventListener('input', e => { - let { scale, translateX, translateY, rotate} = Object.values(inputs).reduce((acc, input) => { - acc[input.name] = input.value; - return acc; - }, {}); + let { translateX, translateY, rotate, scaleX, scaleY } = + Object.values(inputs).reduce((acc, input) => { + acc[input.name] = input.value; + return acc; + }, {}); - let transform = `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) scale(${scale})`; + let transform = `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) scale(${scaleX}, ${scaleY})`; target.style.transform = transform; }); @@ -888,11 +891,14 @@ svg.addEventListener('wheel', e => { let vb = `${newX} ${newY} ${newWidth} ${newHeight}` + // TODO attribute change event? localStorage.setItem('viewBox', vb); svg.setAttributeNS(null, 'viewBox', vb); }); svg.addEventListener('pointerdown', e => { + e.preventDefault(); + const minPanDistanceThreshold = 5; let dist, ctm, @@ -904,16 +910,19 @@ svg.addEventListener('pointerdown', e => { function pointerMove(e) { movePt.x = e.clientX; movePt.y = e.clientY; - dist = Math.sqrt((movePt.x - startPt.x)**2 + (movePt.y - startPt.y)**2); - if (!pan && dist >= minPanDistanceThreshold) { - pan = true; - startPt.x = e.clientX; - startPt.y = e.clientY; + if (!pan) { + dist = Math.sqrt((movePt.x - startPt.x)**2 + (movePt.y - startPt.y)**2); + + if (dist >= minPanDistanceThreshold) { + pan = true; + svg.setPointerCapture(e.pointerId); + startPt.x = e.clientX; + startPt.y = e.clientY; + } } if (pan) { - svg.setPointerCapture(e.pointerId); ctm = svg.getScreenCTM().inverse(); const [svgStartPt, svgMovePt] = [startPt, movePt].map(p => p.matrixTransform(ctm)), @@ -928,7 +937,6 @@ svg.addEventListener('pointerdown', e => { } function pointerUp(e) { - svg.releasePointerCapture(e.pointerId); svg.removeEventListener('pointermove', pointerMove); svg.removeEventListener('pointerup', pointerUp); } @@ -24,6 +24,10 @@ svg image.map-scans { image-rendering: auto; } +svg text { + user-select: none; +} + div#status { position: absolute; bottom: 0; @@ -159,19 +163,17 @@ g#grid { } #map2 { - transform: rotate(0.1deg); + transform-origin: 0px 0px; + transform: translate(-0.9px, -2.4px) scale(0.999, 1.007); } #map3 { - transform: rotate(0.1deg); -} - -image.map-scans { - /* transform: scale(1.39, 1.407) rotate(0.07deg); */ - /* opacity: 0.33; */ + transform-origin: 0px 0px; + /* transform: translateY(1518px); */ + transform: translate(1.3px, 1564.1px) rotate(0.1deg) scale(0.999, 1.002); } -#debug { +#panel { display: none; position: absolute; right: 0; @@ -180,7 +182,7 @@ image.map-scans { padding: 2px; } -#debug fieldset label { +#panel fieldset label { display: block; text-align: right; } @@ -259,14 +261,6 @@ text.counter, #troop-counter text { user-select: none; } -rect#map { - fill: black; - opacity: 0; - /* fill-opacity: 0; - stroke: red; - stroke-width: 4px; */ -} - polygon.firing-arc[data-troop-allegiance="davion"] { fill: red; } |