mirror of
https://iceshrimp.dev/limepotato/jormungandr-patches.git
synced 2024-11-22 02:57:25 -07:00
143 lines
3.9 KiB
Diff
143 lines
3.9 KiB
Diff
From d41a81f60051c197ca98db912d706745edd002d7 Mon Sep 17 00:00:00 2001
|
|
From: limepotato <limepot@protonmail.ch>
|
|
Date: Sun, 14 Jul 2024 06:11:58 -0600
|
|
Subject: [PATCH 4/5] Follow Mouse MFM
|
|
|
|
---
|
|
.../client/src/components/CkFollowMouse.vue | 86 +++++++++++++++++++
|
|
packages/client/src/components/mfm.ts | 19 ++++
|
|
2 files changed, 105 insertions(+)
|
|
create mode 100644 packages/client/src/components/CkFollowMouse.vue
|
|
|
|
diff --git a/packages/client/src/components/CkFollowMouse.vue b/packages/client/src/components/CkFollowMouse.vue
|
|
new file mode 100644
|
|
index 000000000..ce7e3c79a
|
|
--- /dev/null
|
|
+++ b/packages/client/src/components/CkFollowMouse.vue
|
|
@@ -0,0 +1,86 @@
|
|
+<!--
|
|
+SPDX-FileCopyrightText: leah and other Cutiekey contributors
|
|
+SPDX-License-Identifier: AGPL-3.0-only
|
|
+-->
|
|
+
|
|
+<template>
|
|
+<span ref="container" :class="$style.root">
|
|
+ <span ref="el" :class="$style.inner" style="position: absolute">
|
|
+ <slot></slot>
|
|
+ </span>
|
|
+</span>
|
|
+</template>
|
|
+
|
|
+<script lang="ts" setup>
|
|
+import { onMounted, onUnmounted, shallowRef } from 'vue';
|
|
+const el = shallowRef<HTMLElement>();
|
|
+const container = shallowRef<HTMLElement>();
|
|
+const props = defineProps({
|
|
+ x: {
|
|
+ type: Boolean,
|
|
+ default: true,
|
|
+ },
|
|
+ y: {
|
|
+ type: Boolean,
|
|
+ default: true,
|
|
+ },
|
|
+ speed: {
|
|
+ type: String,
|
|
+ default: '0.1s',
|
|
+ },
|
|
+ rotateByVelocity: {
|
|
+ type: Boolean,
|
|
+ default: true,
|
|
+ },
|
|
+});
|
|
+
|
|
+let lastX = 0;
|
|
+let lastY = 0;
|
|
+let oldAngle = 0;
|
|
+
|
|
+function lerp(a, b, alpha) {
|
|
+ return a + alpha * (b - a);
|
|
+}
|
|
+
|
|
+const updatePosition = (mouseEvent: MouseEvent) => {
|
|
+ if (el.value && container.value) {
|
|
+ const containerRect = container.value.getBoundingClientRect();
|
|
+ const newX = mouseEvent.clientX - containerRect.left;
|
|
+ const newY = mouseEvent.clientY - containerRect.top;
|
|
+ let transform = `translate(calc(${props.x ? newX : 0}px - 50%), calc(${props.y ? newY : 0}px - 50%))`;
|
|
+ if (props.rotateByVelocity) {
|
|
+ const deltaX = newX - lastX;
|
|
+ const deltaY = newY - lastY;
|
|
+ const angle = lerp(
|
|
+ oldAngle,
|
|
+ Math.atan2(deltaY, deltaX) * (180 / Math.PI),
|
|
+ 0.1,
|
|
+ );
|
|
+ transform += ` rotate(${angle}deg)`;
|
|
+ oldAngle = angle;
|
|
+ }
|
|
+ el.value.style.transform = transform;
|
|
+ el.value.style.transition = `transform ${props.speed}`;
|
|
+ lastX = newX;
|
|
+ lastY = newY;
|
|
+ }
|
|
+};
|
|
+
|
|
+onMounted(() => {
|
|
+ window.addEventListener('mousemove', updatePosition);
|
|
+});
|
|
+
|
|
+onUnmounted(() => {
|
|
+ window.removeEventListener('mousemove', updatePosition);
|
|
+});
|
|
+</script>
|
|
+
|
|
+<style lang="scss" module>
|
|
+.root {
|
|
+ position: relative;
|
|
+ display: inline-block;
|
|
+}
|
|
+.inner {
|
|
+ transform-origin: center center;
|
|
+}
|
|
+</style>
|
|
diff --git a/packages/client/src/components/mfm.ts b/packages/client/src/components/mfm.ts
|
|
index 382b1b9e7..25faf680b 100644
|
|
--- a/packages/client/src/components/mfm.ts
|
|
+++ b/packages/client/src/components/mfm.ts
|
|
@@ -1,6 +1,7 @@
|
|
import { defineComponent, h } from "vue";
|
|
import * as mfm from "@transfem-org/sfm-js";
|
|
import type { VNode } from "vue";
|
|
+import CkFollowMouse from "./CkFollowMouse.vue";
|
|
import MkUrl from "@/components/global/MkUrl.vue";
|
|
import MkTime from '@/components/global/MkTime.vue';
|
|
import MkLink from "@/components/MkLink.vue";
|
|
@@ -275,6 +276,24 @@ export default defineComponent({
|
|
style = `transform: ${rotate}(${degrees}deg); transform-origin: center center;`;
|
|
break;
|
|
}
|
|
+ case 'followmouse': {
|
|
+ // Make sure advanced MFM is on and that reduced motion is off
|
|
+
|
|
+ let x = (!!token.props.args.x);
|
|
+ let y = (!!token.props.args.y);
|
|
+
|
|
+ if (!x && !y) {
|
|
+ x = true;
|
|
+ y = true;
|
|
+ }
|
|
+
|
|
+ return h(CkFollowMouse, {
|
|
+ x: x,
|
|
+ y: y,
|
|
+ speed: validTime(token.props.args.speed) ?? '0.1s',
|
|
+ rotateByVelocity: !!token.props.args.rotateByVelocity,
|
|
+ }, genEl(token.children));
|
|
+ }
|
|
case "position": {
|
|
const x = parseFloat(token.props.args.x ?? "0");
|
|
const y = parseFloat(token.props.args.y ?? "0");
|
|
--
|
|
2.45.2
|
|
|