waveform-analysis 0.1.74 → 0.1.75
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.
- package/README.md +246 -39
- package/dist/assets/workerRuntime-BJiRmIZD.js +2446 -0
- package/dist/index.cjs +1 -2
- package/dist/index.js +1 -7119
- package/dist/style.css +1 -1
- package/dist/types/animation/WaveformAnimationController.d.ts +30 -0
- package/dist/types/animation/core/Animation.d.ts +13 -0
- package/dist/types/animation/core/Animator.d.ts +23 -0
- package/dist/types/animation/core/easing.d.ts +3 -0
- package/dist/types/animation/core/errors.d.ts +4 -0
- package/dist/types/animation/core/handle.d.ts +7 -0
- package/dist/types/animation/core/owner.d.ts +3 -0
- package/dist/types/animation/core/propertyGroups.d.ts +17 -0
- package/dist/types/animation/core/task.d.ts +29 -0
- package/dist/types/animation/core/types.d.ts +74 -0
- package/dist/types/animation/core/validation.d.ts +30 -0
- package/dist/types/animation/core/values.d.ts +8 -0
- package/dist/types/animation/presets/annotation.d.ts +4 -0
- package/dist/types/animation/presets/lineDrawing.d.ts +7 -0
- package/dist/types/animation/presets/shared.d.ts +14 -0
- package/dist/types/animation/presets/transitions.d.ts +4 -0
- package/dist/types/animation/types.d.ts +84 -0
- package/dist/types/components/WaveformChart.vue.d.ts +3 -2
- package/dist/types/components/animation/annotationPresentation.d.ts +17 -0
- package/dist/types/components/animation/chartExportVersion.d.ts +2 -0
- package/dist/types/components/animation/config.d.ts +31 -0
- package/dist/types/components/animation/context.d.ts +20 -0
- package/dist/types/components/animation/geometry.d.ts +10 -0
- package/dist/types/components/animation/paginationPresentation.d.ts +13 -0
- package/dist/types/components/animation/pathBuffer.d.ts +4 -0
- package/dist/types/components/animation/trackPresentation.d.ts +35 -0
- package/dist/types/components/animation/useWaveformAnimations.d.ts +27 -0
- package/dist/types/components/annotation/WaveformAnnotationContextMenu.vue.d.ts +2 -2
- package/dist/types/components/annotation/types.d.ts +7 -0
- package/dist/types/components/controls/useChartImageExport.d.ts +2 -0
- package/dist/types/components/core/types.d.ts +8 -0
- package/dist/types/components/core/useWaveformChartController.d.ts +25 -0
- package/dist/types/components/core/useWaveformRenderSampling.d.ts +2 -0
- package/dist/types/components/core/waveformChartTypes.d.ts +2 -1
- package/dist/types/components/rendering/WaveformSeriesLayer.vue.d.ts +1 -0
- package/dist/types/components/rendering/WaveformTrack.vue.d.ts +4 -3
- package/dist/types/components/rendering/updateAxis.d.ts +5 -0
- package/dist/types/components/rendering/updateGrid.d.ts +3 -0
- package/dist/types/components/rendering/yAxisTickVisibility.d.ts +2 -0
- package/dist/types/components/utils/assignElement.d.ts +2 -0
- package/dist/types/index.d.ts +9 -0
- package/dist/types/views/AnimationDemo.vue.d.ts +3 -0
- package/package.json +5 -2
- package/src/DemoRouterApp.vue +1 -0
- package/src/animation/WaveformAnimationController.ts +328 -0
- package/src/animation/core/Animation.ts +37 -0
- package/src/animation/core/Animator.ts +200 -0
- package/src/animation/core/easing.ts +74 -0
- package/src/animation/core/errors.ts +24 -0
- package/src/animation/core/handle.ts +34 -0
- package/src/animation/core/owner.ts +9 -0
- package/src/animation/core/propertyGroups.ts +143 -0
- package/src/animation/core/task.ts +153 -0
- package/src/animation/core/types.ts +81 -0
- package/src/animation/core/validation.ts +173 -0
- package/src/animation/core/values.ts +38 -0
- package/src/animation/presets/annotation.ts +66 -0
- package/src/animation/presets/lineDrawing.ts +51 -0
- package/src/animation/presets/shared.ts +58 -0
- package/src/animation/presets/transitions.ts +77 -0
- package/src/animation/types.ts +81 -0
- package/src/components/WaveformChart.vue +1 -0
- package/src/components/WaveformChartView.vue +13 -4
- package/src/components/animation/annotationPresentation.ts +145 -0
- package/src/components/animation/chartExportVersion.ts +5 -0
- package/src/components/animation/config.ts +87 -0
- package/src/components/animation/context.ts +56 -0
- package/src/components/animation/geometry.ts +148 -0
- package/src/components/animation/paginationPresentation.ts +114 -0
- package/src/components/animation/pathBuffer.ts +61 -0
- package/src/components/animation/trackPresentation.ts +172 -0
- package/src/components/animation/useWaveformAnimations.ts +420 -0
- package/src/components/annotation/WaveformAnnotationLayer.vue +43 -30
- package/src/components/annotation/types.ts +3 -0
- package/src/components/controls/useChartImageExport.ts +4 -0
- package/src/components/core/trackLayoutBuilder.ts +9 -18
- package/src/components/core/types.ts +4 -0
- package/src/components/core/useWaveformChartController.ts +24 -20
- package/src/components/core/useWaveformRenderSampling.ts +23 -1
- package/src/components/core/waveformChartTypes.ts +2 -1
- package/src/components/rendering/WaveformSeriesLayer.vue +13 -1
- package/src/components/rendering/WaveformTrack.vue +6 -1
- package/src/components/rendering/WaveformTrackAxes.vue +64 -51
- package/src/components/rendering/WaveformTrackBackdrop.vue +35 -49
- package/src/components/rendering/updateAxis.ts +57 -0
- package/src/components/rendering/updateGrid.ts +42 -0
- package/src/components/rendering/yAxisTickVisibility.ts +45 -18
- package/src/components/utils/assignElement.ts +7 -0
- package/src/index.ts +52 -0
- package/src/router.ts +1 -0
- package/src/views/AnimationDemo.vue +129 -0
- package/dist/assets/workerRuntime-5p-EI-GL.js +0 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { sameTick } from '../core/yAxisPadding'
|
|
2
2
|
import { formatYAxisTickLabel } from '../core/layout'
|
|
3
|
+
import { updateSvgAttribute } from './updateAxis'
|
|
3
4
|
|
|
4
5
|
interface Box {
|
|
5
6
|
left: number
|
|
@@ -42,14 +43,25 @@ export function linesOverlap(a: number, b: number, widthA = 1, widthB = 1): bool
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
function hide(element: Element) {
|
|
45
|
-
element
|
|
46
|
-
element
|
|
46
|
+
updateSvgAttribute(element, 'display', 'none')
|
|
47
|
+
updateSvgAttribute(element, 'data-maximum-hidden', 'true')
|
|
47
48
|
}
|
|
48
49
|
|
|
49
50
|
function strokeWidth(element: Element): number {
|
|
50
51
|
return Number.parseFloat(getComputedStyle(element).strokeWidth) || 1
|
|
51
52
|
}
|
|
52
53
|
|
|
54
|
+
const pending = new WeakSet<SVGSVGElement>()
|
|
55
|
+
/** Coalesce sibling axes after Vue's current DOM patch, without adding a late animation frame. */
|
|
56
|
+
export function scheduleMaximumTickVisibility(svg: SVGSVGElement) {
|
|
57
|
+
if (pending.has(svg)) return
|
|
58
|
+
pending.add(svg)
|
|
59
|
+
queueMicrotask(() => {
|
|
60
|
+
pending.delete(svg)
|
|
61
|
+
updateMaximumTickVisibility(svg)
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
53
65
|
function formatCompactLabels(svg: SVGSVGElement) {
|
|
54
66
|
svg.querySelectorAll<SVGTextElement>('text[data-axis-maximum-label]').forEach((maximum) => {
|
|
55
67
|
const axis = maximum.parentElement!.parentElement!
|
|
@@ -64,13 +76,14 @@ function formatCompactLabels(svg: SVGSVGElement) {
|
|
|
64
76
|
Number(axis.getAttribute('data-label-domain-max')),
|
|
65
77
|
]
|
|
66
78
|
labels.forEach((text) => {
|
|
67
|
-
|
|
79
|
+
const label = formatYAxisTickLabel(
|
|
68
80
|
value(text),
|
|
69
81
|
domain,
|
|
70
82
|
visibleValues,
|
|
71
83
|
axis.getAttribute('data-label-unit') ?? undefined,
|
|
72
84
|
axis.getAttribute('data-y-axis-side') === 'right' ? 'right' : 'left',
|
|
73
85
|
)
|
|
86
|
+
if (text.textContent !== label) text.textContent = label
|
|
74
87
|
})
|
|
75
88
|
})
|
|
76
89
|
}
|
|
@@ -78,24 +91,38 @@ function formatCompactLabels(svg: SVGSVGElement) {
|
|
|
78
91
|
/** Apply after axes and grid are in the DOM; never feed the filtered set back into layout. */
|
|
79
92
|
export function updateMaximumTickVisibility(svg: SVGSVGElement) {
|
|
80
93
|
svg.querySelectorAll('[data-maximum-hidden]').forEach((el) => {
|
|
81
|
-
el
|
|
82
|
-
el
|
|
94
|
+
updateSvgAttribute(el, 'display', null)
|
|
95
|
+
updateSvgAttribute(el, 'data-maximum-hidden', null)
|
|
83
96
|
})
|
|
84
97
|
svg.querySelectorAll('.waveform-track__axis--y .tick text').forEach((text) => {
|
|
85
|
-
text
|
|
98
|
+
updateSvgAttribute(text, 'display', null)
|
|
86
99
|
})
|
|
87
100
|
formatCompactLabels(svg)
|
|
101
|
+
const boxes = new Map<SVGTextElement, Box>()
|
|
102
|
+
const widths = new Map<Element, number>()
|
|
103
|
+
const box = (text: SVGTextElement) => {
|
|
104
|
+
if (!boxes.has(text)) boxes.set(text, textBox(text))
|
|
105
|
+
return boxes.get(text)!
|
|
106
|
+
}
|
|
107
|
+
const width = (element: Element) => {
|
|
108
|
+
if (!widths.has(element)) widths.set(element, strokeWidth(element))
|
|
109
|
+
return widths.get(element)!
|
|
110
|
+
}
|
|
88
111
|
const minimumLabels = [...svg.querySelectorAll<SVGTextElement>('text[data-axis-minimum-label]')]
|
|
89
112
|
svg.querySelectorAll<SVGTextElement>('text[data-axis-maximum-label]').forEach((maximum) => {
|
|
90
|
-
const
|
|
91
|
-
if (minimumLabels.some((minimum) => labelsOverlap(
|
|
113
|
+
const maximumBox = box(maximum)
|
|
114
|
+
if (minimumLabels.some((minimum) => labelsOverlap(maximumBox, box(minimum)))) hide(maximum)
|
|
92
115
|
})
|
|
93
116
|
svg.querySelectorAll<SVGGElement>('.waveform-track__axis--y .tick').forEach((tick) => {
|
|
94
117
|
const position = Number(tick.getAttribute('data-tick-y'))
|
|
95
118
|
const height = Number(tick.closest('.waveform-track')?.getAttribute('data-track-height'))
|
|
96
119
|
const line = tick.querySelector('line')
|
|
97
|
-
if (
|
|
98
|
-
|
|
120
|
+
if (line)
|
|
121
|
+
updateSvgAttribute(
|
|
122
|
+
line,
|
|
123
|
+
'display',
|
|
124
|
+
sameTick(position, 0) || sameTick(position, height) ? 'none' : null,
|
|
125
|
+
)
|
|
99
126
|
})
|
|
100
127
|
const minimumTicks = [...svg.querySelectorAll<SVGGElement>('.tick[data-minimum-tick]')]
|
|
101
128
|
const maximumTicks = [...svg.querySelectorAll<SVGGElement>('.tick[data-maximum-tick]')]
|
|
@@ -105,7 +132,7 @@ export function updateMaximumTickVisibility(svg: SVGSVGElement) {
|
|
|
105
132
|
if (!text) return
|
|
106
133
|
maximumTicks.forEach((maximum) => {
|
|
107
134
|
const other = maximum.querySelector('text')
|
|
108
|
-
if (other && other !== text && labelsOverlap(
|
|
135
|
+
if (other && other !== text && labelsOverlap(box(text), box(other))) hide(other)
|
|
109
136
|
})
|
|
110
137
|
})
|
|
111
138
|
const extremeTicks = [...new Set([...minimumTicks, ...maximumTicks])]
|
|
@@ -113,14 +140,14 @@ export function updateMaximumTickVisibility(svg: SVGSVGElement) {
|
|
|
113
140
|
const text = tick.querySelector('text')
|
|
114
141
|
const line = tick.querySelector('line')
|
|
115
142
|
if (!text || !line) return
|
|
116
|
-
const
|
|
143
|
+
const textBounds = box(text)
|
|
117
144
|
labels.forEach((other) => {
|
|
118
145
|
if (text.getAttribute('display') === 'none') return
|
|
119
146
|
if (other.getAttribute('display') === 'none') return
|
|
120
147
|
if (other.parentElement?.matches('[data-minimum-tick], [data-maximum-tick]')) return
|
|
121
148
|
if (!tick.hasAttribute('data-minimum-tick') && other.hasAttribute('data-axis-minimum-label'))
|
|
122
149
|
return
|
|
123
|
-
if (labelsOverlap(
|
|
150
|
+
if (labelsOverlap(textBounds, box(other))) hide(other)
|
|
124
151
|
})
|
|
125
152
|
const axis = tick.parentElement!
|
|
126
153
|
const value = Number(tick.getAttribute('data-tick-value'))
|
|
@@ -134,8 +161,8 @@ export function updateMaximumTickVisibility(svg: SVGSVGElement) {
|
|
|
134
161
|
linesOverlap(
|
|
135
162
|
position,
|
|
136
163
|
Number(other.getAttribute('data-tick-y')),
|
|
137
|
-
|
|
138
|
-
|
|
164
|
+
width(line),
|
|
165
|
+
width(otherLine),
|
|
139
166
|
)
|
|
140
167
|
)
|
|
141
168
|
hide(otherLine)
|
|
@@ -145,12 +172,12 @@ export function updateMaximumTickVisibility(svg: SVGSVGElement) {
|
|
|
145
172
|
const track = axis.closest('.waveform-track')!
|
|
146
173
|
track.querySelectorAll('[data-grid-direction="horizontal"]').forEach((gridLine) => {
|
|
147
174
|
const gridY = Number(gridLine.getAttribute('y1'))
|
|
148
|
-
if (linesOverlap(position, gridY,
|
|
175
|
+
if (linesOverlap(position, gridY, width(line), width(gridLine))) hide(gridLine)
|
|
149
176
|
})
|
|
150
177
|
if (tick.hasAttribute('data-maximum-tick'))
|
|
151
|
-
tick
|
|
178
|
+
updateSvgAttribute(tick, 'data-maximum-value', value)
|
|
152
179
|
if (tick.hasAttribute('data-minimum-tick'))
|
|
153
|
-
tick
|
|
180
|
+
updateSvgAttribute(tick, 'data-minimum-value', value)
|
|
154
181
|
})
|
|
155
182
|
formatCompactLabels(svg)
|
|
156
183
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ComponentPublicInstance, Ref } from 'vue'
|
|
2
|
+
export function assignElement<T extends Element>(
|
|
3
|
+
target: Ref<T | undefined>,
|
|
4
|
+
element: Element | ComponentPublicInstance | null,
|
|
5
|
+
) {
|
|
6
|
+
target.value = element instanceof Element ? (element as T) : undefined
|
|
7
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -7,6 +7,58 @@
|
|
|
7
7
|
export { default as WaveformChart } from './components/WaveformChart.vue'
|
|
8
8
|
export type { WaveformChartProps } from './components/core/waveformChartTypes'
|
|
9
9
|
|
|
10
|
+
// Numeric engine, pure preset factories and owner-scoped chart animation.
|
|
11
|
+
export { getEasingFunction } from './animation/core/easing'
|
|
12
|
+
export { WaveformAnimationController } from './animation/WaveformAnimationController'
|
|
13
|
+
export {
|
|
14
|
+
createLineDrawingAnimation,
|
|
15
|
+
createStaggeredLineDrawingAnimations,
|
|
16
|
+
} from './animation/presets/lineDrawing'
|
|
17
|
+
export {
|
|
18
|
+
createPathTransitionAnimation,
|
|
19
|
+
createYAxisScaleAnimation,
|
|
20
|
+
} from './animation/presets/transitions'
|
|
21
|
+
export {
|
|
22
|
+
createAnnotationAppearAnimation,
|
|
23
|
+
createAnnotationDisappearAnimation,
|
|
24
|
+
} from './animation/presets/annotation'
|
|
25
|
+
export { Animation } from './animation/core/Animation'
|
|
26
|
+
export { Animator, globalAnimator } from './animation/core/Animator'
|
|
27
|
+
export type {
|
|
28
|
+
AnimationValue,
|
|
29
|
+
AnimationDirection,
|
|
30
|
+
AnimationState,
|
|
31
|
+
AnimationFrame,
|
|
32
|
+
AnimationTrack,
|
|
33
|
+
AnimationConfig,
|
|
34
|
+
AnimationHandle,
|
|
35
|
+
AnimationScheduler,
|
|
36
|
+
EasingFunction,
|
|
37
|
+
EasingFamily,
|
|
38
|
+
EasingType,
|
|
39
|
+
} from './animation/core/types'
|
|
40
|
+
export type {
|
|
41
|
+
LineDrawingDirection,
|
|
42
|
+
AnnotationAnimationType,
|
|
43
|
+
LineDrawingOptions,
|
|
44
|
+
StaggeredLineDrawingOptions,
|
|
45
|
+
DataUpdateOptions,
|
|
46
|
+
AnnotationAnimationOptions,
|
|
47
|
+
WaveformEnterAnimationOptions,
|
|
48
|
+
WaveformUpdateAnimationOptions,
|
|
49
|
+
WaveformAnnotationAnimationOptions,
|
|
50
|
+
WaveformAnimationProps,
|
|
51
|
+
ClipAnimationState,
|
|
52
|
+
AnimationBinding,
|
|
53
|
+
NumericGeometry,
|
|
54
|
+
GeometryTransitionInput,
|
|
55
|
+
GeometryTransitionFrame,
|
|
56
|
+
AnnotationAnimationState,
|
|
57
|
+
AnimationScope,
|
|
58
|
+
AnimationObjectKey,
|
|
59
|
+
WaveformAnimationControllerOptions,
|
|
60
|
+
} from './animation/types'
|
|
61
|
+
|
|
10
62
|
// 类型定义
|
|
11
63
|
export type {
|
|
12
64
|
// 图表类型
|
package/src/router.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { createRouter, createWebHashHistory, type RouteRecordRaw } from 'vue-rou
|
|
|
3
3
|
import App from './App.vue'
|
|
4
4
|
|
|
5
5
|
export const routes: RouteRecordRaw[] = [
|
|
6
|
+
{ path: '/animation', name: 'animation', component: () => import('./views/AnimationDemo.vue') },
|
|
6
7
|
{
|
|
7
8
|
path: '/',
|
|
8
9
|
name: 'workspace',
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { ref } from 'vue'
|
|
3
|
+
import { WaveformChart } from '@/index'
|
|
4
|
+
import type {
|
|
5
|
+
AnnotationAnimationType,
|
|
6
|
+
LineDrawingDirection,
|
|
7
|
+
WaveformData,
|
|
8
|
+
WaveformAnnotation,
|
|
9
|
+
} from '@/index'
|
|
10
|
+
|
|
11
|
+
const enabled = ref(true)
|
|
12
|
+
const enter = ref(true)
|
|
13
|
+
const update = ref(true)
|
|
14
|
+
const annotationEnabled = ref(true)
|
|
15
|
+
const effect = ref<AnnotationAnimationType>('scale')
|
|
16
|
+
const direction = ref<LineDrawingDirection>('left-to-right')
|
|
17
|
+
let generation = 0
|
|
18
|
+
function generate(count = 500): WaveformData {
|
|
19
|
+
return {
|
|
20
|
+
kind: 'series',
|
|
21
|
+
series: Array.from({ length: 3 }, (_, channel) => ({
|
|
22
|
+
id: channel === 0 ? 'signal' : `signal-${channel}`,
|
|
23
|
+
name: `信号 ${channel + 1}`,
|
|
24
|
+
data: {
|
|
25
|
+
kind: 'points' as const,
|
|
26
|
+
points: Array.from({ length: count }, (_, i) => ({
|
|
27
|
+
x: i / (count - 1),
|
|
28
|
+
y: Math.sin((i / (count - 1)) * Math.PI * 6 + channel) * (10 + generation * 2),
|
|
29
|
+
})),
|
|
30
|
+
},
|
|
31
|
+
})),
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const data = ref(generate())
|
|
35
|
+
const annotations = ref<WaveformAnnotation[]>([])
|
|
36
|
+
const key = ref(0)
|
|
37
|
+
function replace(compatible: boolean) {
|
|
38
|
+
generation++
|
|
39
|
+
data.value = generate(compatible ? 500 : 750)
|
|
40
|
+
}
|
|
41
|
+
function toggleAnnotation() {
|
|
42
|
+
annotations.value = annotations.value.length
|
|
43
|
+
? []
|
|
44
|
+
: Array.from({ length: 3 }, (_, channel) => ({
|
|
45
|
+
id: channel === 0 ? 'note' : `note-${channel}`,
|
|
46
|
+
seriesId: channel === 0 ? 'signal' : `signal-${channel}`,
|
|
47
|
+
x: 0.4,
|
|
48
|
+
y: 10,
|
|
49
|
+
text: '受控标注',
|
|
50
|
+
}))
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<main class="animation-demo">
|
|
56
|
+
<h1>波形动画</h1>
|
|
57
|
+
<p>
|
|
58
|
+
分别控制入场、更新 /
|
|
59
|
+
切页和标注效果。切换分页时波形与标注同步淡入,坐标轴立即更新。拖动、缩放与导出会提交最终画面。
|
|
60
|
+
</p>
|
|
61
|
+
<div class="animation-demo__controls">
|
|
62
|
+
<label><input v-model="enabled" type="checkbox" /> 动画</label>
|
|
63
|
+
<label><input v-model="enter" type="checkbox" /> 入场</label>
|
|
64
|
+
<label><input v-model="update" type="checkbox" /> 更新 / 切页</label>
|
|
65
|
+
<label><input v-model="annotationEnabled" type="checkbox" /> 标注</label>
|
|
66
|
+
<label
|
|
67
|
+
>入场方向
|
|
68
|
+
<select v-model="direction">
|
|
69
|
+
<option value="left-to-right">从左向右</option>
|
|
70
|
+
<option value="right-to-left">从右向左</option>
|
|
71
|
+
<option value="center-out">从中心展开</option>
|
|
72
|
+
</select></label
|
|
73
|
+
>
|
|
74
|
+
<label
|
|
75
|
+
>标注效果
|
|
76
|
+
<select v-model="effect">
|
|
77
|
+
<option value="fade-in">淡入</option>
|
|
78
|
+
<option value="scale">缩放</option>
|
|
79
|
+
<option value="slide-in">滑入</option>
|
|
80
|
+
<option value="bounce">弹跳</option>
|
|
81
|
+
</select></label
|
|
82
|
+
>
|
|
83
|
+
<button @click="key++">重新入场</button>
|
|
84
|
+
<button @click="replace(true)">更新振幅</button>
|
|
85
|
+
<button @click="replace(false)">改变点数</button>
|
|
86
|
+
<button @click="toggleAnnotation">增删标注</button>
|
|
87
|
+
</div>
|
|
88
|
+
<WaveformChart
|
|
89
|
+
:key="key"
|
|
90
|
+
:data="data"
|
|
91
|
+
:height="360"
|
|
92
|
+
:grid="{ rowCount: 1, columnCount: 1 }"
|
|
93
|
+
:animation-enabled="enabled"
|
|
94
|
+
:animation="{ enabled: enter, direction }"
|
|
95
|
+
:animation-update="{ enabled: update }"
|
|
96
|
+
:animation-annotation="{ enabled: annotationEnabled, type: effect }"
|
|
97
|
+
:annotations="annotations"
|
|
98
|
+
@update:annotations="annotations = $event"
|
|
99
|
+
/>
|
|
100
|
+
</main>
|
|
101
|
+
</template>
|
|
102
|
+
|
|
103
|
+
<style scoped>
|
|
104
|
+
.animation-demo {
|
|
105
|
+
padding: 24px;
|
|
106
|
+
max-width: 1280px;
|
|
107
|
+
margin: auto;
|
|
108
|
+
}
|
|
109
|
+
.animation-demo__controls {
|
|
110
|
+
display: flex;
|
|
111
|
+
flex-wrap: wrap;
|
|
112
|
+
gap: 12px;
|
|
113
|
+
margin-bottom: 20px;
|
|
114
|
+
}
|
|
115
|
+
.animation-demo__controls label {
|
|
116
|
+
display: flex;
|
|
117
|
+
align-items: center;
|
|
118
|
+
gap: 4px;
|
|
119
|
+
}
|
|
120
|
+
button,
|
|
121
|
+
select {
|
|
122
|
+
padding: 6px;
|
|
123
|
+
}
|
|
124
|
+
@media (max-width: 520px) {
|
|
125
|
+
.animation-demo {
|
|
126
|
+
padding: 8px;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
</style>
|