-
Notifications
You must be signed in to change notification settings - Fork 739
/
scale-border-radius.ts
42 lines (37 loc) · 1.58 KB
/
scale-border-radius.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
import { px } from "style-value-types"
import { Axis } from "../geometry/types"
import { ScaleCorrectorDefinition } from "./types"
export function pixelsToPercent(pixels: number, axis: Axis): number {
if (axis.max === axis.min) return 0
return (pixels / (axis.max - axis.min)) * 100
}
/**
* We always correct borderRadius as a percentage rather than pixels to reduce paints.
* For example, if you are projecting a box that is 100px wide with a 10px borderRadius
* into a box that is 200px wide with a 20px borderRadius, that is actually a 10%
* borderRadius in both states. If we animate between the two in pixels that will trigger
* a paint each time. If we animate between the two in percentage we'll avoid a paint.
*/
export const correctBorderRadius: ScaleCorrectorDefinition = {
correct: (latest, node) => {
if (!node.target) return latest
/**
* If latest is a string, if it's a percentage we can return immediately as it's
* going to be stretched appropriately. Otherwise, if it's a pixel, convert it to a number.
*/
if (typeof latest === "string") {
if (px.test(latest)) {
latest = parseFloat(latest)
} else {
return latest
}
}
/**
* If latest is a number, it's a pixel value. We use the current viewportBox to calculate that
* pixel value as a percentage of each axis
*/
const x = pixelsToPercent(latest, node.target.x)
const y = pixelsToPercent(latest, node.target.y)
return `${x}% ${y}%`
},
}