㊙️
This commit is contained in:
		
							parent
							
								
									2112fb3896
								
							
						
					
					
						commit
						9a270e59a4
					
				
					 4 changed files with 266 additions and 46 deletions
				
			
		|  | @ -74,6 +74,7 @@ | ||||||
| 		"@types/koa__multer": "2.0.2", | 		"@types/koa__multer": "2.0.2", | ||||||
| 		"@types/koa__router": "8.0.2", | 		"@types/koa__router": "8.0.2", | ||||||
| 		"@types/markdown-it": "10.0.3", | 		"@types/markdown-it": "10.0.3", | ||||||
|  | 		"@types/matter-js": "0.14.7", | ||||||
| 		"@types/mocha": "7.0.2", | 		"@types/mocha": "7.0.2", | ||||||
| 		"@types/node": "14.0.22", | 		"@types/node": "14.0.22", | ||||||
| 		"@types/node-fetch": "2.5.7", | 		"@types/node-fetch": "2.5.7", | ||||||
|  | @ -175,6 +176,7 @@ | ||||||
| 		"lookup-dns-cache": "2.1.0", | 		"lookup-dns-cache": "2.1.0", | ||||||
| 		"markdown-it": "11.0.1", | 		"markdown-it": "11.0.1", | ||||||
| 		"markdown-it-anchor": "6.0.1", | 		"markdown-it-anchor": "6.0.1", | ||||||
|  | 		"matter-js": "0.14.2", | ||||||
| 		"mocha": "8.2.1", | 		"mocha": "8.2.1", | ||||||
| 		"moji": "0.5.1", | 		"moji": "0.5.1", | ||||||
| 		"ms": "2.1.2", | 		"ms": "2.1.2", | ||||||
|  |  | ||||||
|  | @ -1,50 +1,54 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase class="znqjceqz"> | <div style="overflow: hidden;"> | ||||||
| 	<section class="_formItem"> | 	<FormBase class="znqjceqz"> | ||||||
| 		<div class="_formPanel" style="text-align: center; padding: 16px;"> | 		<div id="debug"></div> | ||||||
| 			<img src="/assets/icons/512.png" alt="" style="display: block; width: 100px; margin: 0 auto; border-radius: 16px;" ref="icon"/> | 		<section class="_formItem"> | ||||||
| 			<div style="margin-top: 0.75em;">Misskey</div> | 			<div class="_formPanel" style="text-align: center; padding: 16px;" ref="about"> | ||||||
| 			<div style="opacity: 0.5;">v{{ version }}</div> | 				<img src="/assets/icons/512.png" alt="" style="display: block; width: 100px; margin: 0 auto; border-radius: 16px;" ref="icon" @load="iconLoaded" draggable="false"/> | ||||||
| 		</div> | 				<div style="margin: 0.75em auto 0 auto; width: max-content;">Misskey</div> | ||||||
| 	</section> | 				<div style="margin: 0 auto; opacity: 0.5; width: max-content;">v{{ version }}</div> | ||||||
| 	<section class="_formItem" style="text-align: center; padding: 0 16px;"> | 				<span v-for="emoji in easterEggEmojis" :key="emoji.emoji" class="_physics_circle_" :style="{ position: 'absolute', top: emoji.top, left: emoji.left, userSelect: 'none' }"><MkEmoji style="pointer-events: none; font-size: 24px; width: 24px;" :emoji="emoji.emoji" :custom-emojis="$store.state.instance.meta.emojis" :is-reaction="false" :normal="true" :no-style="true"/></span> | ||||||
| 		{{ $t('_aboutMisskey.about') }} | 			</div> | ||||||
| 	</section> | 		</section> | ||||||
| 	<FormGroup> | 		<section class="_formItem" style="text-align: center; padding: 0 16px;" @click="gravity"> | ||||||
| 		<FormLink to="https://github.com/syuilo/misskey" external> | 			{{ $t('_aboutMisskey.about') }} | ||||||
| 			<template #icon><Fa :icon="faCode"/></template> | 		</section> | ||||||
| 			{{ $t('_aboutMisskey.source') }} | 		<FormGroup> | ||||||
| 			<template #suffix>GitHub</template> | 			<FormLink to="https://github.com/syuilo/misskey" external> | ||||||
| 		</FormLink> | 				<template #icon><Fa :icon="faCode"/></template> | ||||||
| 		<FormLink to="https://crowdin.com/project/misskey" external> | 				{{ $t('_aboutMisskey.source') }} | ||||||
| 			<template #icon><Fa :icon="faLanguage"/></template> | 				<template #suffix>GitHub</template> | ||||||
| 			{{ $t('_aboutMisskey.translation') }} | 			</FormLink> | ||||||
| 			<template #suffix>Crowdin</template> | 			<FormLink to="https://crowdin.com/project/misskey" external> | ||||||
| 		</FormLink> | 				<template #icon><Fa :icon="faLanguage"/></template> | ||||||
| 		<FormLink to="https://www.patreon.com/syuilo" external> | 				{{ $t('_aboutMisskey.translation') }} | ||||||
| 			<template #icon><Fa :icon="faHandHoldingMedical"/></template> | 				<template #suffix>Crowdin</template> | ||||||
| 			{{ $t('_aboutMisskey.donate') }} | 			</FormLink> | ||||||
| 			<template #suffix>Patreon</template> | 			<FormLink to="https://www.patreon.com/syuilo" external> | ||||||
| 		</FormLink> | 				<template #icon><Fa :icon="faHandHoldingMedical"/></template> | ||||||
| 	</FormGroup> | 				{{ $t('_aboutMisskey.donate') }} | ||||||
| 	<FormGroup> | 				<template #suffix>Patreon</template> | ||||||
| 		<template #label>{{ $t('_aboutMisskey.contributors') }}</template> | 			</FormLink> | ||||||
| 		<FormLink to="https://github.com/syuilo" external>@syuilo</FormLink> | 		</FormGroup> | ||||||
| 		<FormLink to="https://github.com/AyaMorisawa" external>@AyaMorisawa</FormLink> | 		<FormGroup> | ||||||
| 		<FormLink to="https://github.com/mei23" external>@mei23</FormLink> | 			<template #label>{{ $t('_aboutMisskey.contributors') }}</template> | ||||||
| 		<FormLink to="https://github.com/acid-chicken" external>@acid-chicken</FormLink> | 			<FormLink to="https://github.com/syuilo" external>@syuilo</FormLink> | ||||||
| 		<FormLink to="https://github.com/tamaina" external>@tamaina</FormLink> | 			<FormLink to="https://github.com/AyaMorisawa" external>@AyaMorisawa</FormLink> | ||||||
| 		<FormLink to="https://github.com/rinsuki" external>@rinsuki</FormLink> | 			<FormLink to="https://github.com/mei23" external>@mei23</FormLink> | ||||||
| 		<FormLink to="https://github.com/Xeltica" external>@Xeltica</FormLink> | 			<FormLink to="https://github.com/acid-chicken" external>@acid-chicken</FormLink> | ||||||
| 		<FormLink to="https://github.com/u1-liquid" external>@u1-liquid</FormLink> | 			<FormLink to="https://github.com/tamaina" external>@tamaina</FormLink> | ||||||
| 		<template #caption><MkLink url="https://github.com/syuilo/misskey/graphs/contributors">{{ $t('_aboutMisskey.allContributors') }}</MkLink></template> | 			<FormLink to="https://github.com/rinsuki" external>@rinsuki</FormLink> | ||||||
| 	</FormGroup> | 			<FormLink to="https://github.com/Xeltica" external>@Xeltica</FormLink> | ||||||
| 	<FormGroup> | 			<FormLink to="https://github.com/u1-liquid" external>@u1-liquid</FormLink> | ||||||
| 		<template #label><Mfm text="[jelly ❤]"/> {{ $t('_aboutMisskey.patrons') }}</template> | 			<template #caption><MkLink url="https://github.com/syuilo/misskey/graphs/contributors">{{ $t('_aboutMisskey.allContributors') }}</MkLink></template> | ||||||
| 		<FormKeyValueView v-for="patron in patrons" :key="patron"><template #key>{{ patron }}</template></FormKeyValueView> | 		</FormGroup> | ||||||
| 		<template #caption>{{ $t('_aboutMisskey.morePatrons') }}</template> | 		<FormGroup> | ||||||
| 	</FormGroup> | 			<template #label><Mfm text="[jelly ❤]"/> {{ $t('_aboutMisskey.patrons') }}</template> | ||||||
| </FormBase> | 			<FormKeyValueView v-for="patron in patrons" :key="patron"><template #key>{{ patron }}</template></FormKeyValueView> | ||||||
|  | 			<template #caption>{{ $t('_aboutMisskey.morePatrons') }}</template> | ||||||
|  | 		</FormGroup> | ||||||
|  | 	</FormBase> | ||||||
|  | </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|  | @ -57,6 +61,7 @@ import FormBase from '@/components/form/base.vue'; | ||||||
| import FormGroup from '@/components/form/group.vue'; | import FormGroup from '@/components/form/group.vue'; | ||||||
| import FormKeyValueView from '@/components/form/key-value-view.vue'; | import FormKeyValueView from '@/components/form/key-value-view.vue'; | ||||||
| import MkLink from '@/components/link.vue'; | import MkLink from '@/components/link.vue'; | ||||||
|  | import { physics } from '@/scripts/physics.ts'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| 
 | 
 | ||||||
