react-native-squircle-skia
Version:
Skia based squircle for React Native. draws with Figma squirce style
187 lines (166 loc) • 7.08 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _reactNativeSkia = require("@shopify/react-native-skia");
var _react = _interopRequireWildcard(require("react"));
var _reactNative = require("react-native");
var _utils = require("../utils");
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
const Squircle = _ref => {
let {
smoothing = 1,
style,
children,
color,
...otherProps
} = _ref;
const flattenStyle = (0, _react.useMemo)(() => _reactNative.StyleSheet.flatten(style), [style]);
const {
borderRadius,
borderTopLeftRadius = borderRadius,
borderTopRightRadius = borderRadius,
borderBottomLeftRadius = borderRadius,
borderBottomRightRadius = borderRadius,
borderWidth,
borderColor,
borderStyle,
backgroundColor,
...otherStyles
} = flattenStyle;
if (borderRadius === undefined || borderTopLeftRadius === undefined && borderTopRightRadius === undefined && borderBottomLeftRadius === undefined && borderBottomRightRadius === undefined) {
throw new Error('react-native-squircle-skia: No borderRadius provided in Squircle style');
}
if (borderWidth !== undefined || borderColor !== undefined || borderStyle !== undefined) {
throw new Error('react-native-squircle-skia: Setting border is not supported.');
}
const [width, setWidth] = (0, _react.useState)(0);
const [height, setHeight] = (0, _react.useState)(0);
const pathColor = (0, _react.useMemo)(() => {
return color || backgroundColor || 'transparent';
}, [backgroundColor, color]);
const drawTopRightCornerPath = path => {
if (borderTopRightRadius) {
const {
a,
b,
c,
d,
p,
circularSectionLength
} = (0, _utils.getPathParamsForCorner)({
width,
height,
cornerRadius: borderTopRightRadius,
cornerSmoothing: smoothing
});
path.moveTo(Math.max(width / 2, width - p), 0);
path.cubicTo(width - (p - a), 0, width - (p - a - b), 0, width - (p - a - b - c), d);
path.rArcTo(borderTopRightRadius, borderTopRightRadius, 0, true, false, circularSectionLength, circularSectionLength);
path.cubicTo(width, p - a - b, width, p - a, width, Math.min(height / 2, p));
} else {
path.moveTo(width / 2, 0);
path.lineTo(width, 0);
path.lineTo(width, height / 2);
}
};
const drawBottomRightCornerPath = path => {
if (borderBottomRightRadius) {
const {
a,
b,
c,
d,
p,
circularSectionLength
} = (0, _utils.getPathParamsForCorner)({
width,
height,
cornerRadius: borderBottomRightRadius,
cornerSmoothing: smoothing
});
path.lineTo(width, Math.max(height / 2, height - p));
path.cubicTo(width, height - (p - a), width, height - (p - a - b), width - d, height - (p - a - b - c));
path.rArcTo(borderBottomRightRadius, borderBottomRightRadius, 0, true, false, -circularSectionLength, circularSectionLength);
path.cubicTo(width - (p - a - b), height, width - (p - a), height, Math.max(width / 2, width - p), height);
} else {
path.lineTo(width, height);
path.lineTo(width / 2, height);
}
};
const drawBottomLeftCornerPath = path => {
if (borderBottomLeftRadius) {
const {
a,
b,
c,
d,
p,
circularSectionLength
} = (0, _utils.getPathParamsForCorner)({
width,
height,
cornerRadius: borderBottomLeftRadius,
cornerSmoothing: smoothing
});
path.lineTo(Math.min(width / 2, p), height);
path.cubicTo(p - a, height, p - a - b, height, p - a - b - c, height - d);
path.rArcTo(borderBottomLeftRadius, borderBottomLeftRadius, 0, true, false, -circularSectionLength, -circularSectionLength);
path.cubicTo(0, height - (p - a - b), 0, height - (p - a), 0, Math.max(height / 2, height - p));
} else {
path.lineTo(0, height);
path.lineTo(0, height / 2);
}
};
const drawTopLeftCornerPath = path => {
if (borderTopLeftRadius) {
const {
a,
b,
c,
d,
p,
circularSectionLength
} = (0, _utils.getPathParamsForCorner)({
width,
height,
cornerRadius: borderTopLeftRadius,
cornerSmoothing: smoothing
});
path.lineTo(0, Math.min(height / 2, p));
path.cubicTo(0, p - a, 0, p - a - b, d, p - a - b - c);
path.rArcTo(borderTopLeftRadius, borderTopLeftRadius, 0, true, false, circularSectionLength, -circularSectionLength);
path.cubicTo(p - a - b, 0, p - a, 0, Math.min(width / 2, p), 0);
} else {
path.lineTo(0, 0);
}
path.close();
};
const _path = (0, _reactNativeSkia.usePath)(path => {
drawTopRightCornerPath(path);
drawBottomRightCornerPath(path);
drawBottomLeftCornerPath(path);
drawTopLeftCornerPath(path);
return path;
}, [smoothing, borderRadius, width, height]);
const handleLayout = event => {
setWidth(event.nativeEvent.layout.width);
setHeight(event.nativeEvent.layout.height);
};
return /*#__PURE__*/_react.default.createElement(_reactNative.View, _extends({
style: [otherStyles]
}, otherProps, {
onLayout: handleLayout
}), /*#__PURE__*/_react.default.createElement(_reactNativeSkia.Canvas, {
style: _reactNative.StyleSheet.absoluteFill
}, /*#__PURE__*/_react.default.createElement(_reactNativeSkia.Path, {
path: _path,
color: pathColor
})), children);
};
var _default = Squircle;
exports.default = _default;
//# sourceMappingURL=Squircle.js.map