add support for sliding to select cards

This commit is contained in:
Songyi Huang 2021-05-23 00:23:56 -07:00
parent 011f744efc
commit 8381c01d38
4 changed files with 117 additions and 12 deletions

View File

@ -70,7 +70,17 @@
bottom: 0; bottom: 0;
} }
.playingCards.selectable label.card:active::after { /* .playingCards.selectable label.card:active::after {
background-color: rgba(23, 146, 210, 0.5);
content: '';
position: absolute;
left: 0;
top: 0;
width: 3em;
height: 4em;
} */
.playingCards.selectable label.card.user-selecting::after {
background-color: rgba(23, 146, 210, 0.5); background-color: rgba(23, 146, 210, 0.5);
content: ''; content: '';
position: absolute; position: absolute;

View File

@ -232,7 +232,7 @@
.played-card-area { .played-card-area {
width: 100%; width: 100%;
position: relative; position: relative;
//transform: translateY(25px); transform: translateY(-10px);
.playingCards ul.hand { .playingCards ul.hand {
margin-bottom: 0; margin-bottom: 0;

View File

@ -10,6 +10,16 @@ import PlaceHolderPlayer from '../../assets/images/Portrait/Player.png';
import { computeHandCardsWidth, millisecond2Second, sortDoudizhuCards, translateCardData } from '../../utils'; import { computeHandCardsWidth, millisecond2Second, sortDoudizhuCards, translateCardData } from '../../utils';
class DoudizhuGameBoard extends React.Component { class DoudizhuGameBoard extends React.Component {
constructor(props) {
super(props);
this.isSelectingCards = false;
this.selectingCards = { start: null, cards: [] };
this.state = {
highlightedCards: [],
};
}
computePlayerPortrait(playerId, playerIdx) { computePlayerPortrait(playerId, playerIdx) {
if (this.props.playerInfo.length > 0) { if (this.props.playerInfo.length > 0) {
return this.props.playerInfo[playerIdx].role === 'landlord' ? ( return this.props.playerInfo[playerIdx].role === 'landlord' ? (
@ -32,6 +42,52 @@ class DoudizhuGameBoard extends React.Component {
); );
} }
handleContainerMouseLeave() {
if (this.isSelectingCards) {
console.log('container leave');
this.isSelectingCards = false;
this.selectingCards = { start: null, cards: [] };
this.setState({ highlightedCards: [] });
}
}
handleContainerMouseUp() {
if (this.isSelectingCards) {
console.log('container up');
this.isSelectingCards = false;
this.props.handleSelectedCards(this.selectingCards.cards);
this.selectingCards = { start: null, cards: [] };
this.setState({ highlightedCards: [] });
} else {
this.props.handleMainPlayerAct('deselect');
}
}
handleCardMouseDown(card, idx) {
console.log('down');
this.isSelectingCards = true;
this.selectingCards.start = idx;
this.selectingCards.cards = [card];
this.setState({ highlightedCards: this.selectingCards.cards });
console.log(this.selectingCards);
}
handleCardMouseOver(allCards, card, idx) {
if (this.isSelectingCards) {
console.log('over');
let tmpCards;
if (idx > this.selectingCards.start) {
tmpCards = allCards.slice(this.selectingCards.start, idx + 1);
} else if (idx < this.selectingCards.start) {
tmpCards = allCards.slice(idx, this.selectingCards.start + 1);
} else {
tmpCards = [card];
}
this.selectingCards = { ...this.selectingCards, cards: tmpCards };
this.setState({ highlightedCards: this.selectingCards.cards });
}
}
computeSingleLineHand(inputCards, fadeClassName = '', cardSelectable = false) { computeSingleLineHand(inputCards, fadeClassName = '', cardSelectable = false) {
const cards = inputCards === 'pass' ? inputCards : sortDoudizhuCards(inputCards); const cards = inputCards === 'pass' ? inputCards : sortDoudizhuCards(inputCards);
if (cards === 'pass') { if (cards === 'pass') {
@ -48,19 +104,30 @@ class DoudizhuGameBoard extends React.Component {
}`} }`}
> >
<ul className="hand" style={{ width: computeHandCardsWidth(cards.length, 12) }}> <ul className="hand" style={{ width: computeHandCardsWidth(cards.length, 12) }}>
{cards.map((card) => { {cards.map((card, idx) => {
const [rankClass, suitClass, rankText, suitText] = translateCardData(card); const [rankClass, suitClass, rankText, suitText] = translateCardData(card);
let selected = false; let selected = false;
if (this.props.gamePlayable && cardSelectable) { if (this.props.gamePlayable && cardSelectable) {
selected = this.props.selectedCards.indexOf(card) >= 0; selected = this.props.selectedCards.indexOf(card) >= 0;
} }
// todo: right click and move to select multiple cards
return ( return (
<li key={`handCard-${card}`}> <li key={`handCard-${card}`}>
<label <label
onClick={() => this.props.handleSelectedCards([card])} onMouseDown={(e) => {
className={`card ${rankClass} ${suitClass} ${selected ? 'selected' : ''}`} e.stopPropagation();
cardSelectable && this.handleCardMouseDown(card, idx);
}}
onMouseOver={(e) => {
e.stopPropagation();
cardSelectable && this.handleCardMouseOver(cards, card, idx);
}}
// onClick={() => this.props.handleSelectedCards([card])}
className={`card ${rankClass} ${suitClass} ${selected ? 'selected' : ''} ${
cardSelectable && this.state.highlightedCards.includes(card)
? 'user-selecting'
: ''
}`}
> >
<span className="rank">{rankText}</span> <span className="rank">{rankText}</span>
<span className="suit">{suitText}</span> <span className="suit">{suitText}</span>
@ -147,7 +214,8 @@ class DoudizhuGameBoard extends React.Component {
{this.props.gamePlayable ? ( {this.props.gamePlayable ? (
<> <>
<Button <Button
onClick={() => { onClick={(e) => {
e.stopPropagation();
this.props.handleMainPlayerAct('deselect'); this.props.handleMainPlayerAct('deselect');
}} }}
style={{ marginRight: '2em' }} style={{ marginRight: '2em' }}
@ -158,7 +226,8 @@ class DoudizhuGameBoard extends React.Component {
</Button> </Button>
<Button <Button
disabled={this.props.isPassDisabled} disabled={this.props.isPassDisabled}
onClick={() => { onClick={(e) => {
e.stopPropagation();
this.props.handleMainPlayerAct('pass'); this.props.handleMainPlayerAct('pass');
}} }}
style={{ marginRight: '2em' }} style={{ marginRight: '2em' }}
@ -169,7 +238,9 @@ class DoudizhuGameBoard extends React.Component {
</Button> </Button>
<Button <Button
disabled={!this.props.selectedCards || this.props.selectedCards.length === 0} disabled={!this.props.selectedCards || this.props.selectedCards.length === 0}
onClick={() => { onClick={(e) => {
console.log('play', e.stopPropagation);
e.stopPropagation();
this.props.handleMainPlayerAct('play'); this.props.handleMainPlayerAct('play');
}} }}
variant="contained" variant="contained"
@ -227,7 +298,17 @@ class DoudizhuGameBoard extends React.Component {
if (found) leftId = found.id; if (found) leftId = found.id;
} }
return ( return (
<div className="doudizhu-wrapper" style={{}}> <div
className="doudizhu-wrapper"
onMouseLeave={(e) => {
e.stopPropagation();
this.handleContainerMouseLeave();
}}
onClick={(e) => {
e.stopPropagation();
this.handleContainerMouseUp();
}}
>
<div <div
id={'gameboard-background'} id={'gameboard-background'}
className={ className={

View File

@ -815,7 +815,7 @@ function PvEDoudizhuDemoView() {
{gameEndDialogTitle} {gameEndDialogTitle}
</DialogTitle> </DialogTitle>
<DialogContent> <DialogContent>
<TableContainer component={Paper} className="doudizhu-statistic-table"> <TableContainer className="doudizhu-statistic-table" component={Paper}>
<Table aria-label="statistic table"> <Table aria-label="statistic table">
<TableHead> <TableHead>
<TableRow> <TableRow>
@ -841,7 +841,21 @@ function PvEDoudizhuDemoView() {
</TableContainer> </TableContainer>
</DialogContent> </DialogContent>
<DialogActions> <DialogActions>
<Button onClick={() => handleCloseGameEndDialog()} color="primary" variant="contained" autoFocus> <Button
onClick={() => {
// todo: disable all action (pass, deselect) if cancel
setIsGameEndDialogOpen(false);
}}
>
Cancel
</Button>
<Button
onClick={() => handleCloseGameEndDialog()}
color="primary"
variant="contained"
autoFocus
style={{ margin: '16px' }}
>
Play Again Play Again
</Button> </Button>
</DialogActions> </DialogActions>