| const patrons = [ | const patrons = [ | ||||||
|  | @ -115,10 +120,24 @@ export default defineComponent({ | ||||||
| 			}, | 			}, | ||||||
| 			version, | 			version, | ||||||
| 			patrons, | 			patrons, | ||||||
|  | 			easterEggReady: false, | ||||||
|  | 			easterEggEmojis: [], | ||||||
|  | 			easterEggEngine: null, | ||||||
| 			faInfoCircle, faCode, faLanguage, faHandHoldingMedical, | 			faInfoCircle, faCode, faLanguage, faHandHoldingMedical, | ||||||
| 		} | 		} | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	created() { | ||||||
|  | 		const emojis = this.$store.state.settings.reactions; | ||||||
|  | 		for (let i = 0; i < 32; i++) { | ||||||
|  | 			this.easterEggEmojis.push({ | ||||||
|  | 				top: -(32 + (Math.random() * 256)) + 'px', | ||||||
|  | 				left: (Math.random() * 99) + '%', | ||||||
|  | 				emoji: emojis[Math.floor(Math.random() * emojis.length)], | ||||||
|  | 			}); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
| 	mounted() { | 	mounted() { | ||||||
| 		VanillaTilt.init(this.$refs.icon, { | 		VanillaTilt.init(this.$refs.icon, { | ||||||
| 			max: 30, | 			max: 30, | ||||||
|  | @ -127,6 +146,27 @@ export default defineComponent({ | ||||||
| 			speed: 1000, | 			speed: 1000, | ||||||
| 		}); | 		}); | ||||||
| 	}, | 	}, | ||||||
|  | 
 | ||||||
|  | 	beforeUnmount() { | ||||||
|  | 		if (this.easterEggEngine) { | ||||||
|  | 			this.easterEggEngine.stop(); | ||||||
|  | 		} | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	methods: { | ||||||
|  | 		iconLoaded() { | ||||||
|  | 			this.$nextTick(() => { | ||||||
|  | 				this.easterEggReady = true; | ||||||
|  | 			}); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		gravity() { | ||||||
|  | 			if (!this.easterEggReady) return; | ||||||
|  | 			this.easterEggReady = false; | ||||||
|  | 			this.$refs.icon.vanillaTilt.destroy(); | ||||||
|  | 			this.easterEggEngine = physics(this.$refs.about); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										168
									
								
								src/client/scripts/physics.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										168
									
								
								src/client/scripts/physics.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,168 @@ | ||||||
|  | import Matter from 'matter-js'; | ||||||
|  | 
 | ||||||
|  | export function physics(container: HTMLElement) { | ||||||
|  | 	const containerWidth = container.offsetWidth; | ||||||
|  | 	const containerHeight = container.offsetHeight; | ||||||
|  | 	const containerCenterX = containerWidth / 2; | ||||||
|  | 
 | ||||||
|  | 	// サイズ固定化(要らないかも?)
 | ||||||
|  | 	container.style.position = 'relative'; | ||||||
|  | 	container.style.boxSizing = 'border-box'; | ||||||
|  | 	container.style.width = `${containerWidth}px`; | ||||||
|  | 	container.style.height = `${containerHeight}px`; | ||||||
|  | 
 | ||||||
|  | 	// create engine
 | ||||||
|  | 	const engine    = Matter.Engine.create(); | ||||||
|  | 	const world     = engine.world; | ||||||
|  | 
 | ||||||
|  | 	// create renderer
 | ||||||
|  | 	const render = Matter.Render.create({ | ||||||
|  | 		engine: engine, | ||||||
|  | 		//element: document.getElementById('debug'),
 | ||||||
|  | 		options: { | ||||||
|  | 			width: containerWidth, | ||||||
|  | 			height: containerHeight, | ||||||
|  | 			background: 'transparent', // transparent to hide
 | ||||||
|  | 			wireframeBackground: 'transparent', // transparent to hide
 | ||||||
|  | 			hasBounds: false, | ||||||
|  | 			enabled: true, | ||||||
|  | 			wireframes: false, | ||||||
|  | 			showSleeping: true, | ||||||
|  | 			showDebug: false, | ||||||
|  | 			showBroadphase: false, | ||||||
|  | 			showBounds: false, | ||||||
|  | 			showVelocity: false, | ||||||
|  | 			showCollisions: false, | ||||||
|  | 			showAxes: false, | ||||||
|  | 			showPositions: false, | ||||||
|  | 			showAngleIndicator: false, | ||||||
|  | 			showIds: false, | ||||||
|  | 			showShadows: false | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	// Disable to hide debug
 | ||||||
|  | 	Matter.Render.run(render); | ||||||
|  | 
 | ||||||
|  | 	// create runner
 | ||||||
|  | 	const runner = Matter.Runner.create(); | ||||||
|  | 	Matter.Runner.run(runner, engine); | ||||||
|  | 
 | ||||||
|  | 	// add walls
 | ||||||
|  | 	const wallopts = { | ||||||
|  | 		isStatic:     true, | ||||||
|  | 		restitution:  0.2, | ||||||
|  | 		friction:     1 | ||||||
|  | 	}; | ||||||
|  | 	const groundopts = { | ||||||
|  | 		isStatic:     true, | ||||||
|  | 		restitution:  0.1, | ||||||
|  | 		friction:     2 | ||||||
|  | 	}; | ||||||
|  | 
 | ||||||
|  | 	const groundThickness = 100; | ||||||
|  | 	const ground = Matter.Bodies.rectangle(containerCenterX, containerHeight + (groundThickness / 2), containerWidth, groundThickness, groundopts); | ||||||
|  | 	//const wallRight = Matter.Bodies.rectangle(window.innerWidth+50, window.innerHeight/2, 100, window.innerHeight, wallopts);
 | ||||||
|  | 	//const wallLeft = Matter.Bodies.rectangle(-50, window.innerHeight/2, 100, window.innerHeight, wallopts);
 | ||||||
|  | 
 | ||||||
|  | 	Matter.World.add(world, [ | ||||||
|  | 		ground, | ||||||
|  | 		//wallRight,
 | ||||||
|  | 		//wallLeft,
 | ||||||
|  | 	]); | ||||||
|  | 
 | ||||||
|  | 	const objEls = Array.from(container.children); | ||||||
|  | 	const objs = []; | ||||||
|  | 	for (const objEl of objEls) { | ||||||
|  | 		let obj; | ||||||
|  | 		if (objEl.classList.contains('_physics_circle_')) { | ||||||
|  | 			obj = Matter.Bodies.circle( | ||||||
|  | 				objEl.offsetLeft + (objEl.offsetWidth / 2), | ||||||
|  | 				objEl.offsetTop + (objEl.offsetHeight / 2), | ||||||
|  | 				Math.max(objEl.offsetWidth, objEl.offsetHeight) / 2, | ||||||
|  | 				{ | ||||||
|  | 					restitution:      0.1, | ||||||
|  | 					friction:         4, | ||||||
|  | 					frictionAir:      0, | ||||||
|  | 					frictionStatic:   50, | ||||||
|  | 					density:          100, | ||||||
|  | 				} | ||||||
|  | 			); | ||||||
|  | 		} else { | ||||||
|  | 			const style = window.getComputedStyle(objEl); | ||||||
|  | 			obj = Matter.Bodies.rectangle( | ||||||
|  | 				objEl.offsetLeft + (objEl.offsetWidth / 2), | ||||||
|  | 				objEl.offsetTop + (objEl.offsetHeight / 2), | ||||||
|  | 				objEl.offsetWidth, | ||||||
|  | 				objEl.offsetHeight, | ||||||
|  | 				{ | ||||||
|  | 					restitution:      0.1, | ||||||
|  | 					friction:         4, | ||||||
|  | 					frictionAir:      0, | ||||||
|  | 					frictionStatic:   50, | ||||||
|  | 					density:          100, | ||||||
|  | 					chamfer:          { radius: parseInt(style.borderRadius, 10) }, | ||||||
|  | 				} | ||||||
|  | 			); | ||||||
|  | 		} | ||||||
|  | 		objEl.id = obj.id; | ||||||
|  | 		objs.push(obj); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	Matter.World.add(engine.world, objs); | ||||||
|  | 
 | ||||||
|  | 	// Add mouse control
 | ||||||
|  | 
 | ||||||
|  | 	const mouse = Matter.Mouse.create(container); | ||||||
|  | 	const mouseConstraint = Matter.MouseConstraint.create(engine, { | ||||||
|  | 		mouse: mouse, | ||||||
|  | 		constraint: { | ||||||
|  | 			stiffness: 1, | ||||||
|  | 			render: { | ||||||
|  | 				visible: false | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	}); | ||||||
|  | 
 | ||||||
|  | 	Matter.World.add(engine.world, mouseConstraint); | ||||||
|  | 
 | ||||||
|  | 	// keep the mouse in sync with rendering
 | ||||||
|  | 	render.mouse = mouse; | ||||||
|  | 
 | ||||||
|  | 	for (const objEl of objEls) { | ||||||
|  | 		objEl.style.position = `absolute`; | ||||||
|  | 		objEl.style.top = 0; | ||||||
|  | 		objEl.style.left = 0; | ||||||
|  | 		objEl.style.margin = 0; | ||||||
|  | 		objEl.style.userSelect = 'none'; | ||||||
|  | 		objEl.style.willChange = 'transform'; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	window.requestAnimationFrame(update); | ||||||
|  | 
 | ||||||
|  | 	let stop = false; | ||||||
|  | 
 | ||||||
|  | 	function update() { | ||||||
|  | 		for (const objEl of objEls) { | ||||||
|  | 			const obj = objs.find(obj => obj.id.toString() === objEl.id.toString()); | ||||||
|  | 			if (obj == null) continue; | ||||||
|  | 
 | ||||||
|  | 			const x = (obj.position.x - objEl.offsetWidth / 2); | ||||||
|  | 			const y = (obj.position.y - objEl.offsetHeight / 2); | ||||||
|  | 			const angle = obj.angle; | ||||||
|  | 
 | ||||||
|  | 			objEl.style.transform = `translate(${x}px, ${y}px) rotate(${angle}rad)`; | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		if (!stop) { | ||||||
|  | 			window.requestAnimationFrame(update); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return { | ||||||
|  | 		stop: () => { | ||||||
|  | 			stop = true; | ||||||
|  | 			Matter.Runner.stop(runner); | ||||||
|  | 		} | ||||||
|  | 	}; | ||||||
|  | } | ||||||
							
								
								
									
										10
									
								
								yarn.lock
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								yarn.lock
									
										
									
									
									
								
							|  | @ -661,6 +661,11 @@ | ||||||
|     "@types/mdurl" "*" |     "@types/mdurl" "*" | ||||||
|     highlight.js "^9.7.0" |     highlight.js "^9.7.0" | ||||||
| 
 | 
 | ||||||
|  | "@types/matter-js@0.14.7": | ||||||
|  |   version "0.14.7" | ||||||
|  |   resolved "https://registry.yarnpkg.com/@types/matter-js/-/matter-js-0.14.7.tgz#b816f1e7b441ee7499027f9566e4fb5baea637b3" | ||||||
|  |   integrity sha512-HLUhVTUoKsibpPZ2tCzoCC/f/UYRWPP9WCOUh5F61BlrUESFV5fE7eKq/CmdoEGkNrLW9v407zYlfrTc9hnGIw== | ||||||
|  | 
 | ||||||
| "@types/mdurl@*": | "@types/mdurl@*": | ||||||
|   version "1.0.2" |   version "1.0.2" | ||||||
|   resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" |   resolved "https://registry.yarnpkg.com/@types/mdurl/-/mdurl-1.0.2.tgz#e2ce9d83a613bacf284c7be7d491945e39e1f8e9" | ||||||
|  | @ -6116,6 +6121,11 @@ material-colors@^1.0.0: | ||||||
|   resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" |   resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46" | ||||||
|   integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== |   integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg== | ||||||
| 
 | 
 | ||||||
|  | matter-js@0.14.2: | ||||||
|  |   version "0.14.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/matter-js/-/matter-js-0.14.2.tgz#8169af9e06fdc356ba9e72b49624eb329839883b" | ||||||
|  |   integrity sha512-3ttVT8cJlQnGRjBa8MyVrGyvGmnmOkZ3YsyemIw+KwEEdVi70mo32FH1Eta2b3GfdDJFbMDRqyMQt4heNKBUEA== | ||||||
|  | 
 | ||||||
| mdn-data@2.0.4: | mdn-data@2.0.4: | ||||||
|   version "2.0.4" |   version "2.0.4" | ||||||
|   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" |   resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b" | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue