@maas/vue-equipment 0.10.7 → 0.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@maas/vue-equipment",
3
3
  "configKey": "vueEquipment",
4
- "version": "0.10.6"
4
+ "version": "0.11.0"
5
5
  }
@@ -36,17 +36,24 @@ const functions = [
36
36
  docs: "https://maas.egineering/vue-equipment/plugins/MagicModal/",
37
37
  description: "modal"
38
38
  },
39
+ {
40
+ name: "MagicNoise",
41
+ "package": "plugins",
42
+ lastUpdated: 1697183651000,
43
+ docs: "https://maas.egineering/vue-equipment/plugins/MagicNoise/",
44
+ description: "noise"
45
+ },
39
46
  {
40
47
  name: "MagicPlayer",
41
48
  "package": "plugins",
42
- lastUpdated: 1695376679000,
49
+ lastUpdated: 1697181673000,
43
50
  docs: "https://maas.egineering/vue-equipment/plugins/MagicPlayer/",
44
51
  description: "player"
45
52
  },
46
53
  {
47
54
  name: "MagicScroll",
48
55
  "package": "plugins",
49
- lastUpdated: 1695376679000,
56
+ lastUpdated: 1697181673000,
50
57
  docs: "https://maas.egineering/vue-equipment/plugins/MagicScroll/",
51
58
  description: "scroll"
52
59
  },
@@ -1,6 +1,6 @@
1
1
  <template>
2
- <div class="magic-marquee">
3
- <div class="magic-marquee__track" ref="parentRef">
2
+ <div class="magic-marquee" ref="parentRef">
3
+ <div class="magic-marquee__track">
4
4
  <div class="magic-marquee__content" ref="childRef">
5
5
  <slot />
6
6
  </div>
