index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
author | Catalin Mititiuc <Catalin.Mititiuc@gmail.com> | 2024-03-26 11:45:37 -0700 |
---|---|---|
committer | Catalin Mititiuc <Catalin.Mititiuc@gmail.com> | 2024-03-26 11:45:37 -0700 |
commit | 42428e3643e0a2ebbff766b8c823ef423d5386ee (patch) | |
tree | 73985b323f443b616952e90f36a242e717cca59b | |
parent | 664e228e81331abbce32924a7046b9ae1497ec7a (diff) |
WIP: zoom
-rw-r--r-- | index.html | 215 | ||||
-rw-r--r-- | index.js | 96 | ||||
-rw-r--r-- | style.css | 19 |
3 files changed, 213 insertions, 117 deletions
@@ -101,6 +101,10 @@ </p> </template> + <div> + debug margin + </div> + <svg viewbox="-100 -100 3450 2400" xmlns="http://www.w3.org/2000/svg"> <defs> <pattern id="inch-mark" x="0" y="0" width="2in" height="2in" patternUnits="userSpaceOnUse"> @@ -127,90 +131,151 @@ <image id="img2" href="scans/map1.jpg" width="2284" height="1518" /> <g id="firing-arcs"></g> <rect id="map" x="0" y="0" width="34in" height="23in" /> + <rect id="view-box" x="-100" y="-100" width="3450" height="2400" /> + <!-- <rect id="view-box" x1="-100" y1="-100" x2="3450" y2="2400" /> --> </svg> - <div> - Set firing arc: - <button type="button" class="set-firing-arc" data-size="small"> - <img src="firing_arc_small.png" height="12" /> 2 MP - </button> - <button type="button" class="set-firing-arc" data-size="medium"> - <img src="firing_arc_medium.png" height="12" /> 4 MP - </button> - <button type="button" class="set-firing-arc" data-size="large"> - <img src="firing_arc_large.png" height="12" /> 6 MP - </button> - </div> - - <div id="record-sheet"> + <div id="content"> <div> - <!-- <img class="logo" src="logo-davion.png" /> --> - <p> - Davion - <button type="button" class="clear-firing-arcs" data-allegiance="davion"> - Clear Firing Arcs - </button> - <br> - <!-- 1st Squad, 3rd Platoon, Bravo Company, 2nd Battalion<br> - 17th Kestral Mechanized Infantry --> - </p> - <div is="soldier-record-block" class="soldier-record" data-troop-number="1" data-troop-allegiance="davion"> - <span slot="troop-number">1</span> - <span slot="primary-weapon-type">Rifle</span> - <span slot="primary-weapon-damage">4L</span> - <span slot="primary-weapon-range-short">1-27</span> - <span slot="primary-weapon-range-long">28-75</span> - </div> - <div is="soldier-record-block" class="soldier-record" data-troop-number="2" data-troop-allegiance="davion"> - <span slot="troop-number">2</span> - <span slot="primary-weapon-type">SMG</span> - <span slot="primary-weapon-damage">3L</span> - <span slot="primary-weapon-range-short">1-15</span> - <span slot="primary-weapon-range-long">16-25</span> - </div> - <div is="soldier-record-block" class="soldier-record" data-troop-number="3" data-troop-allegiance="davion"> - <span slot="troop-number">3</span> - <span slot="primary-weapon-type">Blazer</span> - <span slot="primary-weapon-damage">4L</span> - <span slot="primary-weapon-range-short">1-17</span> - <span slot="primary-weapon-range-long">18-105</span> - </div> + Set firing arc: + <button type="button" class="set-firing-arc" data-size="small"> + <img src="firing_arc_small.png" height="12" /> 2 MP + </button> + <button type="button" class="set-firing-arc" data-size="medium"> + <img src="firing_arc_medium.png" height="12" /> 4 MP + </button> + <button type="button" class="set-firing-arc" data-size="large"> + <img src="firing_arc_large.png" height="12" /> 6 MP + </button> </div> - <div> - <!-- <img class="logo" src="logo-liao.png" /> --> - <p> - Liao - <button type="button" class="clear-firing-arcs" data-allegiance="liao"> - Clear Firing Arcs - </button> - <br> - <!-- 2nd Squad, 1st Platoon, 3rd Company, 2nd Battalion<br> - Aldebaran Home Guard --> - </p> - <div is="soldier-record-block" class="soldier-record" data-troop-number="1" data-troop-allegiance="liao"> - <span slot="troop-number">1</span> - <span slot="primary-weapon-type">Rifle</span> - <span slot="primary-weapon-damage">4L</span> - <span slot="primary-weapon-range-short">1-27</span> - <span slot="primary-weapon-range-long">28-75</span> - </div> - <div is="soldier-record-block" class="soldier-record" data-troop-number="2" data-troop-allegiance="liao"> - <span slot="troop-number">2</span> - <span slot="primary-weapon-type">SMG</span> - <span slot="primary-weapon-damage">3L</span> - <span slot="primary-weapon-range-short">1-15</span> - <span slot="primary-weapon-range-long">16-25</span> + + <div id="record-sheet"> + <div> + <!-- <img class="logo" src="logo-davion.png" /> --> + <p> + Davion + <button type="button" class="clear-firing-arcs" data-allegiance="davion"> + Clear Firing Arcs + </button> + <br> + <!-- 1st Squad, 3rd Platoon, Bravo Company, 2nd Battalion<br> + 17th Kestral Mechanized Infantry --> + </p> + <div is="soldier-record-block" class="soldier-record" data-troop-number="1" data-troop-allegiance="davion"> + <span slot="troop-number">1</span> + <span slot="primary-weapon-type">Rifle</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-27</span> + <span slot="primary-weapon-range-long">28-75</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="2" data-troop-allegiance="davion"> + <span slot="troop-number">2</span> + <span slot="primary-weapon-type">Rifle</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-27</span> + <span slot="primary-weapon-range-long">28-75</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="3" data-troop-allegiance="davion"> + <span slot="troop-number">3</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="4" data-troop-allegiance="davion"> + <span slot="troop-number">4</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="5" data-troop-allegiance="davion"> + <span slot="troop-number">5</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="6" data-troop-allegiance="davion"> + <span slot="troop-number">6</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="7" data-troop-allegiance="davion"> + <span slot="troop-number">7</span> + <span slot="primary-weapon-type">Blazer</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-17</span> + <span slot="primary-weapon-range-long">18-105</span> + </div> </div> - <div is="soldier-record-block" class="soldier-record" data-troop-number="3" data-troop-allegiance="liao"> - <span slot="troop-number">3</span> - <span slot="primary-weapon-type">Blazer</span> - <span slot="primary-weapon-damage">4L</span> - <span slot="primary-weapon-range-short">1-17</span> - <span slot="primary-weapon-range-long">18-105</span> + <div> + <!-- <img class="logo" src="logo-liao.png" /> --> + <p> + Liao + <button type="button" class="clear-firing-arcs" data-allegiance="liao"> + Clear Firing Arcs + </button> + <br> + <!-- 2nd Squad, 1st Platoon, 3rd Company, 2nd Battalion<br> + Aldebaran Home Guard --> + </p> + <div is="soldier-record-block" class="soldier-record" data-troop-number="1" data-troop-allegiance="liao"> + <span slot="troop-number">1</span> + <span slot="primary-weapon-type">Rifle</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-27</span> + <span slot="primary-weapon-range-long">28-75</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="2" data-troop-allegiance="liao"> + <span slot="troop-number">2</span> + <span slot="primary-weapon-type">Rifle</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-27</span> + <span slot="primary-weapon-range-long">28-75</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="3" data-troop-allegiance="liao"> + <span slot="troop-number">3</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="4" data-troop-allegiance="liao"> + <span slot="troop-number">4</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="5" data-troop-allegiance="liao"> + <span slot="troop-number">5</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="6" data-troop-allegiance="liao"> + <span slot="troop-number">6</span> + <span slot="primary-weapon-type">SMG</span> + <span slot="primary-weapon-damage">3L</span> + <span slot="primary-weapon-range-short">1-15</span> + <span slot="primary-weapon-range-long">16-25</span> + </div> + <div is="soldier-record-block" class="soldier-record" data-troop-number="7" data-troop-allegiance="liao"> + <span slot="troop-number">7</span> + <span slot="primary-weapon-type">Blazer</span> + <span slot="primary-weapon-damage">4L</span> + <span slot="primary-weapon-range-short">1-17</span> + <span slot="primary-weapon-range-long">18-105</span> + </div> </div> </div> </div> + <script src="soldier_record_block.js"></script> <script src="index.js"></script> </body> </html>
\ No newline at end of file @@ -1,42 +1,3 @@ -class SoldierRecordBlock extends HTMLDivElement { - constructor() { - super(); - - let template = document.getElementById('soldier-record-block'); - let templateContent = template.content; - - const shadowRoot = this.attachShadow({ mode: "open" }); - shadowRoot.appendChild(templateContent.cloneNode(true)); - - this.shadowRoot - .querySelectorAll('p:has(input[type="number"]), .physical-status-track') - .forEach(el => el.addEventListener('click', e => e.stopPropagation())) - ; - } -} - -customElements.define( - 'damage-block', - class extends HTMLSpanElement { - constructor() { - super(); - - let template = document.getElementById('damage-block'); - let templateContent = template.content; - - const shadowRoot = this.attachShadow({ mode: "open" }); - shadowRoot.appendChild(templateContent.cloneNode(true)); - } - }, - { extends: 'span' } -); - -customElements.define( - 'soldier-record-block', - SoldierRecordBlock, - { extends: 'div'} -); - function isEven(n) { return n % 2 === 0; } @@ -106,6 +67,9 @@ let svgns = "http://www.w3.org/2000/svg", svg = document.querySelector('svg'), map = document.querySelector('rect#map'); +const { x: VIEWBOX_X, y: VIEWBOX_Y, width: VIEWBOX_WIDTH, height: VIEWBOX_HEIGHT } = + svg.viewBox.baseVal; + const COLUMN_COUNT = 33, ROW_COUNT = 25, HORZ_POINT_DISTANCE = 1.005, @@ -402,4 +366,56 @@ document.querySelectorAll('.clear-firing-arcs').forEach(el => .querySelectorAll(`.firing-arc[data-troop-allegiance="${allegiance}"]`) .forEach(el => el.remove()) ) -);
\ No newline at end of file +); + +svg.addEventListener('wheel', e => { + e.preventDefault(); + + // let el = document.querySelector('svg'); + let el = document.getElementById('view-box'); + + let boundingRect = el.getBoundingClientRect(); + let pointerX = e.clientX - boundingRect.left; + let pointerY = e.clientY - boundingRect.top; + + // let { x, y, width, height } = el.viewBox.baseVal; + let { x, y, width, height } = el; + [x, y, width, height] = [x, y, width, height].map(el => el.baseVal.value); + + console.log( + 'horz pointer ratio, vert pointer ratio', + pointerX / boundingRect.width, pointerY / boundingRect.height + ); + + let widthDelta = width * 0.1; + let heightDelta = height * 0.1; + + let xChange = pointerX / boundingRect.width * widthDelta; + let widthChange = (1 - (pointerX / boundingRect.width)) * widthDelta; + + let yChange = pointerY / boundingRect.height * heightDelta; + let heightChange = (1 - (pointerY / boundingRect.height)) * heightDelta; + + console.log('widthDelta', 'heightDelta', widthDelta, heightDelta); + console.log('x change', xChange); + console.log('width change', widthChange); + + // console.log('viewbox new ratio', (width * 0.98) / (height * 0.98)); + + // let vb = `${x} ${y} ${parseInt(width * 0.98)} ${parseInt(height * 0.98)}`; + + // el.setAttributeNS(null, 'viewBox', vb) + + let newX = e.deltaY < 0 ? x + xChange : x - xChange; + let newWidth = e.deltaY < 0 ? width - xChange - widthChange : width + xChange + widthChange; + + let newY = e.deltaY < 0 ? y + yChange : y - yChange; + let newHeight = e.deltaY < 0 ? height - yChange - heightChange : height + yChange + heightChange; + + el.setAttributeNS(null, 'x', newX < VIEWBOX_X ? VIEWBOX_X : newX); + el.setAttributeNS(null, 'width', newWidth > VIEWBOX_WIDTH ? VIEWBOX_WIDTH : newWidth); + + el.setAttributeNS(null, 'y', newY < VIEWBOX_Y ? VIEWBOX_Y : newY); + el.setAttributeNS(null, 'height', newHeight > VIEWBOX_HEIGHT ? VIEWBOX_HEIGHT : newHeight); + +}, { passive: false });
\ No newline at end of file @@ -1,9 +1,15 @@ svg { background-color: darkgray; + flex-basis: 100%; +} + +div#content { + flex-basis: 0; } body { margin: 0; + display: flex; } circle#point { @@ -78,6 +84,7 @@ line.ruler { .soldier-record { display: inline-block; + white-space: nowrap; } image#img1 { @@ -109,7 +116,8 @@ image#img2 { } #record-sheet { - display: flex; + /* display: flex; */ + display: none; } #record-sheet > div { @@ -129,5 +137,12 @@ img.logo { } div.soldier-record.selected { - background-color: goldenrod; + background-color: lightgray; +} + +rect#view-box { + stroke: red; + stroke-width: 20px; + fill: blue; + fill-opacity: 0.2; }
\ No newline at end of file |