Skip to content

Commit edde7cc

Browse files
authored
Merge pull request #124 from motiondivision/fix/svg-style
fix: sVG style not update
2 parents 024bbb6 + da03018 commit edde7cc

File tree

6 files changed

+70
-21
lines changed

6 files changed

+70
-21
lines changed

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "vue-motion",
3-
"version": "0.13.0",
3+
"version": "0.13.1-alpha.0",
44
"private": true,
55
"packageManager": "[email protected]+sha1.8bfdb6d72b4d5fdf87d21d27f2bfbe2b21dd2629",
66
"description": "",

packages/motion/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "motion-v",
3-
"version": "0.13.0",
3+
"version": "0.13.1-alpha.0",
44
"description": "",
55
"author": "",
66
"license": "MIT",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { render } from '@testing-library/vue'
3+
import { Motion } from '@/components'
4+
import { motionValue } from 'framer-motion/dom'
5+
import { nextTick } from 'vue'
6+
import { delay } from '@/shared/test'
7+
8+
describe('row-value', () => {
9+
it('should render initial value', async () => {
10+
const opacity = motionValue(0)
11+
const stroke = motionValue('red')
12+
const wrapper = render(Motion, {
13+
props: {
14+
as: 'path',
15+
style: {
16+
opacity,
17+
stroke,
18+
},
19+
},
20+
attrs: {
21+
'data-testid': 'path',
22+
},
23+
})
24+
await nextTick()
25+
const path = wrapper.getByTestId('path')
26+
expect(path.style.opacity).toBeFalsy()
27+
expect(path.style.stroke).toBeFalsy()
28+
expect(path.getAttribute('stroke')).toBe('red')
29+
expect(path.getAttribute('opacity')).toBe('0')
30+
opacity.set(1)
31+
stroke.set('blue')
32+
await delay(100)
33+
expect(path.style.opacity).toBeFalsy()
34+
expect(path.style.stroke).toBeFalsy()
35+
expect(path.getAttribute('stroke')).toBe('blue')
36+
expect(path.getAttribute('opacity')).toBe('1')
37+
})
38+
})

packages/motion/src/components/motion/Motion.vue

+8-9
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { checkMotionIsHidden } from './utils'
77
import type { AsTag, ComponentProps, ElementType, Options, SVGAttributesWithMotionValues, SetMotionValueType } from '@/types'
88
import { useMotionConfig } from '../motion-config/context'
99
import { getMotionElement } from '../hooks/use-motion-elm'
10+
import type { DOMKeyframesDefinition } from 'motion-dom'
1011
</script>
1112

1213
<script setup lang="ts" generic="T extends AsTag = 'div', K = unknown">
@@ -77,7 +78,7 @@ const props = withDefaults(defineProps<ComBindProps & MotionProps<T, K>>(), {
7778
return focus
7879
},
7980
} as any) as MotionProps<T>
80-
const animatePresenceContext = injectAnimatePresence({ })
81+
const animatePresenceContext = injectAnimatePresence({})
8182
const parentState = injectMotion(null)
8283
const attrs = useAttrs()
8384
const layoutGroup = injectLayoutGroup({} as any)
@@ -163,9 +164,12 @@ function getAttrs() {
163164
...(isSVG ? {} : state.visualElement.latestValues),
164165
}
165166
if (isSVG) {
166-
const { attributes, style } = convertSvgStyleToAttributes(state.isMounted() ? state.target : state.baseTarget)
167+
const { attributes, style } = convertSvgStyleToAttributes({
168+
...(state.isMounted() ? state.target : state.baseTarget),
169+
...styleProps,
170+
} as DOMKeyframesDefinition)
167171
Object.assign(attrsProps, attributes)
168-
Object.assign(styleProps, style)
172+
styleProps = style
169173
}
170174
if (props.drag && props.dragListener !== false) {
171175
Object.assign(styleProps, {
@@ -178,12 +182,7 @@ function getAttrs() {
178182
})
179183
}
180184
181-
styleProps = createStyles({
182-
...styleProps,
183-
...props.style,
184-
})
185-
186-
attrsProps.style = styleProps
185+
attrsProps.style = createStyles(styleProps)
187186
return attrsProps
188187
}
189188

packages/motion/src/state/style.ts

+21-9
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import type { DOMKeyframesDefinition } from 'framer-motion'
1+
import type { DOMKeyframesDefinition, ResolvedValues } from 'framer-motion'
22
import { isCssVar, isNumber } from './utils'
33
import { buildTransformTemplate, isTransform, transformAlias, transformDefinitions } from './transform'
44
import { isMotionValue } from '@/utils'
55
import type { MotionStyle } from '@/types'
6+
import { px } from '@/value/types/numbers/units'
67

78
type MotionStyleKey = Exclude<
89
keyof CSSStyleDeclaration,
@@ -83,15 +84,12 @@ const SVG_STYLE_TO_ATTRIBUTES = {
8384
cy: true,
8485
r: true,
8586
d: true,
86-
x: true,
87-
y: true,
8887
x1: true,
8988
y1: true,
9089
x2: true,
9190
y2: true,
9291
points: true,
9392
pathLength: true,
94-
transform: true,
9593
viewBox: true,
9694
width: true,
9795
height: true,
@@ -116,22 +114,36 @@ const SVG_STYLE_TO_ATTRIBUTES = {
116114
vectorEffect: true,
117115
} as const
118116

117+
function buildSVGPath(
118+
attrs: ResolvedValues,
119+
length: number,
120+
spacing = 1,
121+
offset = 0,
122+
) {
123+
attrs.pathLength = 1
124+
// Build the dash offset
125+
attrs['stroke-dashoffset'] = px.transform(-offset)
126+
127+
// Build the dash array
128+
const pathLength = px.transform!(length)
129+
const pathSpacing = px.transform!(spacing)
130+
attrs['stroke-dasharray'] = `${pathLength} ${pathSpacing}`
131+
}
119132
export function convertSvgStyleToAttributes(keyframes?: MotionStyle | DOMKeyframesDefinition) {
120133
const attributes: Record<string, any> = {}
121134
const styleProps: Record<string, any> = {}
122-
123135
for (const key in keyframes as any) {
124136
if (key in SVG_STYLE_TO_ATTRIBUTES) {
125-
const attrKey = SVG_STYLE_TO_ATTRIBUTES[key as keyof typeof SVG_STYLE_TO_ATTRIBUTES]
126-
const attrName = typeof attrKey === 'string' ? attrKey : key
127137
const value = keyframes[key]
128-
attributes[attrName] = isMotionValue(value) ? value.get() : value
138+
attributes[key] = isMotionValue(value) ? value.get() : value
129139
}
130140
else {
131141
styleProps[key] = keyframes[key]
132142
}
133143
}
134-
144+
if (attributes.pathLength) {
145+
buildSVGPath(attributes, attributes.pathLength, attributes.pathSpacing, attributes.pathOffset)
146+
}
135147
return {
136148
attributes,
137149
style: styleProps,

packages/plugins/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "plugins",
3-
"version": "0.13.0",
3+
"version": "0.13.1-alpha.0",
44
"private": true,
55
"description": "",
66
"author": "",

0 commit comments

Comments
 (0)