@@ -0,0 +1,5 @@
1
+ import type { Plugin } from 'vue';
2
+ import MagicNoise from './src/components/MagicNoise.vue.js';
3
+ import { useNoiseApi } from './src/composables/useNoiseApi.js';
4
+ declare const MagicNoisePlugin: Plugin;
5
+ export { MagicNoisePlugin, MagicNoise, useNoiseApi };
@@ -0,0 +1,8 @@
1
+ import MagicNoise from "./src/components/MagicNoise.vue";
2
+ import { useNoiseApi } from "./src/composables/useNoiseApi.mjs";
3
+ const MagicNoisePlugin = {
4
+ install: (app) => {
5
+ app.component("MagicNoise", MagicNoise);
6
+ }
7
+ };
8
+ export { MagicNoisePlugin, MagicNoise, useNoiseApi };
File without changes
@@ -0,0 +1,23 @@
1
+ import {
2
+ defineNuxtModule,
3
+ createResolver,
4
+ addComponent,
5
+ addImports
6
+ } from "@nuxt/kit";
7
+ export default defineNuxtModule({
8
+ meta: {
9
+ name: "@maas/vue-equipment/MagicNoise"
10
+ },
11
+ setup() {
12
+ const resolver = createResolver(import.meta.url);
13
+ addComponent({
14
+ filePath: resolver.resolve("src/components/MagicNoise.vue"),
15
+ name: "MagicNoise",
16
+ global: true
17
+ });
18
+ addImports({
19
+ from: "@maas/vue-equipment/plugins/MagicNoise",
20
+ name: "useNoiseApi"
21
+ });
22
+ }
23
+ });
@@ -0,0 +1,121 @@
1
+ <template>
2
+ <div class="magic-noise" :class="{ '-loading': !isReady }">
3
+ <div :class="{ '-loading': !isReady }" class="magic-noise__inner">
4
+ <canvas ref="canvasRef" class="magic-noise__canvas" />
5
+ <canvas ref="offCanvasRef" class="magic-noise__off-canvas" />
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script lang="ts" setup>
11
+ import { onMounted, onUnmounted, computed, watch, ref, shallowRef } from 'vue'
12
+ import { useResizeObserver, useDebounceFn } from '@vueuse/core'
13
+ import { useNoiseApi } from '../composables/useNoiseApi'
14
+
15
+ interface Props {
16
+ pixelSize?: number
17
+ tiles?: number
18
+ fps?: number
19
+ color?: string
20
+ pause?: boolean
21
+ }
22
+
23
+ const props = withDefaults(defineProps<Props>(), {
24
+ pixelSize: 2,
25
+ tiles: 32,
26
+ fps: 8,
27
+ color: '#000',
28
+ pause: false,
29
+ })
30
+
31
+ const canvasRef = shallowRef<HTMLCanvasElement | undefined>(undefined)
32
+ const offCanvasRef = shallowRef<HTMLCanvasElement | undefined>(undefined)
33
+
34
+ const options = computed(() => {
35
+ return {
36
+ pixelSize: props.pixelSize,
37
+ tiles: props.tiles,
38
+ fps: props.fps,
39
+ color: props.color,
40
+ }
41
+ })
42
+
43
+ const noiseApi = useNoiseApi({ canvasRef, offCanvasRef, options })
44
+ const {
45
+ initialize,
46
+ drawControls,
47
+ transferControls,
48
+ throttledDraw,
49
+ throttledRotateAndTransfer,
50
+ isReady,
51
+ } = noiseApi
52
+
53
+ useResizeObserver(canvasRef, useDebounceFn(initialize, 100))
54
+
55
+ watch(
56
+ () => props.pause,
57
+ (pause) => {
58
+ if (pause) {
59
+ drawControls.value?.pause()
60
+ transferControls.value?.pause()
61
+ } else {
62
+ drawControls.value?.resume()
63
+ transferControls.value?.resume()
64
+ }
65
+ },
66
+ )
67
+
68
+ onMounted(() => {
69
+ throttledDraw()
70
+ throttledRotateAndTransfer()
71
+ })
72
+
73
+ onUnmounted(() => {
74
+ isReady.value = false
75
+ transferControls.value?.pause()
76
+ drawControls.value?.pause()
77
+ })
78
+ </script>
79
+
80
+ <style lang="css">
81
+ :root {
82
+ --magic-noise-loading-background: #000;
83
+ --magic-noise-loading-transition: color 300ms ease, opacity 300ms ease;
84
+ }
85
+
86
+ .magic-noise {
87
+ position: relative;
88
+ user-select: none;
89
+ transition: var(--magic-noise-loading-transition);
90
+ &.-loading {
91
+ background: var(--magic-noise-loading-background);
92
+ }
93
+ }
94
+
95
+ .magic-noise__inner {
96
+ position: relative;
97
+ width: 100%;
98
+ height: 100%;
99
+ transition: var(--magic-noise-loading-transition);
100
+ &.-loading {
101
+ opacity: 0;
102
+ }
103
+ }
104
+
105
+ .magic-noise__canvas {
106
+ position: absolute;
107
+ width: 100%;
108
+ height: 100%;
109
+ top: 0;
110
+ left: 0;
111
+ object-fit: cover;
112
+ }
113
+
114
+ .magic-noise__off-canvas {
115
+ position: absolute;
116
+ top: 0;
117
+ left: 0;
118
+ visibility: hidden;
119
+ pointer-events: none;
120
+ }
121
+ </style>
@@ -0,0 +1,50 @@
1
+ declare const _default: import("vue").DefineComponent<{
2
+ pause: {
3
+ type: import("vue").PropType<boolean>;
4
+ default: boolean;
5
+ };
6
+ pixelSize: {
7
+ type: import("vue").PropType<number>;
8
+ default: number;
9
+ };
10
+ tiles: {
11
+ type: import("vue").PropType<number>;
12
+ default: number;
13
+ };
14
+ fps: {
15
+ type: import("vue").PropType<number>;
16
+ default: number;
17
+ };
18
+ color: {
19
+ type: import("vue").PropType<string>;
20
+ default: string;
21
+ };
22
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
23
+ pause: {
24
+ type: import("vue").PropType<boolean>;
25
+ default: boolean;
26
+ };
27
+ pixelSize: {
28
+ type: import("vue").PropType<number>;
29
+ default: number;
30
+ };
31
+ tiles: {
32
+ type: import("vue").PropType<number>;
33
+ default: number;
34
+ };
35
+ fps: {
36
+ type: import("vue").PropType<number>;
37
+ default: number;
38
+ };
39
+ color: {
40
+ type: import("vue").PropType<string>;
41
+ default: string;
42
+ };
43
+ }>>, {
44
+ pause: boolean;
45
+ pixelSize: number;
46
+ tiles: number;
47
+ fps: number;
48
+ color: string;
49
+ }, {}>;
50
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import { type Ref, type MaybeRef } from 'vue';
2
+ import type { RafControls } from '../types.js';
3
+ type UseNoiseApiArgs = {
4
+ canvasRef: Ref<HTMLCanvasElement | undefined>;
5
+ offCanvasRef: Ref<HTMLCanvasElement | undefined>;
6
+ options?: MaybeRef<{
7
+ pixelSize?: number;
8
+ tiles?: number;
9
+ color?: string;
10
+ fps?: number;
11
+ }>;
12
+ };
13
+ export declare function useNoiseApi({ canvasRef, offCanvasRef, options, }: UseNoiseApiArgs): {
14
+ initialize: () => void;
15
+ draw: () => void;
16
+ rotateAndTransfer: () => void;
17
+ throttledDraw: () => void;
18
+ throttledRotateAndTransfer: () => void;
19
+ isReady: Ref<boolean>;
20
+ drawControls: import("vue").ShallowRef<RafControls | undefined>;
21
+ transferControls: import("vue").ShallowRef<RafControls | undefined>;
22
+ };
23
+ export {};
@@ -0,0 +1,182 @@
1
+ import { shallowRef, ref, reactive } from "vue";
2
+ import { defu } from "defu";
3
+ import {
4
+ useElementSize,
5
+ useDevicePixelRatio,
6
+ useThrottleFn,
7
+ useRafFn
8
+ } from "@vueuse/core";
9
+ const defaultOptions = {
10
+ pixelSize: 2,
11
+ tiles: 32,
12
+ fps: 12,
13
+ color: "white"
14
+ };
15
+ export function useNoiseApi({
16
+ canvasRef,
17
+ offCanvasRef,
18
+ options
19
+ }) {
20
+ const tiles = shallowRef([]);
21
+ const pixels = shallowRef([]);
22
+ const isReady = ref(false);
23
+ let context = shallowRef(null);
24
+ let offContext = shallowRef(null);
25
+ const { width, height } = useElementSize(canvasRef);
26
+ const { pixelRatio } = useDevicePixelRatio();
27
+ const drawControls = shallowRef(void 0);
28
+ const transferControls = shallowRef(void 0);
29
+ const dimensions = reactive({
30
+ width: 0,
31
+ height: 0,
32
+ offWidth: 0,
33
+ offHeight: 0
34
+ });
35
+ const mappedOptions = defu(options, defaultOptions);
36
+ function findBiggerNumber(target, divisor) {
37
+ const remainder = target % divisor;
38
+ if (remainder === 0) {
39
+ return target;
40
+ }
41
+ const biggerNumber = Math.ceil(target / divisor) * divisor;
42
+ return biggerNumber;
43
+ }
44
+ function resetContexts() {
45
+ context.value = null;
46
+ offContext.value = null;
47
+ }
48
+ function resetPixels() {
49
+ pixels.value = [];
50
+ }
51
+ function calculatePixels({
52
+ width: width2,
53
+ height: height2,
54
+ pixelSize,
55
+ rotation
56
+ }) {
57
+ if (pixelSize <= 0 || pixelSize <= 0) {
58
+ return [];
59
+ }
60
+ const pixels2 = [];
61
+ for (let y = 0; y < height2; y += pixelSize) {
62
+ for (let x = 0; x < width2; x += pixelSize) {
63
+ let radian;
64
+ if (rotation) {
65
+ const angle = getRandomRotationAngle();
66
+ radian = getRadianFromAngle(angle);
67
+ }
68
+ const pixel = {
69
+ w: pixelSize,
70
+ h: pixelSize,
71
+ x,
72
+ y,
73
+ r: radian
74
+ };
75
+ pixels2.push(pixel);
76
+ }
77
+ }
78
+ return pixels2;
79
+ }
80
+ function calculate() {
81
+ const offCanvasHeight = offCanvasRef.value?.height;
82
+ const offCanvasWidth = offCanvasRef.value?.width;
83
+ if (!offCanvasHeight || !offCanvasWidth)
84
+ return;
85
+ pixels.value = calculatePixels({
86
+ width: offCanvasWidth,
87
+ height: offCanvasHeight,
88
+ pixelSize: mappedOptions.pixelSize * pixelRatio.value
89
+ });
90
+ tiles.value = calculatePixels({
91
+ width: dimensions.width,
92
+ height: dimensions.height,
93
+ pixelSize: dimensions.offWidth,
94
+ rotation: true
95
+ });
96
+ isReady.value = true;
97
+ draw();
98
+ rotateAndTransfer();
99
+ }
100
+ function initialize() {
101
+ resetContexts();
102
+ if (!canvasRef.value || !offCanvasRef.value)
103
+ return;
104
+ const maxCanvasDim = Math.max(width.value, height.value) * pixelRatio.value;
105
+ const maxOffCanvasDim = maxCanvasDim / Math.sqrt(mappedOptions.tiles);
106
+ const adjustedOffCanvasDim = findBiggerNumber(
107
+ maxOffCanvasDim,
108
+ mappedOptions.pixelSize
109
+ );
110
+ canvasRef.value.width = dimensions.width = maxCanvasDim;
111
+ canvasRef.value.height = dimensions.height = maxCanvasDim;
112
+ offCanvasRef.value.width = dimensions.offWidth = adjustedOffCanvasDim;
113
+ offCanvasRef.value.height = dimensions.offHeight = adjustedOffCanvasDim;
114
+ context.value = canvasRef.value.getContext("2d", {
115
+ alpha: false
116
+ });
117
+ offContext.value = offCanvasRef.value.getContext("2d", {
118
+ alpha: false,
119
+ willReadFrequently: true
120
+ });
121
+ resetPixels();
122
+ calculate();
123
+ }
124
+ function getRandomRotationAngle() {
125
+ return [0, 90, 180, 270][Math.floor(Math.random() * 4)];
126
+ }
127
+ function getRadianFromAngle(angle) {
128
+ return angle * Math.PI / 180;
129
+ }
130
+ function rotateAndTransfer() {
131
+ if (!canvasRef.value || !offCanvasRef.value || !context.value || !offContext.value) {
132
+ return;
133
+ }
134
+ context.value.clearRect(0, 0, dimensions.width, dimensions.height);
135
+ for (const tile of tiles.value) {
136
+ context.value.translate(tile.x + tile.w / 2, tile.y + tile.h / 2);
137
+ context.value.rotate(tile.r);
138
+ context.value.drawImage(offCanvasRef.value, -tile.w / 2, -tile.h / 2);
139
+ context.value.resetTransform();
140
+ }
141
+ }
142
+ function throttledRotateAndTransfer() {
143
+ transferControls.value?.pause();
144
+ const throttled = useThrottleFn(() => {
145
+ rotateAndTransfer();
146
+ }, 600 / mappedOptions.fps);
147
+ transferControls.value = useRafFn(throttled);
148
+ }
149
+ function draw() {
150
+ if (!offContext.value || !offCanvasRef.value)
151
+ return;
152
+ offContext.value.clearRect(
153
+ 0,
154
+ 0,
155
+ offCanvasRef.value.width,
156
+ offCanvasRef.value.height
157
+ );
158
+ for (const pixel of pixels.value) {
159
+ if (Math.random() > 0.5) {
160
+ offContext.value.fillStyle = mappedOptions.color;
161
+ offContext.value.fillRect(pixel.x, pixel.y, pixel.w, pixel.h);
162
+ }
163
+ }
164
+ }
165
+ function throttledDraw() {
166
+ drawControls.value?.pause();
167
+ const throttled = useThrottleFn(() => {
168
+ draw();
169
+ }, 600 / mappedOptions.fps);
170
+ drawControls.value = useRafFn(throttled);
171
+ }
172
+ return {
173
+ initialize,
174
+ draw,
175
+ rotateAndTransfer,
176
+ throttledDraw,
177
+ throttledRotateAndTransfer,
178
+ isReady,
179
+ drawControls,
180
+ transferControls
181
+ };
182
+ }
@@ -0,0 +1,9 @@
1
+ import type { Pausable } from '@vueuse/core';
2
+ export type Pixel = {
3
+ w: number;
4
+ h: number;
5
+ x: number;
6
+ y: number;
7
+ r?: number;
8
+ };
9
+ export type RafControls = Pick<Pausable, 'pause' | 'resume'>;
File without changes
@@ -8,7 +8,8 @@ import { usePlayerApi } from './src/composables/usePlayerApi.js';
8
8
  import { useProvidePlayer, useInjectPlayer } from './src/composables/usePlayer.js';
