enhance(client): 🎨

This commit is contained in:
syuilo 2021-12-27 22:59:14 +09:00
parent 154e418c34
commit ae2d71553e
6 changed files with 71 additions and 46 deletions

View File

@ -77,7 +77,7 @@
import { defineComponent, markRaw } from 'vue'; import { defineComponent, markRaw } from 'vue';
import { emojilist } from '@/scripts/emojilist'; import { emojilist } from '@/scripts/emojilist';
import { getStaticImageUrl } from '@/scripts/get-static-image-url'; import { getStaticImageUrl } from '@/scripts/get-static-image-url';
import Particle from '@/components/particle.vue'; import Ripple from '@/components/ripple.vue';
import * as os from '@/os'; import * as os from '@/os';
import { isTouchUsing } from '@/scripts/touch'; import { isTouchUsing } from '@/scripts/touch';
import { isMobile } from '@/scripts/is-mobile'; import { isMobile } from '@/scripts/is-mobile';
@ -296,9 +296,9 @@ export default defineComponent({
if (ev) { if (ev) {
const el = ev.currentTarget || ev.target; const el = ev.currentTarget || ev.target;
const rect = el.getBoundingClientRect(); const rect = el.getBoundingClientRect();
const x = rect.left + (el.clientWidth / 2); const x = rect.left + (el.offsetWidth / 2);
const y = rect.top + (el.clientHeight / 2); const y = rect.top + (el.offsetHeight / 2);
os.popup(Particle, { x, y }, {}, 'end'); os.popup(Ripple, { x, y }, {}, 'end');
} }
const key = this.getKey(emoji); const key = this.getKey(emoji);

View File

@ -9,7 +9,7 @@
:disabled="disabled" :disabled="disabled"
@keydown.enter="toggle" @keydown.enter="toggle"
> >
<span v-adaptive-border v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button" @click.prevent="toggle"> <span ref="button" v-adaptive-border v-tooltip="checked ? $ts.itsOn : $ts.itsOff" class="button" @click.prevent="toggle">
<i class="check fas fa-check"></i> <i class="check fas fa-check"></i>
</span> </span>
<span class="label"> <span class="label">
@ -20,7 +20,9 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent, ref, toRefs } from 'vue';
import * as os from '@/os';
import Ripple from '@/components/ripple.vue';
export default defineComponent({ export default defineComponent({
props: { props: {
@ -33,17 +35,28 @@ export default defineComponent({
default: false default: false
} }
}, },
computed: {
checked(): boolean { setup(props, context) {
return this.modelValue; const button = ref<HTMLElement>();
} const checked = toRefs(props).modelValue;
const toggle = () => {
if (props.disabled) return;
context.emit('update:modelValue', !checked.value);
if (!checked.value) {
const rect = button.value.getBoundingClientRect();
const x = rect.left + (button.value.offsetWidth / 2);
const y = rect.top + (button.value.offsetHeight / 2);
os.popup(Ripple, { x, y, particle: false }, {}, 'end');
}
};
return {
button,
checked,
toggle,
};
}, },
methods: {
toggle() {
if (this.disabled) return;
this.$emit('update:modelValue', !this.checked);
}
}
}); });
</script> </script>
@ -51,7 +64,7 @@ export default defineComponent({
.ziffeoms { .ziffeoms {
position: relative; position: relative;
display: flex; display: flex;
transition: all 0.2s; transition: all 0.2s ease;
> * { > * {
user-select: none; user-select: none;
@ -85,6 +98,8 @@ export default defineComponent({
opacity: 0; opacity: 0;
color: var(--fgOnAccent); color: var(--fgOnAccent);
font-size: 13px; font-size: 13px;
transform: scale(0.5);
transition: all 0.2s ease;
} }
} }
@ -131,6 +146,7 @@ export default defineComponent({
> .check { > .check {
opacity: 1; opacity: 1;
transform: scale(1);
} }
} }
} }

View File

@ -2,7 +2,7 @@
<button <button
v-if="count > 0" v-if="count > 0"
ref="buttonRef" ref="buttonRef"
v-particle="canToggle" v-ripple="canToggle"
class="hkzvhatu _button" class="hkzvhatu _button"
:class="{ reacted: note.myReaction == reaction, canToggle }" :class="{ reacted: note.myReaction == reaction, canToggle }"
@click="toggleReaction()" @click="toggleReaction()"

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="vswabwbm" :style="{ top: `${y - 64}px`, left: `${x - 64}px` }" :class="{ active }"> <div class="vswabwbm" :style="{ zIndex, top: `${y - 64}px`, left: `${x - 64}px` }" :class="{ active }">
<svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" xmlns="http://www.w3.org/2000/svg">
<circle fill="none" cx="64" cy="64"> <circle fill="none" cx="64" cy="64">
<animate attributeName="r" <animate attributeName="r"
@ -52,7 +52,8 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent } from 'vue'; import { defineComponent, onMounted } from 'vue';
import * as os from '@/os';
export default defineComponent({ export default defineComponent({
props: { props: {
@ -63,37 +64,46 @@ export default defineComponent({
y: { y: {
type: Number, type: Number,
required: true required: true
},
particle: {
type: Boolean,
required: false,
default: true,
} }
}, },
emits: ['end'], emits: ['end'],
data() { setup(props, context) {
const particles = []; const particles = [];
const origin = 64; const origin = 64;
const colors = ['#FF1493', '#00FFFF', '#FFE202']; const colors = ['#FF1493', '#00FFFF', '#FFE202'];
for (let i = 0; i < 12; i++) { if (props.particle) {
const angle = Math.random() * (Math.PI * 2); for (let i = 0; i < 12; i++) {
const pos = Math.random() * 16; const angle = Math.random() * (Math.PI * 2);
const velocity = 16 + (Math.random() * 48); const pos = Math.random() * 16;
particles.push({ const velocity = 16 + (Math.random() * 48);
size: 4 + (Math.random() * 8), particles.push({
xA: origin + (Math.sin(angle) * pos), size: 4 + (Math.random() * 8),
yA: origin + (Math.cos(angle) * pos), xA: origin + (Math.sin(angle) * pos),
xB: origin + (Math.sin(angle) * (pos + velocity)), yA: origin + (Math.cos(angle) * pos),
yB: origin + (Math.cos(angle) * (pos + velocity)), xB: origin + (Math.sin(angle) * (pos + velocity)),
color: colors[Math.floor(Math.random() * colors.length)] yB: origin + (Math.cos(angle) * (pos + velocity)),
}); color: colors[Math.floor(Math.random() * colors.length)]
});
}
} }
onMounted(() => {
setTimeout(() => {
context.emit('end');
}, 1100);
});
return { return {
particles particles,
zIndex: os.claimZIndex('high'),
}; };
}, },
mounted() {
setTimeout(() => {
this.$emit('end');
}, 1100);
}
}); });
</script> </script>
@ -101,7 +111,6 @@ export default defineComponent({
.vswabwbm { .vswabwbm {
pointer-events: none; pointer-events: none;
position: fixed; position: fixed;
z-index: 1000000;
width: 128px; width: 128px;
height: 128px; height: 128px;

View File

@ -3,7 +3,7 @@ import { App } from 'vue';
import userPreview from './user-preview'; import userPreview from './user-preview';
import size from './size'; import size from './size';
import getSize from './get-size'; import getSize from './get-size';
import particle from './particle'; import ripple from './ripple';
import tooltip from './tooltip'; import tooltip from './tooltip';
import hotkey from './hotkey'; import hotkey from './hotkey';
import appear from './appear'; import appear from './appear';
@ -18,7 +18,7 @@ export default function(app: App) {
app.directive('user-preview', userPreview); app.directive('user-preview', userPreview);
app.directive('size', size); app.directive('size', size);
app.directive('get-size', getSize); app.directive('get-size', getSize);
app.directive('particle', particle); app.directive('ripple', ripple);
app.directive('tooltip', tooltip); app.directive('tooltip', tooltip);
app.directive('hotkey', hotkey); app.directive('hotkey', hotkey);
app.directive('appear', appear); app.directive('appear', appear);

View File

@ -1,4 +1,4 @@
import Particle from '@/components/particle.vue'; import Ripple from '@/components/ripple.vue';
import { popup } from '@/os'; import { popup } from '@/os';
export default { export default {
@ -9,10 +9,10 @@ export default {
el.addEventListener('click', () => { el.addEventListener('click', () => {
const rect = el.getBoundingClientRect(); const rect = el.getBoundingClientRect();
const x = rect.left + (el.clientWidth / 2); const x = rect.left + (el.offsetWidth / 2);
const y = rect.top + (el.clientHeight / 2); const y = rect.top + (el.offsetHeight / 2);
popup(Particle, { x, y }, {}, 'end'); popup(Ripple, { x, y }, {}, 'end');
}); });
} }
}; };