edit readme,fix some bug,edit client ui
This commit is contained in:
@@ -0,0 +1,300 @@
|
||||
<template>
|
||||
<div class="action-container">
|
||||
<div class="action"
|
||||
v-show="isAction">
|
||||
<div class="action-type action-btn">
|
||||
<span @click="action('fold')">fold</span>
|
||||
<span @click="action('check')"
|
||||
v-show="showActionBtn('check')">check</span>
|
||||
<span @click="action('call')"
|
||||
v-show="showActionBtn('call')">call</span>
|
||||
<span @click="otherSizeHandle()"
|
||||
v-show="showActionBtn('raise')">more</span>
|
||||
<span @click="action('allin')"
|
||||
v-show="!showActionBtn('raise')">allin</span>
|
||||
</div>
|
||||
<div class="raise-size">
|
||||
<div class="not-allin"
|
||||
v-show="showActionBtn('raise')">
|
||||
<i v-for="size in raiseSizeMap.firsAction"
|
||||
@click="raise(size)"
|
||||
v-show="isPreFlop && pot === 3">
|
||||
{{Math.floor(size * prevSize)}}
|
||||
</i>
|
||||
<i v-for="size in raiseSizeMap.other"
|
||||
@click="raise(size)"
|
||||
v-show="showActionSize(size)"
|
||||
> {{Math.floor(size * pot)}}</i>
|
||||
<!-- <i @click="raise(pot)">{{pot}}</i>-->
|
||||
<!-- <i @click="raise(pot * 2)">{{2*pot}}</i>-->
|
||||
</div>
|
||||
</div>
|
||||
<div class="action-other-size"
|
||||
v-if="isRaise">
|
||||
<div class="action-other-size-body">
|
||||
<div class="size"
|
||||
v-show="currPlayer && raiseSize < currPlayer.counter">
|
||||
<input type="number" v-model="raiseSize">
|
||||
</div>
|
||||
<div class="size"
|
||||
v-show="currPlayer && raiseSize === currPlayer.counter">Allin
|
||||
</div>
|
||||
<range :max="currPlayer && currPlayer.counter"
|
||||
:min="minActionSize"
|
||||
:is-horizontal="true"
|
||||
v-model="raiseSize"
|
||||
@change="getActionSize"></range>
|
||||
<div class="btn"
|
||||
@click="addSize">ok
|
||||
</div>
|
||||
</div>
|
||||
<div class="shadow"
|
||||
@click="isRaise = false"></div>
|
||||
</div>
|
||||
<iAudio :play="playClick" type="click"></iAudio>
|
||||
<iAudio :play="playFold" type="fold"></iAudio>
|
||||
<iAudio :play="playRaise" type="raise"></iAudio>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
import range from './Range.vue';
|
||||
import iAudio from './Audio.vue';
|
||||
import { IPlayer } from '@/interface/IPlayer';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
range,
|
||||
iAudio,
|
||||
},
|
||||
})export default class Action extends Vue {
|
||||
@Prop() private isAction: boolean = false;
|
||||
@Prop() private minActionSize!: number;
|
||||
@Prop() private pot!: number;
|
||||
@Prop() private prevSize!: number;
|
||||
@Prop() private baseSize!: number;
|
||||
@Prop() private isPreFlop!: boolean;
|
||||
@Prop() private isTwoPlayer!: boolean;
|
||||
@Prop() private currPlayer!: IPlayer;
|
||||
|
||||
private isRaise = false;
|
||||
private raiseSize: number = 0;
|
||||
private actioned = false;
|
||||
private playClick = false;
|
||||
private playRaise = false;
|
||||
private playFold = false;
|
||||
private raiseSizeMap = {
|
||||
firsAction: {
|
||||
two: 2,
|
||||
three: 3,
|
||||
four: 4,
|
||||
},
|
||||
other: {
|
||||
oneThirdPot: 0.5,
|
||||
halfPot: 0.75,
|
||||
pot: 1,
|
||||
},
|
||||
};
|
||||
|
||||
@Watch('isAction')
|
||||
private wAction(val: boolean) {
|
||||
this.actioned = !val;
|
||||
this.playClick = false;
|
||||
this.playRaise = false;
|
||||
this.playFold = false;
|
||||
}
|
||||
|
||||
@Watch('raiseSize')
|
||||
private wRaiseSize(val: number) {
|
||||
this.raiseSize = val > this.currPlayer.counter ? this.currPlayer.counter : val < this.minActionSize
|
||||
? this.minActionSize
|
||||
: val;
|
||||
}
|
||||
|
||||
get canActionSize() {
|
||||
return Number(this.currPlayer && this.currPlayer.counter + this.currPlayer.actionSize);
|
||||
}
|
||||
|
||||
private raise(size: number) {
|
||||
const realSize = size === 0 ? this.prevSize * 3 : size * this.pot;
|
||||
this.action(`raise:${Math.floor(realSize)}`);
|
||||
}
|
||||
|
||||
private action(command: string) {
|
||||
if (command.indexOf('raise') > -1 || command === 'allin' || command === 'call' ) {
|
||||
this.playRaise = true;
|
||||
}
|
||||
if (command === 'fold' || command === 'check') {
|
||||
this.playFold = true;
|
||||
}
|
||||
if (!this.actioned) {
|
||||
this.actioned = true;
|
||||
this.$emit('action', command);
|
||||
// this.isAction = false;
|
||||
this.isRaise = false;
|
||||
this.actioned = false;
|
||||
}
|
||||
}
|
||||
|
||||
private showActionSize(multiple: number) {
|
||||
// big then double pre-size and small then counter
|
||||
return this.currPlayer
|
||||
&& this.currPlayer.counter > Math.floor(multiple * this.pot)
|
||||
&& this.prevSize * 2 <= Math.floor(multiple * this.pot)
|
||||
&& this.baseSize * 2 <= Math.floor(multiple * this.pot);
|
||||
}
|
||||
|
||||
private otherSizeHandle() {
|
||||
this.isRaise = true;
|
||||
this.raiseSize = this.minActionSize;
|
||||
}
|
||||
|
||||
private getActionSize(size: number) {
|
||||
this.raiseSize = size;
|
||||
}
|
||||
|
||||
private addSize() {
|
||||
if (this.raiseSize === this.currPlayer?.counter) {
|
||||
this.action('allin');
|
||||
} else {
|
||||
this.action(`raise:${this.raiseSize}`);
|
||||
}
|
||||
}
|
||||
|
||||
private showActionBtn(type: string) {
|
||||
// check
|
||||
if ('check' === type) {
|
||||
return this.prevSize <= 0
|
||||
|| (this.isPreFlop
|
||||
&& this.isTwoPlayer
|
||||
&& this.currPlayer?.type === 'd'
|
||||
&& this.prevSize === 2)
|
||||
|| (this.currPlayer?.type === 'bb' && this.prevSize === 2 &&
|
||||
this.isPreFlop);
|
||||
}
|
||||
// raise
|
||||
if ('raise' === type) {
|
||||
return this.canActionSize > this.prevSize * 2;
|
||||
}
|
||||
// call
|
||||
if ('call' === type) {
|
||||
return this.canActionSize > this.prevSize
|
||||
&& this.prevSize > 0
|
||||
&& !((this.isPreFlop
|
||||
&& this.isTwoPlayer
|
||||
&& this.currPlayer?.type === 'd'
|
||||
&& this.prevSize === 2 * this.baseSize)
|
||||
|| (this.currPlayer?.type === 'bb' && this.prevSize === 2 * this.baseSize &&
|
||||
this.isPreFlop));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
.action-container {
|
||||
.action {
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
width: 80vw;
|
||||
top: 65vh;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
|
||||
.raise-size {
|
||||
position: absolute;
|
||||
top: -7vh;
|
||||
left: 50%;
|
||||
width: 53vw;
|
||||
margin-left: -26.4vw;
|
||||
text-align: center;
|
||||
|
||||
i {
|
||||
padding: 2px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
display: inline-block;
|
||||
font-style: normal;
|
||||
font-size: 10px;
|
||||
line-height: 24px;
|
||||
border-radius: 50%;
|
||||
color: #fff;
|
||||
border: 1px solid #fff;
|
||||
background: rgba(0, 0, 0, .2);
|
||||
margin: 10px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
|
||||
.action-btn {
|
||||
span {
|
||||
border-radius: 50%;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
padding: 2px;
|
||||
text-align: center;
|
||||
margin: 0 10px;
|
||||
line-height: 40px;
|
||||
border: 1px solid #fff;
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
.action-other-size {
|
||||
background-color: rgba(0, 0, 0, 0);
|
||||
position: fixed;
|
||||
width: 50vw;
|
||||
height: 30vh;
|
||||
right: -16px;
|
||||
top: -35vh;
|
||||
z-index: 90;
|
||||
|
||||
.shadow {
|
||||
position: absolute;
|
||||
top: -30vh;
|
||||
width: 99vw;
|
||||
height: 100vh;
|
||||
right: -5vw;
|
||||
z-index: 8;
|
||||
overflow: hidden;
|
||||
background: linear-gradient(-70deg, black, transparent);
|
||||
}
|
||||
|
||||
.action-other-size-body {
|
||||
z-index: 9;
|
||||
position: absolute;
|
||||
width: 50vw;
|
||||
height: 30vh;
|
||||
.size{
|
||||
input{
|
||||
background: transparent;
|
||||
font-size: 20px;
|
||||
width: 50px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
.btn {
|
||||
position: absolute;
|
||||
top: 34vh;
|
||||
left: 20vw;
|
||||
border: 1px solid #fff;
|
||||
border-radius: 50%;
|
||||
background-color: rgba(0, 0, 0, 0.4);
|
||||
padding: 5px;
|
||||
font-size: 12px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,106 @@
|
||||
<template>
|
||||
<div class="buy-in"
|
||||
v-show="showBuyIn">
|
||||
<div class="shadow"
|
||||
@click="closeBuyIn"></div>
|
||||
<div class="buy-in-body">
|
||||
<div class="input-bd">
|
||||
<div class="input-name"><span>buy in: </span><input type="number" v-model="buyInSize"></div>
|
||||
<range :max="max"
|
||||
:min="min"
|
||||
v-model="buyInSize"
|
||||
@change="getBuyInSize"></range>
|
||||
</div>
|
||||
<div class="btn"><span @click="buyIn">buy in</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Watch, Vue } from 'vue-property-decorator';
|
||||
import range from './Range.vue';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
range,
|
||||
},
|
||||
})
|
||||
export default class BuyIn extends Vue {
|
||||
@Prop() private showBuyIn!: boolean;
|
||||
@Prop() private min!: number;
|
||||
@Prop() private max!: number;
|
||||
private buyInSize: number = 0;
|
||||
|
||||
@Watch('buyInSize')
|
||||
private wBuyInSize(val: number) {
|
||||
this.buyInSize = val > this.max ? this.max : val < this.min ? this.min : val;
|
||||
}
|
||||
|
||||
private getBuyInSize(val: string) {
|
||||
this.buyInSize = Number(val);
|
||||
}
|
||||
|
||||
private closeBuyIn() {
|
||||
this.$emit('update:showBuyIn', false);
|
||||
}
|
||||
|
||||
private async buyIn() {
|
||||
this.closeBuyIn();
|
||||
this.$emit('buyIn', this.buyInSize);
|
||||
}
|
||||
private mounted() {
|
||||
this.buyInSize = this.min;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.buy-in {
|
||||
position: fixed;
|
||||
z-index: 99;
|
||||
|
||||
.shadow {
|
||||
position: fixed;
|
||||
z-index: 9;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.buy-in-body {
|
||||
z-index: 99;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
margin: -100px -150px;
|
||||
width: 300px;
|
||||
border-radius: 12px;
|
||||
box-sizing: border-box;
|
||||
background: #fff;
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
.input-text {
|
||||
input {
|
||||
width: 100px;
|
||||
}
|
||||
}
|
||||
.input-name{
|
||||
margin-bottom: 15px;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
input{
|
||||
width: 50px;
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
.btn{
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -1,53 +1,163 @@
|
||||
<template>
|
||||
<div class="common-card-container">
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
<div class="container">
|
||||
<div class="common-card-container">
|
||||
<cardList :card-list="commonCardMap"
|
||||
:value-cards="valueCards"></cardList>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Vue} from 'vue-property-decorator';
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import cardList from './CardList.vue';
|
||||
|
||||
@Component
|
||||
export default class SitList extends Vue {
|
||||
@Prop() private msg!: string;
|
||||
@Prop() private currPlayer: any;
|
||||
private sitList: ISit[] = [];
|
||||
@Component({
|
||||
components: {
|
||||
cardList,
|
||||
},
|
||||
})
|
||||
export default class CommonCard extends Vue {
|
||||
@Prop() private commonCard: any;
|
||||
@Prop() private valueCards!: string[];
|
||||
|
||||
private sitDown(sit: ISit) {
|
||||
if (!sit.player) {
|
||||
sit.player = this.currPlayer;
|
||||
}
|
||||
}
|
||||
|
||||
private mounted() {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const sit = {
|
||||
position: i + 1,
|
||||
};
|
||||
this.sitList.push(sit);
|
||||
get commonCardMap() {
|
||||
const arr = [];
|
||||
if (this.commonCard.length !== 0) {
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (this.commonCard[i]) {
|
||||
arr.push(this.commonCard[i]);
|
||||
} else {
|
||||
arr.push('');
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
.common-card-container{
|
||||
<style scoped
|
||||
lang="less">
|
||||
.common-card-container {
|
||||
position: absolute;
|
||||
top: 50vh;
|
||||
left: 50%;
|
||||
margin: -35px -122px;
|
||||
i{
|
||||
background: url("../assets/poke.png");
|
||||
height: 237/3.5px;
|
||||
width: 155/3.5px;
|
||||
background-size: 100% 100%;
|
||||
display: inline-block;
|
||||
margin:0 2px;
|
||||
margin: -38px -114px;
|
||||
|
||||
.card {
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform-style: preserve-3d;
|
||||
opacity: 0;
|
||||
border-radius: 5px;
|
||||
|
||||
i {
|
||||
background: url("../assets/poke.png");
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
background-size: 100% 100%;
|
||||
transform: rotateY(0deg) translate3d(0px, 0px, 0px);
|
||||
backface-visibility: hidden;
|
||||
position: absolute;
|
||||
border-radius: 5px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-bg {
|
||||
/*background: url("../assets/poke-icon.png");*/
|
||||
background-size: 100% 100%;
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
transform: rotateY(180deg) translate3d(0px, 0px, 0px);
|
||||
backface-visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transform-style: preserve-3d;
|
||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
|
||||
|
||||
&.red {
|
||||
color: #e8050a;
|
||||
}
|
||||
|
||||
&.black {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.number {
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
z-index: -2;
|
||||
left: 5px;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.color {
|
||||
flex: 1;
|
||||
font-size: 28px;
|
||||
line-height: 60px;
|
||||
}
|
||||
}
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transition: left 1s;
|
||||
}
|
||||
|
||||
&.turn {
|
||||
animation: turnA 2s forwards;
|
||||
animation-delay: 2s;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
&.show {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
&.show {
|
||||
left: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
&.show {
|
||||
left: 44 * 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
&.show {
|
||||
left: 44 * 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
&.show {
|
||||
left: 44 * 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes turnA /* Safari 与 Chrome */ {
|
||||
from {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotateY(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<div class="audio-container">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Vue} from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class Emoji extends Vue {
|
||||
@Prop() private type!: string;
|
||||
@Prop() private show!: boolean;
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.audio-container {
|
||||
position: absolute;
|
||||
z-index: -99;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
+408
-101
@@ -1,100 +1,314 @@
|
||||
<template>
|
||||
<div class="sit-list-container">
|
||||
<div class="sit-list">
|
||||
<div class="item" v-for="(sit,key) in sitList" :key="key" @click="sitDown(key)">
|
||||
<div class="default"></div>
|
||||
<div class="player">
|
||||
<div class="user-name">test</div>
|
||||
<div class="icon"></div>
|
||||
<div class="counter">100</div>
|
||||
<div class="action-size">200</div>
|
||||
<div class="action-command">call</div>
|
||||
<div class="type">bb</div>
|
||||
<div class="hand-card"></div>
|
||||
<div
|
||||
class="sit"
|
||||
v-for="(sit, key) in sitList"
|
||||
:key="key"
|
||||
@click="sitDown(sit)"
|
||||
>
|
||||
<div class="default"
|
||||
v-show="!sit.player">
|
||||
<i>sit</i>
|
||||
</div>
|
||||
<div class="cards">
|
||||
<div class="hand-card"></div>
|
||||
<div class="card-style"></div>
|
||||
<div class="sit-player"
|
||||
v-if="sit.player">
|
||||
<div class="player"
|
||||
:class="{fold: sit.player.status === -1}">
|
||||
<div class="count-down"
|
||||
v-show="actionUserId === sit.player.userId">{{time}}
|
||||
</div>
|
||||
<div class="user-name"
|
||||
v-show="sit.player.nickName">
|
||||
{{ sit.player.nickName }}
|
||||
</div>
|
||||
<div class="icon iconfont icon-user-avatar"></div>
|
||||
<div class="counter"
|
||||
:class="{isAction: actionUserId === sit.player.userId,
|
||||
'close-time-out': time > 0 && time < 10 && actionUserId === sit.player.userId }"
|
||||
v-show="sit.player.counter || sit.player.actionCommand === 'allin'">
|
||||
{{ sit.player.counter }}
|
||||
</div>
|
||||
<div class="action-size"
|
||||
v-show="sit.player.actionSize > 0">
|
||||
{{ sit.player.actionSize }}
|
||||
</div>
|
||||
<div class="action-command"
|
||||
v-show="sit.player.actionCommand">
|
||||
{{ sit.player.actionCommand }}
|
||||
</div>
|
||||
<div class="type"
|
||||
v-show="sit.player.type">
|
||||
{{ sit.player.type }}
|
||||
</div>
|
||||
<div class="hand-card"
|
||||
v-show="!!!currPlayer || (sit.player.userId !== currPlayer.userId
|
||||
&& sit.player.handCard
|
||||
&& sit.player.handCard.length !== 0)">
|
||||
<cardList :cardList="sit.player.handCard"
|
||||
:valueCards="valueCards"></cardList>
|
||||
</div>
|
||||
<div class="card-style"
|
||||
v-show="!!!currPlayer || (sit.player.userId !== currPlayer.userId
|
||||
&& sit.player.handCard
|
||||
&& sit.player.handCard.length !== 0)">
|
||||
{{PokeStyle(sit.player.handCard)}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="cards"
|
||||
v-show="showHandCard(sit)">
|
||||
<div class="hand-card">
|
||||
<cardList :cardList="handCard"
|
||||
:valueCards="valueCards"></cardList>
|
||||
</div>
|
||||
<div class="ready"
|
||||
v-show="handCard && handCard.length === 0">ready
|
||||
</div>
|
||||
<div class="card-style"
|
||||
v-if="commonCard && commonCard.length > 0">{{PokeStyle()}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="win"
|
||||
v-show="sit.player.income">
|
||||
<!-- <span>win!</span>-->
|
||||
<span>{{`+${sit.player.income}`}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<BuyIn :showBuyIn.sync="showBuyIn"
|
||||
:min="0"
|
||||
:max="1000"
|
||||
@buyIn='buyIn'></BuyIn>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Vue} from 'vue-property-decorator';
|
||||
import {IUser} from '../../../server/src/interface/IUser';
|
||||
import { Component, Prop, Watch, Vue } from 'vue-property-decorator';
|
||||
import { IPlayer } from '@/interface/IPlayer';
|
||||
import { ILinkNode } from '@/utils/Link';
|
||||
import ISit from '@/interface/ISit';
|
||||
import cardList from './CardList.vue';
|
||||
import BuyIn from '@/components/BuyIn.vue';
|
||||
import { PokerStyle } from '@/utils/PokerStyle';
|
||||
import map from '../utils/map';
|
||||
import {IRoom} from '@/interface/IRoom';
|
||||
|
||||
interface ISit {
|
||||
player?: IUser;
|
||||
position: number;
|
||||
}
|
||||
|
||||
@Component
|
||||
@Component({
|
||||
components: {
|
||||
cardList,
|
||||
BuyIn,
|
||||
},
|
||||
})
|
||||
export default class SitList extends Vue {
|
||||
@Prop() private msg!: string;
|
||||
@Prop() private currPlayer: any;
|
||||
private sitList: ISit[] = [];
|
||||
@Prop() private currPlayer!: IPlayer;
|
||||
@Prop() private commonCard!: string[];
|
||||
@Prop() private sitLink!: ILinkNode<ISit>;
|
||||
@Prop() private handCard!: string[];
|
||||
@Prop() private winner!: IPlayer[][];
|
||||
@Prop() private isPlay!: boolean;
|
||||
@Prop() private roomConfig!: IRoom;
|
||||
@Prop() private actionUserId!: string;
|
||||
@Prop() private valueCards!: string;
|
||||
@Prop({ default: 30, type: Number }) private time!: number;
|
||||
|
||||
private sitLinkNode: any = '';
|
||||
private showBuyIn = false;
|
||||
private currSit!: ISit;
|
||||
|
||||
@Watch('sitLink')
|
||||
private getSit(val: ILinkNode<ISit>) {
|
||||
this.sitLinkNode = val;
|
||||
}
|
||||
|
||||
private buyIn(size: number) {
|
||||
console.log('ccc');
|
||||
this.showBuyIn = false;
|
||||
this.currPlayer.counter += size;
|
||||
this.$emit('buyIn', Number(size));
|
||||
this.sitDown(this.currSit);
|
||||
}
|
||||
|
||||
private showHandCard(sit: ISit) {
|
||||
return sit.player?.userId === this.currPlayer?.userId;
|
||||
}
|
||||
|
||||
private PokeStyle(cards: string[]) {
|
||||
if (this.commonCard.length === 0) {
|
||||
return '';
|
||||
}
|
||||
const commonCard = this.commonCard || [];
|
||||
let handCard = this.handCard || [];
|
||||
if (cards) {
|
||||
handCard = cards;
|
||||
}
|
||||
const card = [...handCard, ...commonCard];
|
||||
const style = new PokerStyle(card, this.roomConfig.isShort);
|
||||
return style.getPokerStyleName();
|
||||
}
|
||||
|
||||
get handCardString() {
|
||||
return this.mapCard(this.handCard);
|
||||
}
|
||||
|
||||
get hasSit() {
|
||||
return !!this.sitList.find((s) => s.player && s.player.userId === this.currPlayer?.userId);
|
||||
}
|
||||
|
||||
private mapCard(cards: string[]) {
|
||||
return map(cards);
|
||||
}
|
||||
|
||||
private sitDown(sit: ISit) {
|
||||
if (!sit.player) {
|
||||
sit.player = this.currPlayer;
|
||||
if (!sit.player && (!this.isPlay || !this.hasSit)) {
|
||||
if (this.currPlayer.counter <= 0) {
|
||||
this.showBuyIn = true;
|
||||
this.currSit = sit;
|
||||
return;
|
||||
}
|
||||
let sitNode = this.sitLinkNode;
|
||||
for (let i = 0; i < 9; i++) {
|
||||
if (sitNode) {
|
||||
const next = sitNode.next;
|
||||
if (sitNode.node.player?.nickName === this.currPlayer?.nickName) {
|
||||
delete sitNode.node.player;
|
||||
}
|
||||
sitNode = next as ILinkNode<ISit>;
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < 9; i++) {
|
||||
if (sitNode) {
|
||||
const next = sitNode.next;
|
||||
if (sit.position === sitNode.node.position) {
|
||||
sitNode.node.player = this.currPlayer as IPlayer;
|
||||
this.$emit('update:sitLink', sitNode);
|
||||
this.$emit('sit', sitNode);
|
||||
break;
|
||||
}
|
||||
sitNode = next as ILinkNode<ISit>;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private mounted() {
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const sit = {
|
||||
position: i + 1,
|
||||
};
|
||||
this.sitList.push(sit);
|
||||
get sitList() {
|
||||
const sitMap: ISit[] = [];
|
||||
if (this.sitLinkNode) {
|
||||
let link = this.sitLinkNode;
|
||||
for (let i = 0; i < 9; i++) {
|
||||
if (
|
||||
link.node.player &&
|
||||
link.node.player.userId === this.currPlayer?.userId
|
||||
) {
|
||||
this.sitLinkNode = link;
|
||||
break;
|
||||
}
|
||||
const next = link.next;
|
||||
link = next as ILinkNode<ISit>;
|
||||
}
|
||||
let sitNode = this.sitLinkNode;
|
||||
for (let i = 0; i < 9; i++) {
|
||||
const next = sitNode.next;
|
||||
sitMap.push(sitNode.node);
|
||||
sitNode = next as ILinkNode<ISit>;
|
||||
}
|
||||
console.log('sit', sitMap);
|
||||
return sitMap;
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
private mounted() {
|
||||
this.sitLinkNode = this.sitLink;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
<style scoped
|
||||
lang="less">
|
||||
.sit-list-container {
|
||||
display: flex;
|
||||
flex-direction: row-reverse;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
|
||||
.sit-list {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
height: 620px;
|
||||
height: 620 / 6.67vh;
|
||||
padding: 10px;
|
||||
margin:0 15px;
|
||||
margin: 0 15px;
|
||||
box-sizing: border-box;
|
||||
.item {
|
||||
|
||||
.sit {
|
||||
position: absolute;
|
||||
font-size: 12px;
|
||||
.player{
|
||||
position: relative;
|
||||
.icon{
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
background: url("../assets/poke-icon.png") #fff;
|
||||
background-size: 100% 100%;
|
||||
border-radius: 2px;
|
||||
|
||||
.default {
|
||||
i {
|
||||
width: 45 / 3.75vw;
|
||||
height: 45 / 3.75vw;
|
||||
border-radius: 50%;
|
||||
border: 1px solid #bababa;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
.user-name{
|
||||
display: block;
|
||||
font-style: normal;
|
||||
font-size: 20px;
|
||||
line-height: 45 / 3.75vw;
|
||||
color: #fff;
|
||||
}
|
||||
.counter{
|
||||
background-color: rgba(0,0,0,0.8);
|
||||
}
|
||||
|
||||
.player {
|
||||
position: relative;
|
||||
|
||||
.icon {
|
||||
width: 45 / 3.75vw;
|
||||
height: 45 / 3.75vw;
|
||||
font-size: 45px;
|
||||
line-height: 45 / 3.75vw;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.count-down {
|
||||
height: 7vh;
|
||||
line-height: 9vh;
|
||||
width: 12vw;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 14px;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.3), transparent);
|
||||
}
|
||||
|
||||
.counter {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
border-radius: 2px;
|
||||
|
||||
&.isAction {
|
||||
box-shadow: 0px 0px 6px 4px;
|
||||
}
|
||||
|
||||
&.close-time-out {
|
||||
animation: 300ms timeOut infinite;
|
||||
}
|
||||
}
|
||||
.action-command{
|
||||
top: 15px;
|
||||
left: 45px;
|
||||
|
||||
.action-command {
|
||||
top: 15 / 6.67vh;
|
||||
left: 45 / 3.75vw;
|
||||
padding: 1px 8px;
|
||||
border-radius: 9px;
|
||||
color: #ffffff;
|
||||
@@ -102,102 +316,195 @@
|
||||
text-shadow: 1px 2px 3px rgba(0, 0, 0, 0.3);
|
||||
position: absolute;
|
||||
}
|
||||
.type{
|
||||
|
||||
.card-style {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.type {
|
||||
background-color: #fff;
|
||||
color: #2b2b2b;
|
||||
border-radius: 50%;
|
||||
padding: 2px;
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
line-height: 18px;
|
||||
width: 15 / 3.75vw;
|
||||
height: 15px;
|
||||
line-height: 16px;
|
||||
position: absolute;
|
||||
top: 53px;
|
||||
left: 38px;
|
||||
top: 53 / 6.67vh;
|
||||
left: 38 / 3.75vw;
|
||||
font-size: 12px;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
.action-size{
|
||||
background-color: rgba(0, 0, 0, 0.3);
|
||||
|
||||
.action-size {
|
||||
background: rgba(0, 0, 0, 0.3) url("../assets/gold.svg") center left no-repeat;
|
||||
background-size: contain;
|
||||
border-radius: 2px;
|
||||
padding:1px 4px;
|
||||
padding: 1px 4px 1px 12px;
|
||||
text-align: center;
|
||||
min-width: 35px;
|
||||
min-width: 35 / 3.75vw;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
position: absolute;
|
||||
top: 35px;
|
||||
left: 40px;
|
||||
top: 35 / 6.67vh;
|
||||
left: 40 / 3.75vw;
|
||||
}
|
||||
|
||||
&.fold {
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.hand-card {
|
||||
position: absolute;
|
||||
top: 1vh;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
left: 75px;
|
||||
top: 0;
|
||||
left: 100 / 3.75vw;
|
||||
top: 460 / 6.67vh;
|
||||
|
||||
.action-command {
|
||||
left: -22 / 3.75vw;
|
||||
}
|
||||
|
||||
.type {
|
||||
left: -16 / 3.75vw;
|
||||
}
|
||||
|
||||
.action-size {
|
||||
top: -5 / 6.67vh;
|
||||
left: 57 / 3.75vw;
|
||||
padding-right: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
left: 240px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
top: 330 / 6.67vh;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
left: 296px;
|
||||
top: 100px;
|
||||
left: 0;
|
||||
top: 210 / 6.67vh;
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
left: 296px;
|
||||
top: 200px;
|
||||
left: 0;
|
||||
top: 100 / 6.67vh;
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
left: 296px;
|
||||
top: 330px;
|
||||
left: 75 / 3.75vw;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:nth-child(6) {
|
||||
left: 100px;
|
||||
top: 460px;
|
||||
.action-command{
|
||||
left: -22px;
|
||||
}
|
||||
.type{
|
||||
left: -16px;
|
||||
}
|
||||
.action-size{
|
||||
top: -5px;
|
||||
left: 57px;
|
||||
padding-right: 15px;
|
||||
text-align: right;
|
||||
}
|
||||
left: 240 / 3.75vw;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
&:nth-child(7) {
|
||||
left: 0;
|
||||
top: 330px;
|
||||
left: 296 / 3.75vw;
|
||||
top: 100 / 6.67vh;
|
||||
}
|
||||
|
||||
&:nth-child(8) {
|
||||
left: 0;
|
||||
top: 200px;
|
||||
left: 296 / 3.75vw;
|
||||
top: 210 / 6.67vh;
|
||||
}
|
||||
|
||||
&:nth-child(9) {
|
||||
left: 0;
|
||||
top: 100px;
|
||||
left: 296 / 3.75vw;
|
||||
top: 330 / 6.67vh;
|
||||
}
|
||||
&:nth-child(2),&:nth-child(3),&:nth-child(4),&:nth-child(5){
|
||||
.action-command{
|
||||
left: -22px;
|
||||
|
||||
&:nth-child(6),
|
||||
&:nth-child(7),
|
||||
&:nth-child(8),
|
||||
&:nth-child(9) {
|
||||
.action-command {
|
||||
left: -22 / 3.75vw;
|
||||
}
|
||||
.type{
|
||||
left: -16px;
|
||||
|
||||
.type {
|
||||
left: -16 / 3.75vw;
|
||||
}
|
||||
.action-size{
|
||||
left: -40px;
|
||||
padding-right: 15px;
|
||||
|
||||
.action-size {
|
||||
background-position: right;
|
||||
left: -40 / 3.75vw;
|
||||
padding-left: 1px;
|
||||
padding-right: 17px;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.hand-card {
|
||||
left: -3vh;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.cards {
|
||||
position: absolute;
|
||||
left: 52 / 3.75vw;
|
||||
top: 20 / 6.67vh;
|
||||
min-width: 60 / 3.75vw;
|
||||
min-height: 60 / 6.67vh;
|
||||
line-height: 60 / 6.67vh;
|
||||
|
||||
.ready {
|
||||
font-size: 14px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.card-style {
|
||||
position: absolute;
|
||||
color: #fff;
|
||||
font-size: 14px;
|
||||
bottom: -48px;
|
||||
width: 60 / 3.75vw;
|
||||
text-align: center;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
|
||||
.win {
|
||||
position: absolute;
|
||||
z-index: 8;
|
||||
left: 0;
|
||||
top: 4vh;
|
||||
font-size: 20px;
|
||||
color: rgba(255, 209, 0, 0.99);
|
||||
font-weight: 600;
|
||||
animation: fadeOut 4s forwards;
|
||||
background-image: linear-gradient(to top, rgba(0, 0, 0, 0.1), rgba(0, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeOut /* Safari 与 Chrome */ {
|
||||
0% {
|
||||
transform: translate3d(2px, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
30% {
|
||||
transform: translate3d(2px, 0, 0);
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
transform: translate3d(2px, -15px, 0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes timeOut /* Safari 与 Chrome */ {
|
||||
0% {
|
||||
box-shadow: none;
|
||||
}
|
||||
100% {
|
||||
box-shadow: 0px 0px 6px 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<div class="input-container">
|
||||
<div class="user-name input-bd"
|
||||
:class="{ move: focus || value !== '', focus: focus, error: error }">
|
||||
<div class="input-name">{{text}}</div>
|
||||
<div class="input-text">
|
||||
<input :type="type"
|
||||
@focus="onFocus"
|
||||
@blur="focus = false"
|
||||
v-model="changeValue"/>
|
||||
<i class="iconfont icon-close close"
|
||||
v-show="value !== ''"
|
||||
@click="clear"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class XInput extends Vue {
|
||||
@Prop({ default: '', type: String }) private value!: string;
|
||||
@Prop({ default: '', type: String }) private text!: string;
|
||||
@Prop({ default: 'text', type: String }) private type!: string;
|
||||
@Prop({ default: false, type: Boolean }) private error!: boolean;
|
||||
|
||||
private focus = false;
|
||||
|
||||
get changeValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
set changeValue(val: string) {
|
||||
this.$emit('input', val);
|
||||
this.$emit('change', val);
|
||||
}
|
||||
|
||||
private clear() {
|
||||
this.$emit('input', '');
|
||||
}
|
||||
|
||||
private onFocus() {
|
||||
this.focus = true;
|
||||
this.$emit('focus');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.input-container {
|
||||
.input-name {
|
||||
top: 12px;
|
||||
left: 10px;
|
||||
text-align: left;
|
||||
padding-left: 2px;
|
||||
position: absolute;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
transition: 300ms transform;
|
||||
z-index: 0;
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.input-text {
|
||||
position: relative;
|
||||
display: block;
|
||||
padding: 2px;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
|
||||
input {
|
||||
width: 80vw;
|
||||
height: 20px;
|
||||
padding: 5px 10px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
line-height: 20px;
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.input-bd {
|
||||
margin: 4vw 0;
|
||||
border: 1px solid #bababa;
|
||||
border-radius: 4px;
|
||||
text-align: left;
|
||||
line-height: 40px;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.move {
|
||||
.input-name {
|
||||
transform: translate3d(-10px, -22px, 0px) scale(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
.focus {
|
||||
border: 1px solid #00976e;
|
||||
|
||||
.input-name {
|
||||
color: #00976e;
|
||||
}
|
||||
}
|
||||
|
||||
.error {
|
||||
border: 1px solid #e8050a;
|
||||
|
||||
.input-name {
|
||||
color: #e8050a;
|
||||
}
|
||||
}
|
||||
|
||||
.close {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
line-height: 30px;
|
||||
text-align: center;
|
||||
z-index: 9;
|
||||
right: 0;
|
||||
top: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div class="audio-container">
|
||||
<audio ref="click" controls>
|
||||
<source src="../assets/mp3/click.mp3" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<audio ref="raise" controls>
|
||||
<source src="../assets/mp3/raise.mp3" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<audio ref="fold" controls>
|
||||
<source src="../assets/mp3/fold.mp3" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
<audio ref="income" controls>
|
||||
<source src="../assets/mp3/income.mp3" type="audio/mpeg">
|
||||
Your browser does not support the audio element.
|
||||
</audio>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Vue, Watch} from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class Audio extends Vue {
|
||||
@Prop() private type!: string;
|
||||
@Prop() private play!: boolean;
|
||||
@Watch('play')
|
||||
private wPlay(val: boolean) {
|
||||
if (val) {
|
||||
(this.$refs[this.type] as HTMLAudioElement).play();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.audio-container {
|
||||
position: absolute;
|
||||
z-index: -99;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<div class="card-container">
|
||||
<div
|
||||
class="card"
|
||||
v-for="(card, key) in cardList"
|
||||
v-bind:class="{ show: show, turn: show && card !== '' }"
|
||||
>
|
||||
<i></i>
|
||||
<span class="card-bg red"
|
||||
:class="{ black : isBlack(map(card)[1])}">
|
||||
<div class="shadow"
|
||||
v-show="shadow(card)"></div>
|
||||
<b class="number">{{ map(card)[0] }}</b>
|
||||
<b class="color">{{ map(card)[1] }}</b>
|
||||
<b class="color big">{{ map(card)[1] }}</b>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import { mapCard } from '@/utils/map';
|
||||
|
||||
@Component
|
||||
export default class Card extends Vue {
|
||||
@Prop() private cardList: any;
|
||||
@Prop({ default: () => [], type: Array }) private valueCards!: string[];
|
||||
|
||||
get show() {
|
||||
return this.cardList.length !== 0;
|
||||
}
|
||||
|
||||
private isBlack(type: string) {
|
||||
return type === '♠' || type === '♣';
|
||||
}
|
||||
|
||||
private map(card: string) {
|
||||
return mapCard(card);
|
||||
}
|
||||
|
||||
private shadow(card: string) {
|
||||
if (this.valueCards.length === 0 || card === '') {
|
||||
return false;
|
||||
}
|
||||
return this.valueCards.indexOf(card) < 0;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.card-container {
|
||||
.card {
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
transform-style: preserve-3d;
|
||||
opacity: 0;
|
||||
border-radius: 5px;
|
||||
z-index: 0;
|
||||
|
||||
i {
|
||||
background: url("../assets/poke.png");
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
background-size: 100% 100%;
|
||||
transform: rotateY(0deg) translate3d(0px, 0px, 0px);
|
||||
backface-visibility: hidden;
|
||||
position: absolute;
|
||||
border-radius: 5px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.card-bg {
|
||||
/*background: url("../assets/poke-icon.png");*/
|
||||
background-size: 100% 100%;
|
||||
height: 60px;
|
||||
width: 40px;
|
||||
border-radius: 5px;
|
||||
background-color: #fff;
|
||||
transform: rotateY(180deg) translate3d(0px, 0px, 0px);
|
||||
backface-visibility: hidden;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
z-index: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transform-style: preserve-3d;
|
||||
box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.3);
|
||||
|
||||
.shadow {
|
||||
width: 40px;
|
||||
height: 60px;
|
||||
left: 0;
|
||||
top: 0;
|
||||
border-radius: 5px;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
&.red {
|
||||
color: #e8050a;
|
||||
}
|
||||
|
||||
&.black {
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.number {
|
||||
text-align: left;
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
font-size: 16px;
|
||||
line-height: 25px;
|
||||
font-family: initial;
|
||||
}
|
||||
|
||||
.color {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: -2px;
|
||||
font-size: 20px;
|
||||
line-height: 60px;
|
||||
font-family: Arial;
|
||||
&.big {
|
||||
left: 15px;
|
||||
font-size: 35px;
|
||||
top: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.show {
|
||||
display: block;
|
||||
opacity: 1;
|
||||
transition: left 1s;
|
||||
}
|
||||
|
||||
&.turn {
|
||||
animation: turnA 1s forwards;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
|
||||
&:nth-child(1) {
|
||||
&.show {
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
&.show {
|
||||
left: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
&.show {
|
||||
left: 44 * 2px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(4) {
|
||||
&.show {
|
||||
left: 44 * 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&:nth-child(5) {
|
||||
&.show {
|
||||
left: 44 * 4px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes turnA /* Safari 与 Chrome */ {
|
||||
from {
|
||||
transform: rotateY(0deg);
|
||||
}
|
||||
to {
|
||||
transform: rotateY(-180deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,236 @@
|
||||
<template>
|
||||
<div class="record-container" :class="{show:show}">
|
||||
<div class="shadow"
|
||||
@click="show = false"></div>
|
||||
<div class="body">
|
||||
<div class="title">record</div>
|
||||
<div class="record-context">
|
||||
<ul class = 'td'>
|
||||
<div class="lo">
|
||||
<span class="player">player</span>
|
||||
<i>commonCard</i>
|
||||
<span class="pot">pot</span>
|
||||
</div>
|
||||
</ul>
|
||||
<ul class="record-box">
|
||||
<li v-for="player in commandList">
|
||||
<div class="player">
|
||||
<Player :player="player" :is-small="true"></Player>
|
||||
</div>
|
||||
<div class="commandCard">
|
||||
<cardList :card-list="commonCardMap(player.commonCard)"
|
||||
:value-cards="valueCard"
|
||||
></cardList>
|
||||
</div>
|
||||
<div class="pot">
|
||||
<span>{{player.pot}}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="record-btn">
|
||||
<i class="iconfont icon-arrow" :class="{ disable: currGameIndex === 1 }" @click="getRecord(-1)"></i>
|
||||
<span>{{currGameIndex}}</span>
|
||||
<i class="iconfont icon-arrow right" :class="{ disable: currGameIndex === maxIndex }" @click="getRecord(1)"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import { IPlayer } from '@/interface/IPlayer';
|
||||
import Player from './Player.vue';
|
||||
import CardList from '@/components/CardList.vue';
|
||||
import { IGameRecord } from '@/interface/IGameRecord';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
CardList,
|
||||
Player,
|
||||
},
|
||||
})
|
||||
export default class Record extends Vue {
|
||||
@Prop() private value!: boolean;
|
||||
@Prop() private gameList!: IGameRecord [];
|
||||
@Prop() private commandList!: IPlayer[];
|
||||
@Prop() private currGameIndex!: number;
|
||||
|
||||
private valueCard = [];
|
||||
|
||||
get show() {
|
||||
return this.value;
|
||||
}
|
||||
set show(val) {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
get maxIndex() {
|
||||
return this.gameList.length;
|
||||
}
|
||||
|
||||
private getRecord(type: number) {
|
||||
const index = this.currGameIndex + type;
|
||||
if (index > this.maxIndex || index <= 0) {
|
||||
return;
|
||||
}
|
||||
this.$emit('getRecord', index);
|
||||
}
|
||||
private commonCardMap(commonCard: string) {
|
||||
const commonCardArr = commonCard.split(',');
|
||||
const arr = [];
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (commonCardArr[i]) {
|
||||
arr.push(commonCardArr[i]);
|
||||
} else {
|
||||
arr.push('');
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.record-container {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
display: none;
|
||||
&.show{
|
||||
display: block;
|
||||
.body{
|
||||
animation: 0.3s move forwards;
|
||||
}
|
||||
}
|
||||
.shadow {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.body {
|
||||
width: 90vw;
|
||||
height: 100vh;
|
||||
color: #fff;
|
||||
background: #006a55;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
overflow: hidden;
|
||||
transform: translate3d(100vw, 0, 0);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
.record-context{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
flex: 1;
|
||||
.record-box{
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
line-height: 30px;
|
||||
height: 30px;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
.td{
|
||||
height:30px;
|
||||
}
|
||||
|
||||
ul {
|
||||
.pot{
|
||||
width: 10vw;
|
||||
font-size: 11px;
|
||||
line-height: 58px;
|
||||
span{
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
.player{
|
||||
width: 16vw;
|
||||
}
|
||||
.lo {
|
||||
display: flex;
|
||||
i {
|
||||
flex: 1;
|
||||
padding: 5px 10px;
|
||||
line-height: 20px;
|
||||
display: inline-block;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
span {
|
||||
padding: 5px 10px;
|
||||
line-height: 20px;
|
||||
display: inline-block;
|
||||
font-style: normal;
|
||||
font-size: 14px;
|
||||
}
|
||||
.pot{
|
||||
line-height: 18px;
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
li{
|
||||
padding: 0 6px;
|
||||
display: flex;
|
||||
height: 90px;
|
||||
.commandCard{
|
||||
flex: 1;
|
||||
position: relative;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
.record-btn{
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
i{
|
||||
transform: rotate(90deg);
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
font-size: 40px;
|
||||
&.right{
|
||||
transform: rotate(270deg);
|
||||
}
|
||||
&.disable{
|
||||
opacity: .4;
|
||||
}
|
||||
}
|
||||
span{
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes move /* Safari 与 Chrome */ {
|
||||
0% {
|
||||
transform: translate3d(100vw,0,0);
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(0, 0px, 0px);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<div class="notice-container">
|
||||
<div class="notice-body">
|
||||
<i v-for="message in messageList"
|
||||
v-if="message !== ''"
|
||||
:style="{top: `${message.top}vh`}"
|
||||
>{{message.message}}</i>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import {Component, Prop, Watch, Vue} from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class Notice extends Vue {
|
||||
@Prop() private messageList!: any[];
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.notice-container {
|
||||
.notice-body{
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
i{
|
||||
position: absolute;
|
||||
top: 20px;
|
||||
left: 0;
|
||||
transform: translate3d(100vw,0,0);
|
||||
z-index: 10;
|
||||
animation: 4s move linear forwards;
|
||||
color: #fff;
|
||||
padding: 4px;
|
||||
font-size: 12px;
|
||||
font-style: normal;
|
||||
border-radius: 2px;
|
||||
background-color: rgba(0,0,0,0.4);
|
||||
}
|
||||
}
|
||||
@-webkit-keyframes move /* Safari 与 Chrome */ {
|
||||
0% {
|
||||
transform: translate3d(100vw,0,0);
|
||||
}
|
||||
99%{
|
||||
transform: translate3d(-198px, 0px, 0px);
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(-200px, 0px, 0px);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,176 @@
|
||||
<template>
|
||||
<div class="sit-container">
|
||||
<div class="sit-player"
|
||||
v-if="player" :class="{ small: isSmall }">
|
||||
<div class="player"
|
||||
:class="{fold: player.status === -1}">
|
||||
<div class="user-name"
|
||||
v-show="player.nickName">
|
||||
{{ player.nickName }}
|
||||
</div>
|
||||
<div class="icon iconfont icon-user-avatar"></div>
|
||||
<div class="counter"
|
||||
v-show="player.counter || player.command === 'allin'">
|
||||
{{ player.counter }}
|
||||
</div>
|
||||
<div class="action-size"
|
||||
v-show="player.actionSize > 0">
|
||||
{{ player.actionSize }}
|
||||
</div>
|
||||
<div class="action-command"
|
||||
v-show="player.command">
|
||||
{{ player.command }}
|
||||
</div>
|
||||
<div class="type"
|
||||
v-show="player.type">
|
||||
{{ player.type }}
|
||||
</div>
|
||||
<div class="hand-card"
|
||||
v-show="player.handCard !== ''">
|
||||
|
||||
<cardList :cardList="player.handCard.split(',')"></cardList>
|
||||
</div>
|
||||
<div class="card-style"
|
||||
v-show="player.handCard !== '' && player.commonCard !== ''">
|
||||
{{PokeStyle(player.handCard, player.commonCard)}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import cardList from './CardList.vue';
|
||||
import { PokerStyle } from '@/utils/PokerStyle';
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
cardList,
|
||||
},
|
||||
})
|
||||
export default class Player extends Vue {
|
||||
@Prop() private player!: any;
|
||||
@Prop() private isSmall!: boolean;
|
||||
|
||||
private PokeStyle(cards: string, commonCard: string) {
|
||||
if (commonCard === '' || cards === '') {
|
||||
return '';
|
||||
}
|
||||
const commonCardArr = commonCard.split(',');
|
||||
const cardsArr = cards.split(',');
|
||||
const card = [...cardsArr, ...commonCardArr];
|
||||
const style = new PokerStyle(card);
|
||||
return style.getPokerStyleName();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
.sit-container {
|
||||
.small{
|
||||
transform: scale(0.9);
|
||||
}
|
||||
.player {
|
||||
position: relative;
|
||||
font-size: 14px;
|
||||
width: 50 / 3.75vw;
|
||||
.icon {
|
||||
width: 45 / 3.75vw;
|
||||
height: 45 / 3.75vw;
|
||||
font-size: 45px;
|
||||
line-height: 45 / 3.75vw;
|
||||
border-radius: 50%;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.user-name {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.count-down {
|
||||
height: 7vh;
|
||||
line-height: 9vh;
|
||||
width: 12vw;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 14px;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
font-size: 20px;
|
||||
background-image: linear-gradient(0deg, rgba(0, 0, 0, 0.3), transparent);
|
||||
}
|
||||
|
||||
.counter {
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
border-radius: 2px;
|
||||
|
||||
&.isAction {
|
||||
box-shadow: 0px 0px 6px 4px;
|
||||
}
|
||||
|
||||
&.close-time-out {
|
||||
animation: 300ms timeOut infinite;
|
||||
}
|
||||
}
|
||||
|
||||
.action-command {
|
||||
top: 15 / 6.67vh;
|
||||
left: 45 / 3.75vw;
|
||||
padding: 1px 8px;
|
||||
border-radius: 9px;
|
||||
color: #ffffff;
|
||||
background-color: #2c3e50;
|
||||
text-shadow: 1px 2px 3px rgba(0, 0, 0, 0.3);
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.card-style {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.type {
|
||||
background-color: #fff;
|
||||
color: #2b2b2b;
|
||||
border-radius: 50%;
|
||||
padding: 2px;
|
||||
width: 15 / 3.75vw;
|
||||
height: 15px;
|
||||
line-height: 16px;
|
||||
position: absolute;
|
||||
top: 53 / 6.67vh;
|
||||
left: 38 / 3.75vw;
|
||||
font-size: 12px;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
|
||||
.action-size {
|
||||
background: rgba(0, 0, 0, 0.3) url("../assets/gold.svg") center left no-repeat;
|
||||
background-size: contain;
|
||||
border-radius: 2px;
|
||||
padding: 1px 4px 1px 12px;
|
||||
text-align: center;
|
||||
min-width: 35 / 3.75vw;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
position: absolute;
|
||||
top: 35 / 6.67vh;
|
||||
left: 40 / 3.75vw;
|
||||
}
|
||||
|
||||
&.fold {
|
||||
opacity: 0.4;
|
||||
}
|
||||
.hand-card{
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 2vh;
|
||||
transform: scale(0.7);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<div class="slide-bar-container">
|
||||
<!-- <div class="value">{{raiseSize}}</div>-->
|
||||
<div class="range-body">
|
||||
<input type="range"
|
||||
v-model="rangeSize"
|
||||
|
||||
:class="{horizontal: !!isHorizontal}">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class Range extends Vue {
|
||||
@Prop({ type: Number, default: 1000 }) private max!: number;
|
||||
@Prop({ type: Number, default: 100 }) private min!: number;
|
||||
@Prop() private value!: any;
|
||||
@Prop({ type: Boolean, default: false }) private isHorizontal!: boolean;
|
||||
private rangeRound = (this.max - this.min) / 100;
|
||||
|
||||
get rangeSize() {
|
||||
const valNum = Number(this.value);
|
||||
const size = valNum >= this.max ? this.max / this.rangeRound :
|
||||
valNum < this.min ? 0 : (valNum - this.min) / this.rangeRound;
|
||||
return size;
|
||||
}
|
||||
|
||||
set rangeSize(val) {
|
||||
const valNum = Number(val);
|
||||
const size = Number(val) === 0 ? this.min : Math.floor(valNum / 100 * (this.max - this.min)) +
|
||||
this.min;
|
||||
console.log('size', size);
|
||||
this.$emit('change', size);
|
||||
this.$emit('input', size);
|
||||
}
|
||||
|
||||
// @Watch('range')
|
||||
// private raiseSize(val: string) {
|
||||
// const valNum = Number(val);
|
||||
// const size = Number(val) === 0 ? this.min : Math.floor(valNum / 100 * (this.max - this.min)) +
|
||||
// this.min;
|
||||
// console.log('size', size);
|
||||
// this.$emit('change', size);
|
||||
// }
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.slide-bar-container {
|
||||
.range-body {
|
||||
line-height: 10px;
|
||||
}
|
||||
|
||||
.value {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
input[type=range] {
|
||||
-webkit-appearance: none;
|
||||
width: 200px;
|
||||
border-radius: 10px; /*这个属性设置使填充进度条时的图形为圆角*/
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
||||
&.horizontal {
|
||||
transform: rotateZ(-90deg) translate3d(-50%, 0, 0);
|
||||
transform-origin: center;
|
||||
margin-left: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
input[type=range]:focus {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
input[type=range]::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
margin-top: -12px; /*使滑块超出轨道部分的偏移量相等*/
|
||||
background: #ffffff;
|
||||
border-radius: 50%; /*外观设置为圆形*/
|
||||
border: solid 0.125em rgba(205, 224, 230, 0.5); /*设置边框*/
|
||||
box-shadow: 0 .125em .125em #3b4547; /*添加底部阴影*/
|
||||
}
|
||||
|
||||
input[type=range]::-webkit-slider-runnable-track {
|
||||
height: 6px;
|
||||
border-radius: 10px; /*将轨道设为圆角的*/
|
||||
box-shadow: 0 1px 1px #def3f8, inset 0 .125em .125em #0d1112; /*轨道内置阴影效果*/
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,101 @@
|
||||
<template>
|
||||
<div class="record-container"
|
||||
v-show="show">
|
||||
<div class="shadow"
|
||||
@click="show = false"></div>
|
||||
<div class="body">
|
||||
<div class="title">record</div>
|
||||
<ul>
|
||||
<li>
|
||||
<i>nickName</i>
|
||||
<i>buy in</i>
|
||||
<i>counter</i>
|
||||
<i>income</i>
|
||||
</li>
|
||||
<li v-for="player in players">
|
||||
<i>{{player.nickName}}</i>
|
||||
<i>{{player.buyIn}}</i>
|
||||
<i>{{player.counter}}</i>
|
||||
<i>{{player.counter - player.buyIn}}</i>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Vue } from 'vue-property-decorator';
|
||||
import { IPlayer } from '@/interface/IPlayer';
|
||||
|
||||
@Component({
|
||||
components: {},
|
||||
})
|
||||
export default class Record extends Vue {
|
||||
@Prop() private value!: boolean;
|
||||
@Prop() private players!: IPlayer[];
|
||||
|
||||
get show() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
set show(val) {
|
||||
this.$emit('input', val);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.record-container {
|
||||
width: 80vw;
|
||||
height: 100vh;
|
||||
color: #fff;
|
||||
background: #2a2a2a;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 9999;
|
||||
|
||||
.shadow {
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
left: 0;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
position: fixed;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.body {
|
||||
position: relative;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.title {
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
line-height: 30px;
|
||||
padding: 5px 10px;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
ul {
|
||||
li {
|
||||
display: flex;
|
||||
|
||||
i {
|
||||
flex: 1;
|
||||
padding: 5px 10px;
|
||||
font-size: 16px;
|
||||
line-height: 20px;
|
||||
display: inline-block;
|
||||
font-style: normal;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,80 @@
|
||||
<template>
|
||||
<div class="send-msg-container">
|
||||
<div class="send-msg-body">
|
||||
<div class="msg-name iconfont icon-msg"></div>
|
||||
<div class="msg-input">
|
||||
<input type="text"
|
||||
v-model='msg'>
|
||||
</div>
|
||||
<div class="msg-btn btn"
|
||||
@click="send"><span>send</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Watch, Vue } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class SendMsg extends Vue {
|
||||
private msg: string = '';
|
||||
|
||||
private send() {
|
||||
if (this.msg !== '') {
|
||||
this.$emit('send', this.msg);
|
||||
this.msg = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.send-msg-container {
|
||||
position: fixed;
|
||||
.send-msg-body {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 25px;
|
||||
padding: 10px 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: #fff;
|
||||
font-size: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.msg-name {
|
||||
width: 40px;
|
||||
font-size: 30px;
|
||||
color: #009870;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.msg-input {
|
||||
flex: 1;
|
||||
border: 1px solid #bababa;
|
||||
text-align: left;
|
||||
|
||||
input {
|
||||
height: 20px;
|
||||
width: 90%;
|
||||
padding: 0 5px;
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
.msg-btn {
|
||||
width: 80px;
|
||||
margin-top: 0;
|
||||
margin-left: 0;
|
||||
text-align: center;
|
||||
|
||||
span {
|
||||
padding: 5px 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,62 @@
|
||||
<template>
|
||||
<div class="toast-container">
|
||||
<div class="toast-body"
|
||||
v-show="showValue">
|
||||
{{text}}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Component, Prop, Watch, Vue } from 'vue-property-decorator';
|
||||
|
||||
@Component
|
||||
export default class Toast extends Vue {
|
||||
@Prop() private text!: string;
|
||||
@Prop({ default: false, type: Boolean }) private show!: boolean;
|
||||
@Prop({ default: 3000, type: Number }) private timeOut!: number;
|
||||
|
||||
private Time: any;
|
||||
|
||||
get showValue() {
|
||||
console.log('come in1111', this.show);
|
||||
if (this.show) {
|
||||
this.close();
|
||||
}
|
||||
return this.show;
|
||||
}
|
||||
|
||||
set showValue(val) {
|
||||
this.$emit('update:show', val);
|
||||
}
|
||||
|
||||
private close() {
|
||||
console.log('come in');
|
||||
clearTimeout(this.Time);
|
||||
this.Time = setTimeout(() => {
|
||||
this.showValue = false;
|
||||
this.$emit('close');
|
||||
}, this.timeOut || 0);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped
|
||||
lang="less">
|
||||
.toast-container {
|
||||
.toast-body {
|
||||
padding: 4px 10px;
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-size: 12px;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
border-radius: 4px;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user