9
9
  import { useProvideControls, useInjectControls } from './src/composables/useControls.js';
10
10
  import { useRuntimeSourceProvider } from './src/composables/useRuntimeSourceProvider.js';
11
+ import { MediaApiInjectionKey, PlayerApiInjectionKey, RuntimeSourceProviderInjectionKey, ControlsApiInjectionKey } from './src/symbols.js';
11
12
  declare const MagicPlayerPlugin: Plugin;
12
- export { MagicPlayerPlugin, MagicPlayer, MagicPlayerControls, MagicPlayerTimeline, MagicPlayerMuxPopover, useMediaApi, usePlayerApi, useRuntimeSourceProvider, useProvidePlayer, useInjectPlayer, useProvideControls, useInjectControls, };
13
+ export { MagicPlayerPlugin, MagicPlayer, MagicPlayerControls, MagicPlayerTimeline, MagicPlayerMuxPopover, useMediaApi, usePlayerApi, useRuntimeSourceProvider, useProvidePlayer, useInjectPlayer, useProvideControls, useInjectControls, MediaApiInjectionKey, PlayerApiInjectionKey, RuntimeSourceProviderInjectionKey, ControlsApiInjectionKey, };
13
14
  export * from './src/symbols.js';
14
15
  export type * from './src/types';
