diff --git a/client/.eslintrc.js b/client/.eslintrc.js index b88c8b4c..1f98c512 100644 --- a/client/.eslintrc.js +++ b/client/.eslintrc.js @@ -78,9 +78,7 @@ module.exports = { // enforce that class methods use "this" // https://eslint.org/docs/rules/class-methods-use-this - 'class-methods-use-this': ['error', { - exceptMethods: [], - }], + 'class-methods-use-this': 0, // require return statements to either always or never specify values 'consistent-return': 'error', diff --git a/client/assets/styles/game.css b/client/assets/styles/game.css index c4b8e534..5acd7352 100644 --- a/client/assets/styles/game.css +++ b/client/assets/styles/game.css @@ -81,7 +81,7 @@ } .game .targeting-arrows { - stroke-width: 5px; + stroke-width: 2px; } .game-construct .targeting { @@ -429,8 +429,4 @@ .game .effects { font-size: 100%; } - - .game .targeting-arrows { - stroke-width: 1em; - } -} +} \ No newline at end of file diff --git a/client/src/components/targeting.arrows.jsx b/client/src/components/targeting.arrows.jsx index 22384c9e..59bde376 100644 --- a/client/src/components/targeting.arrows.jsx +++ b/client/src/components/targeting.arrows.jsx @@ -1,6 +1,9 @@ const preact = require('preact'); +const { Component } = require('preact'); const { connect } = require('preact-redux'); +const throttle = require('lodash/throttle'); + const addState = connect( ({ game, account, resolution }) => ({ game, account, resolution }) ); @@ -13,43 +16,72 @@ const TC_MAP = [ TARGET_COLOURS.GREEN, ]; -function TargetSvg(args) { - const { game, account, resolution } = args; +class TargetSvg extends Component { + constructor() { + super(); + this.state = { width: 3000, height: 1000 }; - const playerTeam = game.players.find(t => t.id === account.id); - const otherTeam = game.players.find(t => t.id !== account.id); + this.onResize = throttle(() => { + console.warn('resize') + const svg = document.getElementById('targeting'); + const { width, height } = svg.getBoundingClientRect(); + this.setState({ width, height }); + }, 500); + } - const playerTeamIds = playerTeam.constructs.map(c => c.id); - const outgoing = game.stack.filter(stack => playerTeamIds.includes(stack.source_construct_id)); + render(props, state) { + const { game, account, resolution } = props; + const { width, height } = state; - const WIDTH = 3000; - const HEIGHT = 1000; + const playerTeam = game.players.find(t => t.id === account.id); + const otherTeam = game.players.find(t => t.id !== account.id); - function getPath(cast) { - const source = playerTeam.constructs.findIndex(c => c.id === cast.source_construct_id); - const defensive = playerTeamIds.includes(cast.target_construct_id); - const target = defensive - ? playerTeam.constructs.findIndex(c => c.id === cast.target_construct_id) - : otherTeam.constructs.findIndex(c => c.id === cast.target_construct_id); + const playerTeamIds = playerTeam.constructs.map(c => c.id); + const outgoing = game.stack.filter(stack => playerTeamIds.includes(stack.source_construct_id)); - const stroke = TC_MAP[source]; + function getPath(cast) { + const source = playerTeam.constructs.findIndex(c => c.id === cast.source_construct_id); + const defensive = playerTeamIds.includes(cast.target_construct_id); + const target = defensive + ? playerTeam.constructs.findIndex(c => c.id === cast.target_construct_id) + : otherTeam.constructs.findIndex(c => c.id === cast.target_construct_id); - const sourceY = HEIGHT; - const sourceX = (source * WIDTH / 3) + WIDTH / 6; - const targetX = (target * WIDTH / 3) + WIDTH / 6 + (defensive ? WIDTH / 24 : 0); - const targetY = defensive ? HEIGHT : 0; - const curveEnd = HEIGHT * 0.25; - const curveStart = HEIGHT * 0.75; + const stroke = TC_MAP[source]; + + const sourceY = height; + const sourceX = (source * width / 3) + width / 6; + const targetX = (target * width / 3) + width / 6 + (defensive ? width / 24 : 0); + const targetY = defensive ? height : 0; + const curveEnd = height * 0.25; + const curveStart = height * 0.75; + + if (defensive) { + const path = ` + M${sourceX},${sourceY} + L${sourceX},${height * 0.75} + L${targetX},${height * 0.75} + L${targetX},${targetY} + L${targetX - (width * 0.005)},${height * 0.875} + M${targetX},${targetY} + L${targetX + (width * 0.005)},${height * 0.875} + `; + + return ; + } - if (defensive) { const path = ` M${sourceX},${sourceY} - L${sourceX},${HEIGHT * 0.75} - L${targetX},${HEIGHT * 0.75} + L${sourceX},${curveStart} + C${sourceX},${curveEnd} ${targetX},${curveStart} ${targetX},${curveEnd} + L${targetX},${targetY} - L${targetX - (WIDTH * 0.005)},${HEIGHT * 0.875} + L${targetX - (width * 0.005)},${height * 0.125} M${targetX},${targetY} - L${targetX + (WIDTH * 0.005)},${HEIGHT * 0.875} + L${targetX + (width * 0.005)},${height * 0.125} + `; return ; } - const path = ` - M${sourceX},${sourceY} - L${sourceX},${curveStart} - C${sourceX},${curveEnd} ${targetX},${curveStart} ${targetX},${curveEnd} + const arrows = resolution + ? null + : outgoing.map(getPath); - L${targetX},${targetY} - L${targetX - (WIDTH * 0.005)},${HEIGHT * 0.125} - M${targetX},${targetY} - L${targetX + (WIDTH * 0.005)},${HEIGHT * 0.125} - - `; - - return ; + return ( + + {arrows} + + ); } - const arrows = resolution - ? null - : outgoing.map(getPath); + componentDidMount() { + window.addEventListener('resize', this.onResize); + this.onResize(); + } - return ( - - {arrows} - - ); + componentWillUnmount() { + window.removeEventListener('resize', this.onResize); + } } module.exports = addState(TargetSvg);