WIP: zoom
This commit is contained in:
parent
664e228e81
commit
42428e3643
215
index.html
215
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 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="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>
|
||||
<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>
|
94
index.js
94
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,
|
||||
@ -403,3 +367,55 @@ document.querySelectorAll('.clear-firing-arcs').forEach(el =>
|
||||
.forEach(el => el.remove())
|
||||
)
|
||||
);
|
||||
|
||||
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 });
|
19
style.css
19
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;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user