@@ -10,6 +10,12 @@ import {
10
10
  useInjectControls
11
11
  } from "./src/composables/useControls.mjs";
12
12
  import { useRuntimeSourceProvider } from "./src/composables/useRuntimeSourceProvider.mjs";
13
+ import {
14
+ MediaApiInjectionKey,
15
+ PlayerApiInjectionKey,
16
+ RuntimeSourceProviderInjectionKey,
17
+ ControlsApiInjectionKey
18
+ } from "./src/symbols/index.mjs";
13
19
  const MagicPlayerPlugin = {
14
20
  install: (app) => {
15
21
  app.component("MagicPlayer", MagicPlayer);
@@ -30,6 +36,10 @@ export {
30
36
  useProvidePlayer,
31
37
  useInjectPlayer,
32
38
  useProvideControls,
33
- useInjectControls
39
+ useInjectControls,
40
+ MediaApiInjectionKey,
41
+ PlayerApiInjectionKey,
42
+ RuntimeSourceProviderInjectionKey,
43
+ ControlsApiInjectionKey
34
44
  };
35
45
  export * from "./src/symbols/index.mjs";
@@ -6,8 +6,9 @@ import MagicScrollCollision from './src/components/MagicScrollCollision.vue.js';
6
6
  import { useCollisionEmitter } from './src/composables/useCollisionEmitter.js';
7
7
  import { useScrollApi } from './src/composables/useScrollApi.js';
8
8
  import { useCollisionDetect } from './src/composables/useCollisionDetect.js';
9
+ import { ScrollParentKey, ScrollPositionKey, ScrollProgressKey } from './src/symbols.js';
9
10
  import type { Plugin } from 'vue';
10
11
  declare const MagicScrollPlugin: Plugin;
11
- export { MagicScrollPlugin, MagicScrollProvider, MagicScrollScene, MagicScrollTransform, MagicScrollMotion, MagicScrollCollision, useCollisionEmitter, useScrollApi, useCollisionDetect, };
12
+ export { MagicScrollPlugin, MagicScrollProvider, MagicScrollScene, MagicScrollTransform, MagicScrollMotion, MagicScrollCollision, useCollisionEmitter, useScrollApi, useCollisionDetect, ScrollParentKey, ScrollPositionKey, ScrollProgressKey, };
12
13
  export * from './src/symbols.js';
13
14
  export type * from './src/types';
@@ -6,6 +6,11 @@ import MagicScrollCollision from "./src/components/MagicScrollCollision.vue";
6
6
  import { useCollisionEmitter } from "./src/composables/useCollisionEmitter.mjs";
7
7
  import { useScrollApi } from "./src/composables/useScrollApi.mjs";
8
8
  import { useCollisionDetect } from "./src/composables/useCollisionDetect.mjs";
9
+ import {
10
+ ScrollParentKey,
11
+ ScrollPositionKey,
12
+ ScrollProgressKey
13
+ } from "./src/symbols/index.mjs";
9
14
  const MagicScrollPlugin = {
10
15
  install: (app) => {
11
16
  app.component("MagicScrollProvider", MagicScrollProvider);
@@ -24,6 +29,9 @@ export {
24
29
  MagicScrollCollision,
25
30
  useCollisionEmitter,
26
31
  useScrollApi,
27
- useCollisionDetect
32
+ useCollisionDetect,
33
+ ScrollParentKey,
34
+ ScrollPositionKey,
35
+ ScrollProgressKey
28
36
  };
29
37
  export * from "./src/symbols/index.mjs";
@@ -1,6 +1,7 @@
1
+ export * from './MagicConsent/index.js';
1
2
  export * from './MagicMarquee/index.js';
2
3
  export * from './MagicModal/index.js';
4
+ export * from './MagicNoise/index.js';
3
5
  export * from './MagicPlayer/index.js';
4
6
  export * from './MagicScroll/index.js';
5
7
  export * from './MagicToast/index.js';
6
- export * from './MagicConsent/index.js';
@@ -1,6 +1,7 @@
1
+ export * from "./MagicConsent/index.mjs";
1
2
  export * from "./MagicMarquee/index.mjs";
2
3
  export * from "./MagicModal/index.mjs";
4
+ export * from "./MagicNoise/index.mjs";
3
5
  export * from "./MagicPlayer/index.mjs";
4
6
  export * from "./MagicScroll/index.mjs";
5
7
  export * from "./MagicToast/index.mjs";
6
- export * from "./MagicConsent/index.mjs";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@maas/vue-equipment",
3
3
  "description": "A magic collection of Vue composables, plugins, components and directives",
4
- "version": "0.10.7",
4
+ "version": "0.11.1",
5
5
  "author": "Robin Scholz <https://github.com/robinscholz>, Christoph Jeworutzki <https://github.com/ChristophJeworutzki>",
6
6
  "devDependencies": {
7
7
  "@antfu/ni": "^0.21.5",