Web Dev Solutions

Catalin Mititiuc

From 16672db15a7ef7e27bfbd8a080cd03740a26d13a Mon Sep 17 00:00:00 2001 From: Catalin Mititiuc Date: Fri, 5 Apr 2024 21:39:52 -0700 Subject: WIP: sight line --- index.js | 199 ++++++++++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 141 insertions(+), 58 deletions(-) diff --git a/index.js b/index.js index 105c4ee..11dddd8 100644 --- a/index.js +++ b/index.js @@ -375,6 +375,7 @@ const Counter = new function() { }, clickClone = function() { + console.log('clone counter click fires'); let { troopNumber, troopAllegiance, x, y } = this.dataset, [xAttr, yAttr] = this.parentElement.getAttribute('transform').match(/-?\d+\.?\d*/g); @@ -637,6 +638,57 @@ const RecordSheet = new function() { }; }; +const SightLine = new function() { + this.clear = function() { + let sl = grid.querySelector('line.sight-line'); + + if (sl) { + sl.remove(); + } + + this.clearHexes(); + }; + + this.clearHexes = function() { + ptGrp.querySelectorAll('use[href="#point"].active').forEach(el => el.classList.remove('active')); + }; + + this.draw = function(x1, y1, x2, y2) { + let source = ptGrp.querySelector(`g[data-x="${x1}"][data-y="${y1}"]`), + target = ptGrp.querySelector(`g[data-x="${x2}"][data-y="${y2}"]`), + + [slX1, slY1] = source.getAttribute('transform').match(/-?\d+\.?\d*/g), + [slX2, slY2] = target.getAttribute('transform').match(/-?\d+\.?\d*/g), + + sightLine = document.createElementNS(svgns, 'line'); + + sightLine.classList.add('sight-line'); + sightLine.classList.add('active'); + sightLine.setAttributeNS(null, 'x1', slX1); + sightLine.setAttributeNS(null, 'y1', slY1); + sightLine.setAttributeNS(null, 'x2', slX2); + sightLine.setAttributeNS(null, 'y2', slY2); + + grid.appendChild(sightLine); + + let coords = [x1, y1, x2, y2]; + this.drawHexes(...coords); + }; + + this.drawHexes = function(...coords) { + this.clearHexes() + + info.querySelector('#hex-count').textContent = offset_distance(...coords); + info.style.display = 'block'; + + let lineCoords = linedraw(...coords); + lineCoords.shift(); + let s = lineCoords.map(([x, y]) => `use[href="#point"][data-x="${x}"][data-y="${y}"]`).join(', '); + + ptGrp.querySelectorAll(s).forEach(p => p.classList.add('active')); + }; +} + POINTS.forEach((row, index) => row.forEach(([x, y]) => { var cx = x * INRADIUS * 2 + (isEven(index) ? INRADIUS : 0), cy = y * 3 / 2 * CIRCUMRADIUS, @@ -667,12 +719,74 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { }); group.addEventListener('click', e => { - let cl = e.target.classList; + console.log('group click fires'); + let cl = e.target.classList, + sl = grid.querySelector('line.sight-line'); - if (cl.contains('counter') && !cl.contains('clone')) { - RecordSheet.select(e.target); - Counter.select(e.target); + + // if you click on someone else's counter (but not their clone), + // then you're selecting another soldier, so you should clear the sightline + // if it's locked, and you click on an intermediate clone, nothing should change + // if it's locked and you click on your own counter or your last clone + // it should redraw from your counter to the locked target hex because in + // both cases your counter just moved + + console.log('target', e.target); + + if (sl) { + let selected = RecordSheet.getSelected(), + { troopNumber: sTn, troopAllegiance: sTa} = selected.dataset, + { troopNumber: tTn, troopAllegiance: tTa} = e.target.dataset; + + console.log('selected', selected); + console.log(cl.contains('counter'), sTn == tTn, sTa == tTa); + + if (!sl.classList.contains('active') && (cl.contains('counter') && sTn == tTn && sTa == tTa)) { + let counterParent = Counter.get(tTn, tTa).parentElement, + [x, y] = counterParent.getAttribute('transform').match(/-?\d+\.?\d*/g), + target = ptGrp.querySelector(`g[transform="translate(${sl.getAttribute('x2')} ${sl.getAttribute('y2')})"]`), + { x: x1, y: y1 } = counterParent.dataset, + { x: x2, y: y2 } = target.dataset; + + sl.setAttributeNS(null, 'x1', x); + sl.setAttributeNS(null, 'y1', y); + + SightLine.drawHexes(...[x1, y1, x2, y2].map(n => parseInt(n))); + } else if ((cl.contains('counter') && sTn == tTn && sTa == tTa) || (cl.contains('counter') && !cl.contains('clone'))) { + RecordSheet.select(e.target); + Counter.select(e.target); + SightLine.clear(); + } } + + // if (cl.contains('counter') && !cl.contains('clone') && !cl.contains('selected')) { + // RecordSheet.select(e.target); + // Counter.select(e.target); + // SightLine.clear(); + // } else if (sl && !sl.classList.contains('active') && cl.contains('counter')) { + // let selected = RecordSheet.getSelected(), + // { troopNumber: tTn, troopAllegiance: tTa} = e.target.dataset; + + // console.log('selected', selected); + + // if (selected && selected.dataset.troopNumber == tTn && selected.dataset.troopAllegiance == tTa) { + // let counterParent = Counter.get(tTn, tTa).parentElement, + // [x, y] = counterParent.getAttribute('transform').match(/-?\d+\.?\d*/g), + // target = ptGrp.querySelector(`g[transform="translate(${sl.getAttribute('x2')} ${sl.getAttribute('y2')})"]`), + // { x: x1, y: y1 } = counterParent.dataset, + // { x: x2, y: y2 } = target.dataset; + + // console.log('group', group); + + // console.log('sl', sl); + // console.log('x1, y1, x2, y2', x1, y1, x2, y2); + + // sl.setAttributeNS(null, 'x1', x); + // sl.setAttributeNS(null, 'y1', y); + + // SightLine.drawHexes(...[x1, y1, x2, y2].map(n => parseInt(n))); + // } + // } }); point.addEventListener('click', e => { @@ -681,14 +795,24 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { svg.querySelector(`.counter[data-x="${point.dataset.x}"][data-y="${point.dataset.y}"]`); if (selectedSoldier && !existingOccupant) { - Counter.place(selectedSoldier, point); - let sl = svg.querySelector('.sight-line'); + Counter.place(selectedSoldier, point); + if (sl) { - sl.classList.add('active'); - point.dispatchEvent(new MouseEvent('mouseout')); - point.dispatchEvent(new MouseEvent('pointerover')); + if (sl.classList.contains('active')) { + SightLine.clear(); + } else { + let [x, y] = point.parentElement.getAttribute('transform').match(/-?\d+\.?\d*/g), + target = ptGrp.querySelector(`g[transform="translate(${sl.getAttribute('x2')} ${sl.getAttribute('y2')})"]`), + { x: x1, y: y1 } = point.dataset, + { x: x2, y: y2 } = target.dataset; + + sl.setAttributeNS(null, 'x1', x); + sl.setAttributeNS(null, 'y1', y); + + SightLine.drawHexes(...[x1, y1, x2, y2].map(n => parseInt(n))); + } } } }); @@ -696,19 +820,16 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { group.addEventListener('contextmenu', e => { e.preventDefault(); - // if the sight line is active - // lock it - // otherwise - // try to draw sightline from active counter to click location let sl = svg.querySelector('.sight-line'); if (sl) { sl.classList.toggle('active'); if (sl.classList.contains('active')) { - point.dispatchEvent(new MouseEvent('mouseout')); - point.dispatchEvent(new MouseEvent('pointerover')); + SightLine.clear(); } + + group.dispatchEvent(new MouseEvent('pointerover')); } }); @@ -723,28 +844,7 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { sl = document.querySelector('line.sight-line'); if (counter && (!sl || sl.classList.contains('active'))) { - let source = ptGrp.querySelector(`g[data-x="${counter.dataset.x}"][data-y="${counter.dataset.y}"]`); - // [x1, y1] = [source.getAttribute('x'), source.getAttribute('y')], - // [x2, y2] = [e.target.getAttribute('x'), e.target.getAttribute('y')]; - if (counter.dataset.x !== e.target.dataset.x || counter.dataset.y !== e.target.dataset.y) { - // let { x: svgX1, y: svgY1 } = ptGrpToSvgPt(x1, y1); - // let { x: svgX2, y: svgY2 } = ptGrpToSvgPt(x2, y2); - - let sightLine = document.createElementNS(svgns, 'line'); - - let [x1, y1] = source.getAttribute('transform').match(/-?\d+\.?\d*/g); - let [x2, y2] = e.target.parentElement.getAttribute('transform').match(/-?\d+\.?\d*/g); - - sightLine.classList.add('sight-line'); - sightLine.classList.add('active'); - sightLine.setAttributeNS(null, 'x1', x1); - sightLine.setAttributeNS(null, 'y1', y1); - sightLine.setAttributeNS(null, 'x2', x2); - sightLine.setAttributeNS(null, 'y2', y2); - - grid.appendChild(sightLine); - let coords = [ counter.dataset.x, counter.dataset.y, @@ -752,27 +852,17 @@ POINTS.forEach((row, index) => row.forEach(([x, y]) => { e.target.dataset.y ].map(n => parseInt(n)); - info.querySelector('#hex-count').textContent = offset_distance(...coords); - info.style.display = 'block'; - - let lineCoords = linedraw(...coords); - lineCoords.shift(); - let s = lineCoords.map(([x, y]) => `use[href="#point"][data-x="${x}"][data-y="${y}"]`).join(', '); - ptGrp.querySelectorAll(s).forEach(p => p.classList.add('active')); + SightLine.draw(...coords); } } } }); - point.addEventListener('pointerout', e => { + group.addEventListener('pointerout', e => { let sl = svg.querySelector('.sight-line.active'); - if (sl) { - // console.log('deleting sight line'); - info.querySelector('#hex-count').textContent = '-'; - info.style.display = 'none'; - ptGrp.querySelectorAll('.active').forEach(el => el.removeAttribute('class')); - svg.querySelectorAll('.sight-line').forEach(el => el.remove()); + if (sl && sl.classList.contains('active')) { + SightLine.clear(); } }); @@ -790,14 +880,7 @@ document.querySelectorAll('.soldier-record').forEach(el => Counter.select(el); } - let sl = svg.querySelector('.sight-line'); - - if (sl) { - info.querySelector('#hex-count').textContent = '-'; - info.style.display = 'none'; - ptGrp.querySelectorAll('.active').forEach(el => el.removeAttribute('class')); - svg.querySelectorAll('.sight-line').forEach(el => el.remove()); - } + SightLine.clear(); }) ); -- cgit v1.2.3