index : btroops | |
Virtual board game-aid for BattleTroops, an infantry combat simulator wargame published by FASA in 1989. |
aboutsummaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'index.js')
-rw-r--r-- | index.js | 77 |
1 files changed, 65 insertions, 12 deletions
@@ -65,7 +65,8 @@ let getPointCoords = (x, y) => { let svgns = "http://www.w3.org/2000/svg", svg = document.querySelector('svg'), - map = document.querySelector('rect#map'); + map = document.querySelector('rect#map'), + hex = document.getElementById('point'); const { x: VIEWBOX_X, y: VIEWBOX_Y, width: VIEWBOX_WIDTH, height: VIEWBOX_HEIGHT } = svg.viewBox.baseVal; @@ -75,6 +76,8 @@ const COLUMN_COUNT = 33, HORZ_POINT_DISTANCE = 1.005, VERT_POINT_DISTANCE = Math.sqrt(3) * HORZ_POINT_DISTANCE / 2, ALTERNATING_OFFSET = HORZ_POINT_DISTANCE / 2, + CIRCUMRADIUS = Math.max(...[...new Set(Object.values(hex.points).flatMap(({x, y}) => [x, y]))]), + INRADIUS = CIRCUMRADIUS * Math.sqrt(3) / 2, [X_OFFSET, Y_OFFSET] = [0.25, 0.45], [COLUMNS, ROWS] = [COLUMN_COUNT, ROW_COUNT].map(n => [...Array(n).keys()]), POINTS = ROWS.map(y => COLUMNS.map(x => [x, y])); @@ -85,14 +88,62 @@ const FIRING_ARC_SIZE = { 'large': Math.atan((21 * HORZ_POINT_DISTANCE) / (6 * VERT_POINT_DISTANCE)) } +const settingsPanel = document.getElementById('panel'); + +Object.values(settingsPanel.querySelectorAll('fieldset')).forEach(fieldset => { + const target = document.getElementById(fieldset.name); + const transform = window.getComputedStyle(target).transform.match(/-?\d+\.?\d*/g); + const inputs = fieldset.querySelectorAll('input'); + + if (transform) { + const [scaleX, skewX, skewY, scaleY, translateX, translateY] = + transform.map(n => parseFloat(n)); + + const cosScale = Math.sqrt(scaleX**2 + skewY**2); + const sinScale = Math.sqrt(scaleY**2 + skewX**2); + + let values = { + scale: Math.round((sinScale + cosScale) / 2 * 10) / 10, + translateX: translateX, + translateY: translateY, + rotate: Math.round(radToDeg((Math.acos(scaleX / cosScale) + Math.asin(skewX / sinScale)) / 2) * 10) / 10 + } + + inputs.forEach(input => input.value = values[input.name]); + } + + inputs.forEach(input => { + 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 transform = `translate(${translateX}px, ${translateY}px) rotate(${rotate}deg) scale(${scale}) ` + target.style.transform = transform; + }); + + input.addEventListener('pointerleave', () => document.activeElement.blur()); + }); +}); + +const pointsGroup = document.getElementById('points'); + POINTS.forEach((row, index) => row.forEach(([x, y]) => { - var cx = x * HORZ_POINT_DISTANCE + X_OFFSET + (isEven(index) ? ALTERNATING_OFFSET : 0), - cy = y * HORZ_POINT_DISTANCE * VERT_POINT_DISTANCE + Y_OFFSET, + // var cx = x * HORZ_POINT_DISTANCE + X_OFFSET + (isEven(index) ? ALTERNATING_OFFSET : 0), + // cy = y * HORZ_POINT_DISTANCE * VERT_POINT_DISTANCE + Y_OFFSET, + // var cx = x * Math.sqrt(3) + X_OFFSET + (isEven(index) ? INRADIUS : 0), + var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0), + cy = y * 3 / 2 * CIRCUMRADIUS, point = document.createElementNS(svgns, 'use'); point.setAttributeNS(null, 'href', `#point`); - point.setAttributeNS(null, 'x', `${cx}in`); - point.setAttributeNS(null, 'y', `${cy}in`); + point.setAttributeNS(null, 'x', `${toFixed(cx)}`); + point.setAttributeNS(null, 'y', `${toFixed(cy)}`); + // point.setAttributeNS(null, 'x', `${cx}`); + // point.setAttributeNS(null, 'y', `${cy}`); point.dataset.x = x; point.dataset.y = y; @@ -147,6 +198,8 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { let {troopNumber, troopAllegiance} = selectedSoldier.dataset, selector = troopSelector(troopNumber, troopAllegiance), source = document.querySelector(`circle.counter${selector}`), + + // TODO: use isEqualNode() method instead sourceAndTargetAreNotTheSame = [ troopNumber != e.target.dataset.troopNumber, troopAllegiance != e.target.dataset.troopAllegiance @@ -185,7 +238,7 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { point.addEventListener('mouseout', e => e.target.removeAttribute('class')); - svg.appendChild(point); + pointsGroup.appendChild(point); })); map.addEventListener('mousemove', e => { @@ -390,11 +443,11 @@ svg.addEventListener('wheel', e => { let widthChange = (1 - ((svgP.x - x) / width)) * widthDelta; let heightChange = (1 - ((svgP.y - y) / height)) * heightDelta; - let newX = e.deltaY < 0 ? x + xChange : x - xChange; - let newWidth = e.deltaY < 0 ? width - xChange - widthChange : width + xChange + widthChange; + let newX = parseInt(e.deltaY < 0 ? x + xChange : x - xChange); + let newWidth = parseInt(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; + let newY = parseInt(e.deltaY < 0 ? y + yChange : y - yChange); + let newHeight = parseInt(e.deltaY < 0 ? height - yChange - heightChange : height + yChange + heightChange); // console.log('VIEWBOX_X', 'VIEWBOX_Y', VIEWBOX_X, VIEWBOX_Y); // console.log('VIEWBOX_WIDTH', 'VIEWBOX_HEIGHT', VIEWBOX_WIDTH, VIEWBOX_HEIGHT); @@ -446,8 +499,8 @@ svg.addEventListener('pointerdown', e => { ctm = svg.getScreenCTM().inverse(); const [svgStartPt, svgMovePt] = [startPt, movePt].map(p => p.matrixTransform(ctm)), - moveX = svgStartPt.x - svgMovePt.x + x, - moveY = svgStartPt.y - svgMovePt.y + y; + moveX = parseInt(svgStartPt.x - svgMovePt.x + x), + moveY = parseInt(svgStartPt.y - svgMovePt.y + y); svg.setAttributeNS(null, 'viewBox', `${moveX} ${moveY} ${width} ${height}`); } |