index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/modules')
-rw-r--r-- | src/modules/game/firingArc.js | 59 |
1 files changed, 18 insertions, 41 deletions
diff --git a/src/modules/game/firingArc.js b/src/modules/game/firingArc.js index fb39aba..e37d2a8 100644 --- a/src/modules/game/firingArc.js +++ b/src/modules/game/firingArc.js @@ -38,7 +38,7 @@ function calculateAngle(xDiff, yDiff) { return angle; } -function edgePoint(x1, y1, x2, y2, maxX, maxY, minX = 0, minY = 0) { +function edgePoint([x1, y1], [x2, y2], { minX = 0, minY = 0, maxX, maxY } = {}) { const xDiff = x2 - x1, yDiff = y2 - y1, xIntercept = y => (y - y1) * xDiff / yDiff + x1, @@ -67,40 +67,19 @@ function edgePoint(x1, y1, x2, y2, maxX, maxY, minX = 0, minY = 0) { return pointCoords; } -let cornerPoints; - -function position(e) { +function position(activeFiringArc, activeFiringArcOutline, aim, grid, e) { // TODO: handle exactly horizontal and vertical lines? - let arcLayer = this.querySelector('#shapes'); - const activeFiringArc = arcLayer.querySelector('polygon.firing-arc.active'); - - if (!activeFiringArc) { - return; - } - - let outlineLayer = this.querySelector('#lines'); - - const { dataset: { allegiance, number }} = activeFiringArc, - outlineSelector = `polyline[data-number="${number}"][data-allegiance="${allegiance}"]`, - activeFiringArcOutline = outlineLayer.querySelector(outlineSelector); - - let grid = this.querySelector('.grid'); - let aim = outlineLayer.querySelector('line'); let pt = new DOMPoint(e.clientX, e.clientY); - let { x, y } = pt.matrixTransform(grid.getScreenCTM().inverse()); + let { x: pointerX, y: pointerY } = pt.matrixTransform(grid.getScreenCTM().inverse()); let pivotPt = [x1, y1] = [aim.getAttribute('x1'), aim.getAttribute('y1')].map(n => parseFloat(n)); + let { x, y, width, height } = grid.getBBox(); + let [minX, minY, maxX, maxY] = [x, y, x + width, y + height]; + let bounds = { minX, minY, maxX, maxY }; + let cornerPoints = [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; - let [maxX, maxY, minX, minY] = [ - grid.getBBox().x + grid.getBBox().width, - grid.getBBox().y + grid.getBBox().height, - grid.getBBox().x, - grid.getBBox().y - ].map(n => parseFloat(n)); - - let edgePointArgs = [aim.getAttribute('x1'), aim.getAttribute('y1'), x, y, maxX, maxY, minX, minY].map(n => parseFloat(n)) - let aimPt = [x2, y2] = edgePoint(...edgePointArgs); + let aimPt = [x2, y2] = edgePoint(pivotPt, [pointerX, pointerY], bounds); aim.setAttributeNS(null, 'x2', x2); aim.setAttributeNS(null, 'y2', y2); @@ -114,8 +93,8 @@ function position(e) { let [newY1, newX1] = [y2 - yDelta, x2 - xDelta]; let [newY2, newX2] = [y2 + yDelta, x2 + xDelta]; - let arcPt1 = [newX1, newY1] = edgePoint(x1, y1, newX1, newY1, maxX, maxY, minX, minY); - let arcPt2 = [newX2, newY2] = edgePoint(x1, y1, newX2, newY2, maxX, maxY, minX, minY); + let arcPt1 = [newX1, newY1] = edgePoint(pivotPt, [newX1, newY1], bounds); + let arcPt2 = [newX2, newY2] = edgePoint(pivotPt, [newX2, newY2], bounds); activeFiringArcOutline.setAttributeNS(null, 'points', `${newX1},${newY1} ${x1},${y1} ${newX2},${newY2}`); @@ -213,6 +192,7 @@ export default function (el) { let outlineLayer = svg.querySelector('#lines'); let arcContainer = svg.querySelector('#firing-arcs'); let grid = svg.querySelector('.grid'); + let points = `${x},${y} ${x},${y} ${x},${y}`; let aim = document.createElementNS(svgns, 'line'); aim.setAttributeNS(null, 'x1', x); @@ -221,21 +201,16 @@ export default function (el) { aim.setAttributeNS(null, 'y2', y); outlineLayer.appendChild(aim); - cornerPoints = (function () { - let { x, y, width, height } = grid.getBBox(); - return [[x, y], [x + width, y], [x + width, y + height], [x, y + height]]; - })(); - let firingArc = document.createElementNS(svgns, 'polygon'); let firingArcOutline = document.createElementNS(svgns, 'polyline'); setDataAttrs(counter, firingArc); firingArc.dataset.size = size; firingArc.classList.add('firing-arc', 'active'); - firingArc.setAttributeNS(null, 'points', `${x},${y} ${x},${y} ${x},${y}`); + firingArc.setAttributeNS(null, 'points', points); setDataAttrs(counter, firingArcOutline); - firingArcOutline.setAttributeNS(null, 'points', `${x},${y} ${x},${y} ${x},${y}`); + firingArcOutline.setAttributeNS(null, 'points', points); let clipShape = document.createElementNS(svgns, 'circle'); clipShape.setAttributeNS(null, 'cx', x); @@ -251,10 +226,12 @@ export default function (el) { arcLayer.appendChild(firingArc); outlineLayer.appendChild(firingArcOutline); + const positionListener = position.bind(svg, firingArc, firingArcOutline, aim, grid); + let firingArcPlacementListener = e => { svg.querySelectorAll('.firing-arc.active').forEach(el => el.classList.remove('active')); grid.removeAttribute('style'); - svg.removeEventListener('mousemove', position); + svg.removeEventListener('mousemove', positionListener); firingArc.removeEventListener('click', firingArcPlacementListener); firingArc.removeEventListener('contextmenu', cancelFiringArcPlacement); }; @@ -268,13 +245,13 @@ export default function (el) { this.get(counter).forEach(fa => fa.remove()); grid.removeAttribute('style'); - svg.removeEventListener('mousemove', position); + svg.removeEventListener('mousemove', positionListener); }; grid.style.pointerEvents = 'none'; - svg.addEventListener('mousemove', position); firingArc.addEventListener('click', firingArcPlacementListener); firingArc.addEventListener('contextmenu', cancelFiringArcPlacement); + svg.addEventListener('mousemove', positionListener); }; this.clear = function (allegiance) { |