edit readme,fix some bug,edit client ui

This commit is contained in:
wzdwc
2020-09-12 20:52:18 +08:00
parent 3105f88f97
commit 70ecee7d87
157 changed files with 6409 additions and 7263 deletions
+300
View File
@@ -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>
+106
View File
@@ -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>
+144 -34
View File
@@ -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>
+24
View File
@@ -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
View File
@@ -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;
}
}
}
+130
View File
@@ -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>
+46
View File
@@ -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>
+191
View File
@@ -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>
+236
View File
@@ -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>
+59
View File
@@ -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>
+176
View File
@@ -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>
+98
View File
@@ -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>
+101
View File
@@ -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>
+80
View File
@@ -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>
+62
View File
@@ -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>