Compare commits
24 Commits
Author | SHA1 | Date | |
---|---|---|---|
854814c226 | |||
b6a322f447 | |||
161b9602f4 | |||
62669bff07 | |||
02bd299714 | |||
f71dabfbfa | |||
8d31cedafc | |||
a88d6c1c47 | |||
d35a13fc0b | |||
8e4029c1cd | |||
9a9f852540 | |||
c66497a4de | |||
1f9ecbf0be | |||
423a6f7013 | |||
ef0ca38362 | |||
ae9bfd69b0 | |||
3d231c3456 | |||
95d0d0047a | |||
d05aee19f2 | |||
125765faa6 | |||
70c0b1d8c0 | |||
72e8660ae3 | |||
2127bf32c2 | |||
2b9acc239e |
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden"
|
update-available: "Eine neue Version von Misskey ist verfügbar ({newer}, aktuell ist {current}). Lade die Seite neu um die aktuelle Version zu laden"
|
||||||
my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
|
my-token-regenerated: "Dein Token wurde generiert. Du wirst jetzt abgemeldet."
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "A new version of Misskey is now available({newer}, current is {current}). Reload the page to apply the update."
|
update-available: "A new version of Misskey is now available({newer}, current is {current}). Reload the page to apply the update."
|
||||||
my-token-regenerated: "Your token has been generated. You will now get logged out."
|
my-token-regenerated: "Your token has been generated. You will now get logged out."
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "Analog clock"
|
||||||
profile: "Profile"
|
profile: "Profile"
|
||||||
calendar: "Calendar"
|
calendar: "Calendar"
|
||||||
timemachine: "Calendar (Time Machine)"
|
timemachine: "Calendar (Time Machine)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Une nouvelle version de Misskey est disponible({newer}, version actuelle: {current}). Recharger la page pour appliquer la mise à jour."
|
update-available: "Une nouvelle version de Misskey est disponible({newer}, version actuelle: {current}). Recharger la page pour appliquer la mise à jour."
|
||||||
my-token-regenerated: "Votre token vient d'être généré, vous allez maintenant être déconnecté."
|
my-token-regenerated: "Votre token vient d'être généré, vous allez maintenant être déconnecté."
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -54,6 +54,7 @@ common:
|
|||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
|
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację."
|
update-available: "Nowa wersja Misskey jest dostępna ({newer}, obecna to {current}). Odśwież stronę, aby zastosować aktualizację."
|
||||||
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
|
my-token-regenerated: "Twój token został wygenerowany. Zostaniesz wylogowany."
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "Profil"
|
profile: "Profil"
|
||||||
calendar: "Kalendarz"
|
calendar: "Kalendarz"
|
||||||
timemachine: "Kalendarz (wehikuł czasu)"
|
timemachine: "Kalendarz (wehikuł czasu)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -48,6 +48,7 @@ common:
|
|||||||
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
update-available: "Misskeyの新しいバージョンがあります({newer}。現在{current}を利用中)。ページを再度読み込みすると更新が適用されます。"
|
||||||
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
my-token-regenerated: "あなたのトークンが更新されたのでサインアウトします。"
|
||||||
widgets:
|
widgets:
|
||||||
|
analog-clock: "アナログ時計"
|
||||||
profile: "プロフィール"
|
profile: "プロフィール"
|
||||||
calendar: "カレンダー"
|
calendar: "カレンダー"
|
||||||
timemachine: "カレンダー(タイムマシン)"
|
timemachine: "カレンダー(タイムマシン)"
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "2.23.0",
|
"version": "2.24.0",
|
||||||
"clientVersion": "1.0.5993",
|
"clientVersion": "1.0.6017",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"main": "./built/index.js",
|
"main": "./built/index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
@ -20,6 +20,7 @@ init(launch => {
|
|||||||
// Init router
|
// Init router
|
||||||
const router = new VueRouter({
|
const router = new VueRouter({
|
||||||
mode: 'history',
|
mode: 'history',
|
||||||
|
base: '/auth/',
|
||||||
routes: [
|
routes: [
|
||||||
{ path: '/:token', component: Index },
|
{ path: '/:token', component: Index },
|
||||||
]
|
]
|
||||||
|
@ -62,7 +62,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
// 既に連携していた場合
|
// 既に連携していた場合
|
||||||
if (this.session.app.isAuthorized) {
|
if (this.session.app.isAuthorized) {
|
||||||
this.$root.$data.os.api('auth/accept', {
|
(this as any).api('auth/accept', {
|
||||||
token: this.session.token
|
token: this.session.token
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.accepted();
|
this.accepted();
|
||||||
|
@ -32,9 +32,9 @@
|
|||||||
//#region Detect app name
|
//#region Detect app name
|
||||||
let app = null;
|
let app = null;
|
||||||
|
|
||||||
if (url.pathname == '/docs') app = 'docs';
|
if (url.pathname == '/docs' || url.pathname.startsWith('/docs/')) app = 'docs';
|
||||||
if (url.pathname == '/dev') app = 'dev';
|
if (url.pathname == '/dev' || url.pathname.startsWith('/dev/')) app = 'dev';
|
||||||
if (url.pathname == '/auth') app = 'auth';
|
if (url.pathname == '/auth' || url.pathname.startsWith('/auth/')) app = 'auth';
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
//#region Detect the user language
|
//#region Detect the user language
|
||||||
|
126
src/client/app/common/views/components/analog-clock.vue
Normal file
126
src/client/app/common/views/components/analog-clock.vue
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<template>
|
||||||
|
<svg class="mk-analog-clock" viewBox="0 0 10 10" preserveAspectRatio="none">
|
||||||
|
<line v-for="angle, i in graduations"
|
||||||
|
:x1="5 + (Math.sin(angle) * (5 - graduationsPadding))"
|
||||||
|
:y1="5 - (Math.cos(angle) * (5 - graduationsPadding))"
|
||||||
|
:x2="5 + (Math.sin(angle) * ((5 - graduationsPadding) - (i % 5 == 0 ? longGraduationLength : shortGraduationLength)))"
|
||||||
|
:y2="5 - (Math.cos(angle) * ((5 - graduationsPadding) - (i % 5 == 0 ? longGraduationLength : shortGraduationLength)))"
|
||||||
|
:stroke="i % 5 == 0 ? longGraduationColor : shortGraduationColor"
|
||||||
|
stroke-width="0.05"/>
|
||||||
|
|
||||||
|
<line
|
||||||
|
:x1="5 - (Math.sin(sAngle) * (sHandLengthRatio * handsTailLength))"
|
||||||
|
:y1="5 + (Math.cos(sAngle) * (sHandLengthRatio * handsTailLength))"
|
||||||
|
:x2="5 + (Math.sin(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:y2="5 - (Math.cos(sAngle) * ((sHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:stroke="sHandColor"
|
||||||
|
stroke-width="0.05"/>
|
||||||
|
<line
|
||||||
|
:x1="5 - (Math.sin(mAngle) * (mHandLengthRatio * handsTailLength))"
|
||||||
|
:y1="5 + (Math.cos(mAngle) * (mHandLengthRatio * handsTailLength))"
|
||||||
|
:x2="5 + (Math.sin(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:y2="5 - (Math.cos(mAngle) * ((mHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:stroke="mHandColor"
|
||||||
|
stroke-width="0.1"/>
|
||||||
|
<line
|
||||||
|
:x1="5 - (Math.sin(hAngle) * (hHandLengthRatio * handsTailLength))"
|
||||||
|
:y1="5 + (Math.cos(hAngle) * (hHandLengthRatio * handsTailLength))"
|
||||||
|
:x2="5 + (Math.sin(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:y2="5 - (Math.cos(hAngle) * ((hHandLengthRatio * 5) - handsPadding))"
|
||||||
|
:stroke="hHandColor"
|
||||||
|
stroke-width="0.1"/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import { themeColor } from '../../../config';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
props: {
|
||||||
|
dark: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
now: new Date(),
|
||||||
|
clock: null,
|
||||||
|
|
||||||
|
graduationsPadding: 0.5,
|
||||||
|
longGraduationLength: 0.3,
|
||||||
|
shortGraduationLength: 0.15,
|
||||||
|
handsPadding: 1,
|
||||||
|
handsTailLength: 0.7,
|
||||||
|
hHandLengthRatio: 0.75,
|
||||||
|
mHandLengthRatio: 1,
|
||||||
|
sHandLengthRatio: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
longGraduationColor(): string {
|
||||||
|
return this.dark ? 'rgba(255, 255, 255, 0.3)' : 'rgba(0, 0, 0, 0.3)';
|
||||||
|
},
|
||||||
|
shortGraduationColor(): string {
|
||||||
|
return this.dark ? 'rgba(255, 255, 255, 0.2)' : 'rgba(0, 0, 0, 0.2)';
|
||||||
|
},
|
||||||
|
|
||||||
|
sHandColor(): string {
|
||||||
|
return this.dark ? 'rgba(255, 255, 255, 0.5)' : 'rgba(0, 0, 0, 0.3)';
|
||||||
|
},
|
||||||
|
mHandColor(): string {
|
||||||
|
return this.dark ? '#fff' : '#777';
|
||||||
|
},
|
||||||
|
hHandColor(): string {
|
||||||
|
return themeColor;
|
||||||
|
},
|
||||||
|
|
||||||
|
s(): number {
|
||||||
|
return this.now.getSeconds();
|
||||||
|
},
|
||||||
|
m(): number {
|
||||||
|
return this.now.getMinutes();
|
||||||
|
},
|
||||||
|
h(): number {
|
||||||
|
return this.now.getHours();
|
||||||
|
},
|
||||||
|
|
||||||
|
hAngle(): number {
|
||||||
|
return Math.PI * (this.h % 12 + this.m / 60) / 6;
|
||||||
|
},
|
||||||
|
mAngle(): number {
|
||||||
|
return Math.PI * (this.m + this.s / 60) / 30;
|
||||||
|
},
|
||||||
|
sAngle(): number {
|
||||||
|
return Math.PI * this.s / 30;
|
||||||
|
},
|
||||||
|
|
||||||
|
graduations(): any {
|
||||||
|
const angles = [];
|
||||||
|
for (let i = 0; i < 60; i++) {
|
||||||
|
const angle = Math.PI * i / 30;
|
||||||
|
angles.push(angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
return angles;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.clock = setInterval(this.tick, 1000);
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
clearInterval(this.clock);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
tick() {
|
||||||
|
this.now = new Date();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.mk-analog-clock
|
||||||
|
display block
|
||||||
|
</style>
|
@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import analogClock from './analog-clock.vue';
|
||||||
import signin from './signin.vue';
|
import signin from './signin.vue';
|
||||||
import signup from './signup.vue';
|
import signup from './signup.vue';
|
||||||
import forkit from './forkit.vue';
|
import forkit from './forkit.vue';
|
||||||
@ -27,6 +28,7 @@ import Switch from './switch.vue';
|
|||||||
import Othello from './othello.vue';
|
import Othello from './othello.vue';
|
||||||
import welcomeTimeline from './welcome-timeline.vue';
|
import welcomeTimeline from './welcome-timeline.vue';
|
||||||
|
|
||||||
|
Vue.component('mk-analog-clock', analogClock);
|
||||||
Vue.component('mk-signin', signin);
|
Vue.component('mk-signin', signin);
|
||||||
Vue.component('mk-signup', signup);
|
Vue.component('mk-signup', signup);
|
||||||
Vue.component('mk-forkit', forkit);
|
Vue.component('mk-forkit', forkit);
|
||||||
|
41
src/client/app/common/views/widgets/analog-clock.vue
Normal file
41
src/client/app/common/views/widgets/analog-clock.vue
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mkw-analog-clock">
|
||||||
|
<mk-widget-container :naked="props.naked" :show-header="false">
|
||||||
|
<div class="mkw-analog-clock--body">
|
||||||
|
<mk-analog-clock :dark="$store.state.device.darkmode"/>
|
||||||
|
</div>
|
||||||
|
</mk-widget-container>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import define from '../../../common/define-widget';
|
||||||
|
export default define({
|
||||||
|
name: 'analog-clock',
|
||||||
|
props: () => ({
|
||||||
|
naked: false
|
||||||
|
})
|
||||||
|
}).extend({
|
||||||
|
methods: {
|
||||||
|
func() {
|
||||||
|
this.props.naked = !this.props.naked;
|
||||||
|
this.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
@import '~const.styl'
|
||||||
|
|
||||||
|
root(isDark)
|
||||||
|
.mkw-analog-clock--body
|
||||||
|
padding 8px
|
||||||
|
|
||||||
|
.mkw-analog-clock[data-darkmode]
|
||||||
|
root(true)
|
||||||
|
|
||||||
|
.mkw-analog-clock:not([data-darkmode])
|
||||||
|
root(false)
|
||||||
|
|
||||||
|
</style>
|
@ -1,5 +1,6 @@
|
|||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import wAnalogClock from './analog-clock.vue';
|
||||||
import wVersion from './version.vue';
|
import wVersion from './version.vue';
|
||||||
import wRss from './rss.vue';
|
import wRss from './rss.vue';
|
||||||
import wServer from './server.vue';
|
import wServer from './server.vue';
|
||||||
@ -12,6 +13,7 @@ import wTips from './tips.vue';
|
|||||||
import wDonation from './donation.vue';
|
import wDonation from './donation.vue';
|
||||||
import wNav from './nav.vue';
|
import wNav from './nav.vue';
|
||||||
|
|
||||||
|
Vue.component('mkw-analog-clock', wAnalogClock);
|
||||||
Vue.component('mkw-nav', wNav);
|
Vue.component('mkw-nav', wNav);
|
||||||
Vue.component('mkw-calendar', wCalendar);
|
Vue.component('mkw-calendar', wCalendar);
|
||||||
Vue.component('mkw-photo-stream', wPhotoStream);
|
Vue.component('mkw-photo-stream', wPhotoStream);
|
||||||
|
@ -1,108 +0,0 @@
|
|||||||
<template>
|
|
||||||
<canvas class="mk-analog-clock" ref="canvas" width="256" height="256"></canvas>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import { themeColor } from '../../../config';
|
|
||||||
|
|
||||||
const Vec2 = function(this: any, x, y) {
|
|
||||||
this.x = x;
|
|
||||||
this.y = y;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
clock: null
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.tick();
|
|
||||||
this.clock = setInterval(this.tick, 1000);
|
|
||||||
},
|
|
||||||
beforeDestroy() {
|
|
||||||
clearInterval(this.clock);
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
tick() {
|
|
||||||
const canv = this.$refs.canvas as any;
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const s = now.getSeconds();
|
|
||||||
const m = now.getMinutes();
|
|
||||||
const h = now.getHours();
|
|
||||||
|
|
||||||
const ctx = canv.getContext('2d');
|
|
||||||
const canvW = canv.width;
|
|
||||||
const canvH = canv.height;
|
|
||||||
ctx.clearRect(0, 0, canvW, canvH);
|
|
||||||
|
|
||||||
{ // 背景
|
|
||||||
const center = Math.min((canvW / 2), (canvH / 2));
|
|
||||||
const lineStart = center * 0.90;
|
|
||||||
const shortLineEnd = center * 0.87;
|
|
||||||
const longLineEnd = center * 0.84;
|
|
||||||
for (let i = 0; i < 60; i++) {
|
|
||||||
const angle = Math.PI * i / 30;
|
|
||||||
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.moveTo((canvW / 2) + uv.x * lineStart, (canvH / 2) + uv.y * lineStart);
|
|
||||||
if (i % 5 == 0) {
|
|
||||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.2)';
|
|
||||||
ctx.lineTo((canvW / 2) + uv.x * longLineEnd, (canvH / 2) + uv.y * longLineEnd);
|
|
||||||
} else {
|
|
||||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.1)';
|
|
||||||
ctx.lineTo((canvW / 2) + uv.x * shortLineEnd, (canvH / 2) + uv.y * shortLineEnd);
|
|
||||||
}
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // 分
|
|
||||||
const angle = Math.PI * (m + s / 60) / 30;
|
|
||||||
const length = Math.min(canvW, canvH) / 2.6;
|
|
||||||
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = '#ffffff';
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
|
||||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // 時
|
|
||||||
const angle = Math.PI * (h % 12 + m / 60) / 6;
|
|
||||||
const length = Math.min(canvW, canvH) / 4;
|
|
||||||
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = themeColor;
|
|
||||||
ctx.lineWidth = 2;
|
|
||||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
|
||||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
|
|
||||||
{ // 秒
|
|
||||||
const angle = Math.PI * s / 30;
|
|
||||||
const length = Math.min(canvW, canvH) / 2.6;
|
|
||||||
const uv = new Vec2(Math.sin(angle), -Math.cos(angle));
|
|
||||||
ctx.beginPath();
|
|
||||||
ctx.strokeStyle = 'rgba(255, 255, 255, 0.5)';
|
|
||||||
ctx.lineWidth = 1;
|
|
||||||
ctx.moveTo(canvW / 2 - uv.x * length / 5, canvH / 2 - uv.y * length / 5);
|
|
||||||
ctx.lineTo(canvW / 2 + uv.x * length, canvH / 2 + uv.y * length);
|
|
||||||
ctx.stroke();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.mk-analog-clock
|
|
||||||
display block
|
|
||||||
width 256px
|
|
||||||
height 256px
|
|
||||||
</style>
|
|
@ -7,6 +7,7 @@
|
|||||||
<p>%i18n:@add-widget%</p>
|
<p>%i18n:@add-widget%</p>
|
||||||
<select v-model="widgetAdderSelected">
|
<select v-model="widgetAdderSelected">
|
||||||
<option value="profile">%i18n:common.widgets.profile%</option>
|
<option value="profile">%i18n:common.widgets.profile%</option>
|
||||||
|
<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
|
||||||
<option value="calendar">%i18n:common.widgets.calendar%</option>
|
<option value="calendar">%i18n:common.widgets.calendar%</option>
|
||||||
<option value="timemachine">%i18n:common.widgets.timemachine%</option>
|
<option value="timemachine">%i18n:common.widgets.timemachine%</option>
|
||||||
<option value="activity">%i18n:common.widgets.activity%</option>
|
<option value="activity">%i18n:common.widgets.activity%</option>
|
||||||
|
@ -9,7 +9,6 @@ import subNoteContent from './sub-note-content.vue';
|
|||||||
import window from './window.vue';
|
import window from './window.vue';
|
||||||
import noteFormWindow from './post-form-window.vue';
|
import noteFormWindow from './post-form-window.vue';
|
||||||
import renoteFormWindow from './renote-form-window.vue';
|
import renoteFormWindow from './renote-form-window.vue';
|
||||||
import analogClock from './analog-clock.vue';
|
|
||||||
import ellipsisIcon from './ellipsis-icon.vue';
|
import ellipsisIcon from './ellipsis-icon.vue';
|
||||||
import mediaImage from './media-image.vue';
|
import mediaImage from './media-image.vue';
|
||||||
import mediaImageDialog from './media-image-dialog.vue';
|
import mediaImageDialog from './media-image-dialog.vue';
|
||||||
@ -40,7 +39,6 @@ Vue.component('mk-sub-note-content', subNoteContent);
|
|||||||
Vue.component('mk-window', window);
|
Vue.component('mk-window', window);
|
||||||
Vue.component('mk-post-form-window', noteFormWindow);
|
Vue.component('mk-post-form-window', noteFormWindow);
|
||||||
Vue.component('mk-renote-form-window', renoteFormWindow);
|
Vue.component('mk-renote-form-window', renoteFormWindow);
|
||||||
Vue.component('mk-analog-clock', analogClock);
|
|
||||||
Vue.component('mk-ellipsis-icon', ellipsisIcon);
|
Vue.component('mk-ellipsis-icon', ellipsisIcon);
|
||||||
Vue.component('mk-media-image', mediaImage);
|
Vue.component('mk-media-image', mediaImage);
|
||||||
Vue.component('mk-media-image-dialog', mediaImageDialog);
|
Vue.component('mk-media-image-dialog', mediaImageDialog);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
</time>
|
</time>
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<mk-analog-clock/>
|
<mk-analog-clock :dark="true"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -80,6 +80,8 @@ export default Vue.extend({
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
@import '~const.styl'
|
@import '~const.styl'
|
||||||
|
|
||||||
|
@import url(https://fonts.googleapis.com/earlyaccess/notosansjp.css);
|
||||||
|
|
||||||
root(isDark)
|
root(isDark)
|
||||||
display flex
|
display flex
|
||||||
flex-direction column
|
flex-direction column
|
||||||
@ -103,6 +105,7 @@ root(isDark)
|
|||||||
text-align center
|
text-align center
|
||||||
|
|
||||||
&.about
|
&.about
|
||||||
|
font-family 'Noto Sans JP'
|
||||||
color isDark ? #fff : #627574
|
color isDark ? #fff : #627574
|
||||||
|
|
||||||
> article
|
> article
|
||||||
@ -114,7 +117,7 @@ root(isDark)
|
|||||||
|
|
||||||
> h1
|
> h1
|
||||||
margin 0
|
margin 0
|
||||||
font-variant small-caps
|
font-weight 900
|
||||||
|
|
||||||
> p
|
> p
|
||||||
margin 20px 0
|
margin 20px 0
|
||||||
|
@ -180,6 +180,8 @@ root(isDark)
|
|||||||
|
|
||||||
> [data-fa]:first-child
|
> [data-fa]:first-child
|
||||||
margin-right 0.5em
|
margin-right 0.5em
|
||||||
|
width 20px
|
||||||
|
text-align center
|
||||||
|
|
||||||
> [data-fa].circle
|
> [data-fa].circle
|
||||||
margin-left 6px
|
margin-left 6px
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
<header>
|
<header>
|
||||||
<select v-model="widgetAdderSelected">
|
<select v-model="widgetAdderSelected">
|
||||||
<option value="profile">%i18n:common.widgets.profile%</option>
|
<option value="profile">%i18n:common.widgets.profile%</option>
|
||||||
|
<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
|
||||||
<option value="calendar">%i18n:common.widgets.calendar%</option>
|
<option value="calendar">%i18n:common.widgets.calendar%</option>
|
||||||
<option value="activity">%i18n:common.widgets.activity%</option>
|
<option value="activity">%i18n:common.widgets.activity%</option>
|
||||||
<option value="rss">%i18n:common.widgets.rss%</option>
|
<option value="rss">%i18n:common.widgets.rss%</option>
|
||||||
|
Reference in New Issue
Block a user