Web Dev Solutions

Catalin Mititiuc

aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCatalin Mititiuc <Catalin.Mititiuc@gmail.com>2024-03-26 11:45:37 -0700
committerCatalin Mititiuc <Catalin.Mititiuc@gmail.com>2024-03-26 11:45:37 -0700
commit42428e3643e0a2ebbff766b8c823ef423d5386ee (patch)
tree73985b323f443b616952e90f36a242e717cca59b
parent664e228e81331abbce32924a7046b9ae1497ec7a (diff)
WIP: zoom
-rw-r--r--index.html215
-rw-r--r--index.js96
-rw-r--r--style.css19
3 files changed, 213 insertions, 117 deletions
diff --git a/index.html b/index.html
index db842b4..0e68a73 100644
--- a/index.html
+++ b/index.html
@@ -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
diff --git a/index.js b/index.js
index 93072c8..dfab442 100644
--- a/index.js
+++ b/index.js
@@ -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
diff --git a/style.css b/style.css
index e91931d..25b4a91 100644
--- a/style.css
+++ b/style.css
@@ -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