mirror of
https://github.com/m1k1o/neko.git
synced 2024-07-24 14:40:50 +12:00
better emotes
This commit is contained in:
@ -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',
|
||||
})
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user