-
Notifications
You must be signed in to change notification settings - Fork 64
/
Copy pathreact-imgix-bg.jsx
115 lines (99 loc) · 2.95 KB
/
react-imgix-bg.jsx
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
import React from "react";
import Measure, { withContentRect } from "react-measure";
import constructUrl from "./constructUrl";
import targetWidths from "./targetWidths";
import findClosest from "./findClosest";
const PACKAGE_VERSION = require("../package.json").version;
const noop = () => {};
const findNearestWidth = actualWidth => findClosest(actualWidth, targetWidths);
const toFixed = (dp, value) => +value.toFixed(dp);
const BackgroundImpl = props => {
const {
measureRef,
measure,
contentRect,
imgixParams = {},
onLoad,
disableLibraryParam,
src,
children,
className = ""
} = props;
const { w: forcedWidth, h: forcedHeight } = imgixParams;
const hasDOMDimensions = contentRect.bounds.top != null;
const htmlAttributes = props.htmlAttributes || {};
const dpr = toFixed(2, imgixParams.dpr || global.devicePixelRatio || 1);
const ref = htmlAttributes.ref;
const onRef = el => {
measureRef(el);
if (typeof ref === "function") {
ref(el);
}
};
const { width, height } = (() => {
const bothWidthAndHeightPassed =
forcedWidth != null && forcedHeight != null;
if (bothWidthAndHeightPassed) {
return { width: forcedWidth, height: forcedHeight };
}
if (!hasDOMDimensions) {
return { width: undefined, height: undefined };
}
const ar = contentRect.bounds.width / contentRect.bounds.height;
const neitherWidthNorHeightPassed =
forcedWidth == null && forcedHeight == null;
if (neitherWidthNorHeightPassed) {
const width = findNearestWidth(contentRect.bounds.width);
const height = Math.ceil(width / ar);
return { width, height };
}
if (forcedWidth != null) {
const height = Math.ceil(forcedWidth / ar);
return { width: forcedWidth, height };
} else if (forcedHeight != null) {
const width = Math.ceil(forcedHeight * ar);
return { width, height: forcedHeight };
}
})();
const isReady = width != null && height != null;
const commonProps = {
...htmlAttributes
};
if (!isReady) {
return (
<div
{...commonProps}
className={`react-imgix-bg-loading ${className}`}
ref={onRef}
>
{children}
</div>
);
}
const renderedSrc = (() => {
const srcOptions = {
fit: "crop",
...imgixParams,
...(disableLibraryParam ? {} : { ixlib: `react-${PACKAGE_VERSION}` }),
width,
height,
dpr
};
return constructUrl(src, srcOptions);
})();
const style = {
...htmlAttributes.style,
backgroundImage: `url(${renderedSrc})`,
backgroundSize:
(htmlAttributes.style || {}).backgroundSize !== undefined
? htmlAttributes.style.backgroundSize
: "cover"
};
return (
<div {...commonProps} className={className} ref={onRef} style={style}>
{children}
</div>
);
};
const Background = withContentRect("bounds")(BackgroundImpl);
export { Background, BackgroundImpl as __BackgroundImpl };