-
-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathreactiveTransform.ts
75 lines (63 loc) · 2.13 KB
/
reactiveTransform.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import { px } from 'style-value-types'
import { reactive, ref, watch } from 'vue'
import type { Reactive, Ref } from 'vue'
import type { TransformProperties } from './types'
import { getValueAsType, getValueType } from './utils/style'
/**
* Aliases translate key for simpler API integration.
*/
const translateAlias: Record<string, string> = {
x: 'translateX',
y: 'translateY',
z: 'translateZ',
}
/**
* Reactive transform string implementing all native CSS transform properties.
*
* @param props
* @param enableHardwareAcceleration
*/
export function reactiveTransform(props: TransformProperties = {}, enableHardwareAcceleration = true): { state: Reactive<TransformProperties>, transform: Ref<string> } {
// Reactive TransformProperties object
const state = reactive<TransformProperties>({ ...props })
const transform = ref('')
watch(
state,
(newVal) => {
// Init result
let result = ''
let hasHardwareAcceleration = false
// Use translate3d by default has a better GPU optimization
// And corrects scaling discrete behaviors
if (enableHardwareAcceleration && (newVal.x || newVal.y || newVal.z)) {
const str = [newVal.x || 0, newVal.y || 0, newVal.z || 0]
.map(val => getValueAsType(val, px))
.join(',')
result += `translate3d(${str}) `
hasHardwareAcceleration = true
}
// Loop on defined TransformProperties state keys
for (const [key, value] of Object.entries(newVal)) {
if (enableHardwareAcceleration && (key === 'x' || key === 'y' || key === 'z'))
continue
// Get value type for key
const valueType = getValueType(key)
// Get value as type for key
const valueAsType = getValueAsType(value, valueType)
// Append the computed transform key to result string
result += `${translateAlias[key] || key}(${valueAsType}) `
}
if (enableHardwareAcceleration && !hasHardwareAcceleration)
result += 'translateZ(0px) '
transform.value = result.trim()
},
{
immediate: true,
deep: true,
},
)
return {
state,
transform,
}
}