better emotes

This commit is contained in:
Craig
2020-02-11 18:10:24 +00:00
parent 7e177cce4c
commit 7b9eda3abb
104 changed files with 252 additions and 74 deletions

View File

@ -1,5 +1,5 @@
<template>
<div ref="emote" @click.stop.prevent="run" class="emote">
<div ref="emote" @click.stop.prevent="run" class="emote-container">
<div :class="classes" />
<div :class="classes" />
<div :class="classes" />
@ -11,46 +11,21 @@
</template>
<style lang="scss" scoped>
.emote {
width: 150px;
height: 30px;
.emote-container {
width: 25%;
height: 10%;
position: absolute;
bottom: 0;
right: 0;
div {
.emote {
position: absolute;
width: 30px;
height: 30px;
width: 100px;
height: 100%;
color: #fff;
font-size: 30px;
line-height: 30px;
transform: scale(0.7);
text-align: center;
background-size: contain;
&.celebrate {
background-image: url('../assets/images/emote/celebrate.png');
}
&.clap {
background-image: url('../assets/images/emote/clap.png');
}
&.exclam {
background-image: url('../assets/images/emote/exclam.png');
}
&.heart {
background-image: url('../assets/images/emote/heart.png');
}
&.laughing {
background-image: url('../assets/images/emote/laughing.png');
}
&.sleep {
background-image: url('../assets/images/emote/sleep.png');
}
}
}
</style>
@ -74,27 +49,27 @@
private classes: string[] = []
mounted() {
const range = 90
const range = 50
let count = 0
let finish: Array<Promise<any>> = []
this.classes = [this.emote.type]
this.classes = ['emote', this.emote.type]
for (let child of this.container.children) {
const ele = child as HTMLElement
ele.style['left'] = `${count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0)}px`
ele.style['left'] = `${count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0)}%`
ele.style['opacity'] = `0`
const animation = this.$anime({
targets: child,
keyframes: [
{ left: count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0), opacity: 1 },
{ left: count % 2 ? this.$anime.random(-range, 0) : this.$anime.random(0, range), opacity: 0.5 },
{ left: count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0), opacity: 0 },
{ left: `${count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0)}%`, opacity: 1 },
{ left: `${count % 2 ? this.$anime.random(-range, 0) : this.$anime.random(0, range)}%`, opacity: 0.5 },
{ left: `${count % 2 ? this.$anime.random(0, range) : this.$anime.random(-range, 0)}%`, opacity: 0 },
],
elasticity: 600,
rotate: this.$anime.random(-35, 35),
top: this.$anime.random(-100, -250),
top: `${this.$anime.random(-200, -600)}%`,
duration: this.$anime.random(1000, 2000),
easing: 'easeInOutQuad',
})

View File

@ -1,13 +1,18 @@
<template>
<div class="emotes">
<ul v-if="!muted">
<li><div @click.stop.prevent="click('heart')" class="heart" /></li>
<li><div @click.stop.prevent="click('sleep')" class="sleep" /></li>
<li><div @click.stop.prevent="click('laughing')" class="laughing" /></li>
<li><div @click.stop.prevent="click('celebrate')" class="celebrate" /></li>
<li><div @click.stop.prevent="click('exclam')" class="exclam" /></li>
<li><div @click.stop.prevent="click('clap')" class="clap" /></li>
<li v-for="emote in recent" :key="emote">
<div @click.stop.prevent="sendEmote(emote)" :class="['emote', emote]" />
</li>
<li>
<i @click.stop.prevent="open" class="fas fa-grin-beam"></i>
</li>
</ul>
<vue-context class="context" ref="context">
<li v-for="emote in emotes" :key="emote">
<div @click="sendEmote(emote)" :class="['emote', emote]" />
</li>
</vue-context>
</div>
</template>
@ -23,53 +28,147 @@
font-size: 24px;
margin: 0 5px;
i,
div {
cursor: pointer;
}
}
}
.context {
background-color: $background-floating;
background-clip: padding-box;
border-radius: 0.25rem;
display: flex;
margin: 0;
padding: 5px;
width: 220px;
z-index: 1500;
position: fixed;
list-style: none;
box-sizing: border-box;
max-height: calc(100% - 50px);
color: $interactive-normal;
flex-wrap: wrap;
user-select: none;
box-shadow: $elevation-high;
> li {
margin: 0;
position: relative;
align-content: center;
padding: 5px;
border-radius: 3px;
.emote {
width: 24px;
height: 24px;
cursor: pointer;
background-size: contain;
&.celebrate {
background-image: url('../assets/images/emote/celebrate.png');
}
&.clap {
background-image: url('../assets/images/emote/clap.png');
}
&.exclam {
background-image: url('../assets/images/emote/exclam.png');
}
&.heart {
background-image: url('../assets/images/emote/heart.png');
}
&.laughing {
background-image: url('../assets/images/emote/laughing.png');
}
&.sleep {
background-image: url('../assets/images/emote/sleep.png');
}
}
&:hover,
&:focus {
text-decoration: none;
background-color: $background-modifier-hover;
color: $interactive-hover;
}
&:focus {
outline: 0;
}
}
&:focus {
outline: 0;
}
}
}
</style>
<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import { Vue, Ref, Component } from 'vue-property-decorator'
import { get, set } from '../utils/localstorage'
// @ts-ignore
import { VueContext } from 'vue-context'
@Component({
name: 'neko-emotes',
components: {
'vue-context': VueContext,
},
})
export default class extends Vue {
@Ref('context') readonly context!: any
recent: string[] = JSON.parse(get('emote_recent', '[]'))
get emotes() {
return [
'anger',
'bomb',
'sleep',
'explode',
'sweat',
'poo',
'hundred',
'alert',
'punch',
'wave',
'okay',
'thumbs-up',
'clap',
'prey',
'celebrate',
'flame',
'goof',
'love',
'cool',
'smerk',
'worry',
'ouch',
'cry',
'surprised',
'quiet',
'rage',
'annoy',
'steamed',
'scared',
'terrified',
'sleepy',
'dead',
'happy',
'roll-eyes',
'thinking',
'clown',
'sick',
'rofl',
'drule',
'sniff',
'sus',
'party',
'odd',
'hot',
'cold',
'blush',
'sad',
].filter(v => !this.recent.includes(v))
}
get muted() {
return this.$accessor.user.muted
}
click(emote: string) {
open(event: MouseEvent) {
this.context.open(event)
}
sendEmote(emote: string) {
if (!this.recent.includes(emote)) {
if (this.recent.length > 4) {
this.recent.shift()
}
this.recent.push(emote)
set('emote_recent', JSON.stringify(this.recent))
}
this.$accessor.chat.sendEmote(emote)
}
}