This repository has been archived by the owner on Dec 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 45
/
Copy pathdotted.js
128 lines (114 loc) · 3.65 KB
/
dotted.js
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* eslint react/prop-types: 0 */
function resolveValue(value, def) {
if (value !== undefined) return value;
return def || 0;
}
export default function dottedTransition({ from, to, render, interpolate }) {
const colCount = 4;
const rowCount = 4;
function convertToTiles(isTarget) {
function interpolate2(start, end, clamped) {
return interpolate(
isTarget ? end : start,
isTarget ? start : end,
clamped
);
}
const result = [];
const clone = isTarget ? to : from;
const { width, height, style, start, end } = clone;
const {
borderRadius,
borderTopLeftRadius,
borderTopRightRadius,
borderBottomLeftRadius,
borderBottomRightRadius
} = style;
for (let rowIndex = 0; rowIndex < rowCount; rowIndex++) {
for (let colIndex = 0; colIndex < colCount; colIndex++) {
const tileIndex = result.length;
// Update size to be the size of a tile
style.width = width / colCount;
style.height = height / rowCount;
// Specify content style to show only a portion
// of the content
clone.contentStyle = {
position: "absolute",
width: width,
height: height,
left: colIndex * -style.width,
top: rowIndex * -style.height
};
// Clip the contents
style.overflow = "hidden";
// Position the tile
style.transform = [
{ translateX: (isTarget ? end.x : start.x) + style.width * colIndex },
{
translateY: (isTarget ? end.y : start.y) + style.height * rowIndex
},
{ scaleX: interpolate2(1, 0) },
{ scaleY: interpolate2(1, 0) }
];
// Calculate border-radius for this tile
style.borderRadius = 0;
style.borderTopLeftRadius = 0;
style.borderTopRightRadius = 0;
style.borderBottomLeftRadius = 0;
style.borderBottomRightRadius = 0;
if (rowIndex === 0 && colIndex === 0) {
style.borderTopLeftRadius = resolveValue(
borderTopLeftRadius,
borderRadius
);
} else if (rowIndex === 0 && colIndex === colCount - 1) {
style.borderTopRightRadius = resolveValue(
borderTopRightRadius,
borderRadius
);
} else if (rowIndex === rowCount - 1 && colIndex === 0) {
style.borderBottomLeftRadius = resolveValue(
borderBottomLeftRadius,
borderRadius
);
} else if (rowIndex === rowCount - 1 && colIndex === colCount - 1) {
style.borderBottomRightRadius = resolveValue(
borderBottomRightRadius,
borderRadius
);
}
// Animate border radius into a circle
const endBorderRadius = Math.max(style.width / 2, style.height / 2);
style.borderTopLeftRadius = interpolate2(
style.borderTopLeftRadius,
endBorderRadius
);
style.borderTopRightRadius = interpolate2(
style.borderTopRightRadius,
endBorderRadius
);
style.borderBottomLeftRadius = interpolate2(
style.borderBottomLeftRadius,
endBorderRadius
);
style.borderBottomRightRadius = interpolate2(
style.borderBottomRightRadius,
endBorderRadius
);
// Render
result.push(render(clone, tileIndex));
}
}
return result;
}
const fromTiles = convertToTiles(false);
const toTiles = convertToTiles(true);
//
// Render
//
return [...fromTiles, ...toTiles];
}
dottedTransition.defaultProps = {
useNativeDriver: true,
nativeContentType: "snapshot"
};