UNPKG

@ta-interaktiv/react-annotated-content

Version:

Component to render annotations above other content

709 lines (698 loc) 32.3 kB
'use strict'; var React = require('react'); var styled = require('styled-components'); var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; function __makeTemplateObject(cooked, raw) { if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } return cooked; }typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { var e = new Error(message); return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; function getDefaultExportFromCjs (x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; } var FUNC_ERROR_TEXT = 'Expected a function'; var NAN = 0 / 0; var symbolTag = '[object Symbol]'; var reTrim = /^\s+|\s+$/g; var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; var reIsBinary = /^0b[01]+$/i; var reIsOctal = /^0o[0-7]+$/i; var freeParseInt = parseInt; var freeGlobal = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; var freeSelf = typeof self == 'object' && self && self.Object === Object && self; var root = freeGlobal || freeSelf || Function('return this')(); var objectProto = Object.prototype; var objectToString = objectProto.toString; var nativeMax = Math.max, nativeMin = Math.min; var now = function() { return root.Date.now(); }; function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall; return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; return (lastCallTime === undefined || (timeSinceLastCall >= wait) || (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait)); } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } function isObject(value) { var type = typeof value; return !!value && (type == 'object' || type == 'function'); } function isObjectLike(value) { return !!value && typeof value == 'object'; } function isSymbol(value) { return typeof value == 'symbol' || (isObjectLike(value) && objectToString.call(value) == symbolTag); } function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? (other + '') : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return (isBinary || reIsOctal.test(value)) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : (reIsBadHex.test(value) ? NAN : +value); } var lodash_debounce = debounce; getDefaultExportFromCjs(lodash_debounce); function useIntersectionObserver({ threshold = 0, root = null, rootMargin = "0%", freezeOnceVisible = false, initialIsIntersecting = false, onChange } = {}) { var _a; const [ref, setRef] = React.useState(null); const [state, setState] = React.useState(() => ({ isIntersecting: initialIsIntersecting, entry: void 0 })); const callbackRef = React.useRef(); callbackRef.current = onChange; const frozen = ((_a = state.entry) == null ? void 0 : _a.isIntersecting) && freezeOnceVisible; React.useEffect(() => { if (!ref) return; if (!("IntersectionObserver" in window)) return; if (frozen) return; let unobserve; const observer = new IntersectionObserver( (entries) => { const thresholds = Array.isArray(observer.thresholds) ? observer.thresholds : [observer.thresholds]; entries.forEach((entry) => { const isIntersecting = entry.isIntersecting && thresholds.some((threshold2) => entry.intersectionRatio >= threshold2); setState({ isIntersecting, entry }); if (callbackRef.current) { callbackRef.current(isIntersecting, entry); } if (isIntersecting && freezeOnceVisible && unobserve) { unobserve(); unobserve = void 0; } }); }, { threshold, root, rootMargin } ); observer.observe(ref); return () => { observer.disconnect(); }; }, [ ref, JSON.stringify(threshold), root, rootMargin, frozen, freezeOnceVisible ]); const prevRef = React.useRef(null); React.useEffect(() => { var _a2; if (!ref && ((_a2 = state.entry) == null ? void 0 : _a2.target) && !freezeOnceVisible && !frozen && prevRef.current !== state.entry.target) { prevRef.current = state.entry.target; setState({ isIntersecting: initialIsIntersecting, entry: void 0 }); } }, [ref, state.entry, freezeOnceVisible, frozen, initialIsIntersecting]); const result = [ setRef, !!state.isIntersecting, state.entry ]; result.ref = result[0]; result.isIntersecting = result[1]; result.entry = result[2]; return result; } function useIsMounted() { const isMounted = React.useRef(false); React.useEffect(() => { isMounted.current = true; return () => { isMounted.current = false; }; }, []); return React.useCallback(() => isMounted.current, []); } var initialSize = { width: void 0, height: void 0 }; function useResizeObserver(options) { const { ref, box = "content-box" } = options; const [{ width, height }, setSize] = React.useState(initialSize); const isMounted = useIsMounted(); const previousSize = React.useRef({ ...initialSize }); const onResize = React.useRef(void 0); onResize.current = options.onResize; React.useEffect(() => { if (!ref.current) return; if (typeof window === "undefined" || !("ResizeObserver" in window)) return; const observer = new ResizeObserver(([entry]) => { const boxProp = box === "border-box" ? "borderBoxSize" : box === "device-pixel-content-box" ? "devicePixelContentBoxSize" : "contentBoxSize"; const newWidth = extractSize(entry, boxProp, "inlineSize"); const newHeight = extractSize(entry, boxProp, "blockSize"); const hasChanged = previousSize.current.width !== newWidth || previousSize.current.height !== newHeight; if (hasChanged) { const newSize = { width: newWidth, height: newHeight }; previousSize.current.width = newWidth; previousSize.current.height = newHeight; if (onResize.current) { onResize.current(newSize); } else { if (isMounted()) { setSize(newSize); } } } }); observer.observe(ref.current, { box }); return () => { observer.disconnect(); }; }, [box, ref, isMounted]); return { width, height }; } function extractSize(entry, box, sizeType) { if (!entry[box]) { if (box === "contentBoxSize") { return entry.contentRect[sizeType === "inlineSize" ? "width" : "height"]; } return void 0; } return Array.isArray(entry[box]) ? entry[box][0][sizeType] : ( entry[box][sizeType] ); } var isDev = window.location.hostname === 'localhost'; var AnnotatedContent = function (_a) { var children = _a.children, _b = _a.annotations, annotations = _b === void 0 ? [] : _b, _c = _a.className, className = _c === void 0 ? '' : _c, connectorStyle = _a.connectorStyle, _d = _a.shapeStyle, shapeStyle = _d === void 0 ? {} : _d; var ref = React.useRef(null); var _e = useResizeObserver({ ref: ref, box: 'border-box', }), _f = _e.width, width = _f === void 0 ? 0 : _f, _g = _e.height, height = _g === void 0 ? 0 : _g; var validateAnnotation = function (annotation) { return (annotation.pos.x >= 0 && annotation.pos.x <= 100 && annotation.pos.y >= 0 && annotation.pos.y <= 100); }; var renderAnnotation = function (annotation, index) { var _a, _b, _c; var basePosition = { position: 'absolute', left: "".concat(annotation.pos.x, "%"), top: "".concat(annotation.pos.y, "%"), }; if (annotation.type === 'custom') { return (React.createElement("div", { key: (_a = annotation.id) !== null && _a !== void 0 ? _a : index, className: annotation.className, style: __assign(__assign(__assign({}, basePosition), { transform: 'translate(-50%, -50%)' }), annotation.style) }, annotation.content)); } if (React.isValidElement(annotation.content)) { return (React.createElement("div", { key: (_b = annotation.id) !== null && _b !== void 0 ? _b : index, style: basePosition }, React.cloneElement(annotation.content, __assign(__assign({}, annotation.content.props), { connectorStyle: __assign(__assign({}, connectorStyle), annotation.content.props.connectorStyle), shapeStyle: __assign(__assign({}, shapeStyle), annotation.content.props.shapeStyle), fullSize: [width, height] })))); } return (React.createElement("div", { key: (_c = annotation.id) !== null && _c !== void 0 ? _c : index, style: basePosition }, annotation.content)); }; return (React.createElement(AnnotatedImageContainer, { ref: ref, className: "annotated-image ".concat(className).trim(), onClick: function (e) { if (!isDev) return; if (!e.shiftKey) { var rect = e.currentTarget.getBoundingClientRect(); var x = ((e.clientX - rect.left) / rect.width) * 100; var y = ((e.clientY - rect.top) / rect.height) * 100; console.log("{ x: ".concat(x.toFixed(2), ", y: ").concat(y.toFixed(2), " },")); } } }, children, annotations.filter(validateAnnotation).map(renderAnnotation))); }; var AnnotatedImageContainer = styled.div(templateObject_1$2 || (templateObject_1$2 = __makeTemplateObject(["\n width: 100%;\n position: relative;\n line-height: 0;\n * {\n line-height: 1.2em;\n }\n .annotated-image__image {\n width: 100%;\n height: auto;\n display: block;\n }\n"], ["\n width: 100%;\n position: relative;\n line-height: 0;\n * {\n line-height: 1.2em;\n }\n .annotated-image__image {\n width: 100%;\n height: auto;\n display: block;\n }\n"]))); var templateObject_1$2; var defaultShapeStyle = { pattern: 'none', patternRotation: 45, patternWidth: 10, patternSpace: 5, fill: 'rgba(0,0,0,0.15)', stroke: 'gray', strokeWidth: 0.5, cornerRadius: 10, }; var AreaAnnotation = function (_a) { var children = _a.children, _b = _a.shapeType, shapeType = _b === void 0 ? 'circle' : _b, _c = _a.size, size = _c === void 0 ? 5 : _c, _d = _a.rotation, rotation = _d === void 0 ? 0 : _d, customShape = _a.customShape, _e = _a.fullSize, fullSize = _e === void 0 ? [100, 100] : _e, _f = _a.textAnchor, textAnchor = _f === void 0 ? 'center' : _f, _g = _a.offset, offset = _g === void 0 ? 0 : _g, _h = _a.shapeStyle, shapeStyle = _h === void 0 ? {} : _h; var _j = getOffset$1(offset), h = _j[0], v = _j[1]; var currentShapeStyle = __assign(__assign({}, defaultShapeStyle), shapeStyle); var pattern = currentShapeStyle.pattern, patternWidth = currentShapeStyle.patternWidth, patternSpace = currentShapeStyle.patternSpace, patternRotation = currentShapeStyle.patternRotation, fill = currentShapeStyle.fill; var hatchId = Math.random().toString(36).substring(7); if (shapeType === 'custom' && !customShape) { console.warn('Custom shape type requires customShape prop. Falling back to circle.'); shapeType = 'circle'; } var getRotation = function () { if (shapeType === 'custom') return 0; return rotation !== null && rotation !== void 0 ? rotation : 0; }; var getShapeSize = function () { if (shapeType === 'custom') return [0, 0]; return getSize(size !== null && size !== void 0 ? size : 20, fullSize[0], fullSize[1]); }; var _k = getShapeSize(), sx = _k[0], sy = _k[1]; rotation = getRotation(); var getPatternFill = function () { switch (pattern) { case 'hatched': return "url(#hatched_".concat(hatchId, ")"); case 'dotted': return "url(#dotted_".concat(hatchId, ")"); case 'crossed': return "url(#crossed_".concat(hatchId, ")"); default: return fill; } }; var renderShape = function () { var shapeProps = { style: __assign(__assign({}, currentShapeStyle), { fill: getPatternFill() }), }; switch (shapeType) { case 'circle': return (React.createElement("ellipse", __assign({ rx: sx / 2, ry: sy / 2, transform: "rotate(".concat(rotation, ")") }, shapeProps))); case 'rect': return (React.createElement("rect", __assign({ rx: currentShapeStyle.cornerRadius, ry: currentShapeStyle.cornerRadius, x: -sx / 2, y: -sy / 2, width: sx, height: sy, transform: "rotate(".concat(rotation, ")") }, shapeProps))); case 'custom': return (React.createElement("path", __assign({ d: customShapeToPath(customShape, fullSize[0], fullSize[1]) }, shapeProps))); } }; return (React.createElement(AnnotationContainer$1, { className: 'annoContainer' }, React.createElement(AreaSvg, { width: Math.max(4, Math.abs(h)), height: Math.max(4, Math.abs(v)), style: { left: h >= 0 ? 0 : h, top: v >= 0 ? 0 : v, } }, React.createElement("defs", null, React.createElement("pattern", { id: "dotted_".concat(hatchId), patternUnits: 'userSpaceOnUse', x: -Math.round(patternSpace / 2), y: -Math.round(patternWidth / 2), patternTransform: "rotate(".concat(patternRotation - rotation, " 0 0)"), width: patternWidth + patternSpace, height: patternWidth + patternSpace }, React.createElement("circle", { cx: Math.round(patternWidth / 2), cy: Math.round(patternWidth / 2), r: Math.round(patternWidth / 2), style: { stroke: 'none', fill: fill } })), React.createElement("pattern", { id: 'hatched_' + hatchId, patternUnits: 'userSpaceOnUse', width: patternSpace + patternWidth, height: patternSpace + patternWidth, patternTransform: 'rotate(' + (patternRotation - rotation) + ' 0 0)' }, React.createElement("line", { x1: '0', y1: '0', x2: 0, y2: patternSpace + patternWidth, style: { stroke: fill, strokeWidth: patternWidth, } })), React.createElement("pattern", { id: "crossed_".concat(hatchId), patternUnits: 'userSpaceOnUse', width: patternWidth + patternSpace, height: patternWidth + patternSpace, patternTransform: "rotate(".concat(patternRotation - rotation, ")") }, React.createElement("path", { d: createCrosshatchPath(patternWidth, patternSpace), stroke: fill, strokeWidth: patternWidth, strokeOpacity: 0.5 }))), renderShape()), React.createElement(ContentContainer$1, { style: { minWidth: 'max-content', left: h, top: v, transform: 'translate(-50%, -50%)', textAlign: textAnchor, } }, children))); }; var AnnotationContainer$1 = styled.div(templateObject_1$1 || (templateObject_1$1 = __makeTemplateObject(["\n display: inline-block;\n line-height: 1em;\n position: absolute;\n"], ["\n display: inline-block;\n line-height: 1em;\n position: absolute;\n"]))); var ContentContainer$1 = styled.div(templateObject_2$1 || (templateObject_2$1 = __makeTemplateObject(["\n position: absolute;\n line-height: 1em;\n"], ["\n position: absolute;\n line-height: 1em;\n"]))); var AreaSvg = styled.svg(templateObject_3$1 || (templateObject_3$1 = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n overflow: visible;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n overflow: visible;\n"]))); var createCrosshatchPath = function (width, space) { var tileSize = width + space; return "M ".concat(space / 2, " 0 \n L ").concat(space / 2, " ").concat(tileSize, "\n M 0 ").concat(space / 2, " \n L ").concat(tileSize, " ").concat(space / 2); }; function percentageToPixel(percentage, total) { return (percentage * total) / 100; } function customShapeToPath(customShape, width, height) { return [ customShape .map(function (point, index) { var x = percentageToPixel(point.x, width); var y = percentageToPixel(point.y, height); return "".concat(index === 0 ? 'M' : 'L', " ").concat(x, " ").concat(y); }) .join(' '), 'Z', ].join(' '); } function getOffset$1(offset) { if (Array.isArray(offset)) { return offset; } return [offset, offset]; } function getSize(size, width, height) { if (Array.isArray(size)) { return [ percentageToPixel(size[0], width), percentageToPixel(size[1], height), ]; } return [percentageToPixel(size, width), percentageToPixel(size, width)]; } var templateObject_1$1, templateObject_2$1, templateObject_3$1; var defaultConnectorStyle = { type: 'straight', stroke: 'black', width: 1, markerSize: 6.5, direction: 'cw', strokeWidth: 1, strokeOpacity: 1, strokeLinecap: 'butt', strokeLinejoin: 'miter', strokeMiterlimit: 4, strokeDasharray: 'none', strokeDashoffset: 0, }; var PointAnnotation = function (_a) { var children = _a.children, _b = _a.offset, offset = _b === void 0 ? 0 : _b, connectorStyle = _a.connectorStyle, _c = _a.endMarker, endMarker = _c === void 0 ? 'none' : _c, _d = _a.startMarker, startMarker = _d === void 0 ? 'none' : _d, _e = _a.padding, padding = _e === void 0 ? 0 : _e, textAnchor = _a.textAnchor, _f = _a.animationDelay, animationDelay = _f === void 0 ? 200 : _f, _g = _a.threshold, threshold = _g === void 0 ? 0.1 : _g; var id = React.useId(); var _h = React.useState(false), isVisible = _h[0], setIsVisible = _h[1]; var _j = React.useState(false), hasAnimated = _j[0], setHasAnimated = _j[1]; var _k = useIntersectionObserver({ threshold: threshold, rootMargin: '50px', freezeOnceVisible: true, }), isIntersecting = _k.isIntersecting, ref = _k.ref; React.useEffect(function () { if (isIntersecting && !hasAnimated) { setHasAnimated(true); setTimeout(function () { setIsVisible(true); }, animationDelay); } }, [isIntersecting, animationDelay, hasAnimated]); var _l = getOffset(offset), h = _l[0], v = _l[1]; var connectorSettings = __assign(__assign({}, defaultConnectorStyle), connectorStyle); var connectorDirection = connectorSettings.direction; var direction = getDirection([h, v]); var shiftToTop = direction === 'top' || (direction === 'top-left' && connectorDirection === 'ccw') || (direction === 'top-right' && connectorDirection === 'cw'); var shiftToBottom = direction === 'bottom' || (direction === 'bottom-left' && connectorDirection === 'cw') || (direction === 'bottom-right' && connectorDirection === 'ccw') || (direction === 'top-left' && connectorDirection === 'cw'); var shiftToRight = direction === 'right' || (direction === 'top-right' && connectorDirection === 'ccw') || (direction === 'bottom-right' && connectorDirection === 'cw'); var shiftToLeft = direction === 'left' || (direction === 'top-left' && connectorDirection === 'cw') || (direction === 'bottom-left' && connectorDirection === 'ccw'); var noshift = !shiftToTop && !shiftToBottom && !shiftToRight && !shiftToLeft; if (noshift && padding) { shiftToRight = true; shiftToBottom = true; } var markerSize = connectorSettings.markerSize; var shiftLabelHorizontal = h >= 0 ? 0 : -100; if (textAnchor === 'center') { shiftLabelHorizontal = -50; } if (textAnchor === 'right') { shiftLabelHorizontal = -100; } if (textAnchor === 'left') { shiftLabelHorizontal = 0; } return (React.createElement(AnnotationContainer, { className: 'annoContainer', ref: ref }, React.createElement(LineSvg, { width: Math.max(4, Math.abs(h)), height: Math.max(4, Math.abs(v)), style: { left: h >= 0 ? 0 : h, top: v >= 0 ? 0 : v, }, "$isVisible": isVisible }, React.createElement("defs", null, React.createElement("marker", { id: "arrow-".concat(id), viewBox: "0 0 ".concat(markerSize * 2, " ").concat(markerSize * 2), refX: markerSize, refY: markerSize, markerWidth: markerSize, markerHeight: markerSize, orient: 'auto-start-reverse' }, React.createElement("path", { d: "M 0 0 L ".concat(markerSize * 2, " ").concat(markerSize, " L 0 ").concat(markerSize * 2, " z"), fill: connectorSettings.stroke })), React.createElement("marker", { id: "circle-".concat(id), viewBox: "0 0 ".concat(markerSize * 1.6, " ").concat(markerSize * 1.6), refX: markerSize * 0.8, refY: markerSize * 0.8, markerWidth: markerSize * 0.8, markerHeight: markerSize * 0.8, orient: 'auto-start-reverse' }, React.createElement("circle", { cx: markerSize * 0.8, cy: markerSize * 0.8, r: markerSize * 0.8, fill: connectorSettings.stroke }))), React.createElement(Path, { d: getLinePath(v, h, direction, connectorDirection, connectorSettings.type), style: { stroke: connectorSettings.stroke, strokeWidth: connectorSettings.strokeWidth, strokeLinecap: connectorSettings.strokeLinecap, strokeLinejoin: connectorSettings.strokeLinejoin, strokeDasharray: connectorSettings.strokeDasharray, strokeDashoffset: connectorSettings.strokeDashoffset, strokeMiterlimit: connectorSettings.strokeMiterlimit, strokeOpacity: connectorSettings.strokeOpacity, }, fill: 'none', markerEnd: startMarker === 'arrow' ? "url(#arrow-".concat(id, ")") : startMarker === 'circle' ? "url(#circle-".concat(id, ")") : '', markerStart: endMarker === 'arrow' ? "url(#arrow-".concat(id, ")") : endMarker === 'circle' ? "url(#circle-".concat(id, ")") : '', "$isVisible": isVisible })), React.createElement(ContentContainer, { style: { minWidth: 'max-content', left: h, top: v, transform: "translate(".concat(shiftLabelHorizontal, "%,").concat(v >= 0 ? 0 : 'calc(-100%)', ")"), marginTop: direction === 'left' || direction === 'right' ? '-1em' : 0, paddingRight: shiftToLeft ? padding + 'px' : 0, paddingLeft: shiftToRight ? padding + 'px' : 0, paddingBottom: shiftToTop ? padding + 'px' : 0, paddingTop: shiftToBottom ? padding + 'px' : 0, }, "$isVisible": isVisible }, children))); }; var AnnotationContainer = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n display: inline-block;\n line-height: 1em;\n position: absolute;\n"], ["\n display: inline-block;\n line-height: 1em;\n position: absolute;\n"]))); var ContentContainer = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n position: absolute;\n line-height: 1em;\n opacity: ", ";\n scale: ", ";\n transform: ", ";\n transform-origin: left center;\n transition: opacity 0.3s ease-in-out;\n * {\n line-height: unset;\n }\n\n animation: ", ";\n\n @keyframes scaleUp {\n 0% {\n scale: 0;\n }\n 70% {\n scale: 1.2;\n }\n 100% {\n scale: 1;\n }\n }\n"], ["\n position: absolute;\n line-height: 1em;\n opacity: ", ";\n scale: ", ";\n transform: ", ";\n transform-origin: left center;\n transition: opacity 0.3s ease-in-out;\n * {\n line-height: unset;\n }\n\n animation: ", ";\n\n @keyframes scaleUp {\n 0% {\n scale: 0;\n }\n 70% {\n scale: 1.2;\n }\n 100% {\n scale: 1;\n }\n }\n"])), function (props) { return (props.$isVisible ? 1 : 0); }, function (props) { return (props.$isVisible ? 1 : 0); }, function (props) { var _a; return (_a = props.style) === null || _a === void 0 ? void 0 : _a.transform; }, function (props) { return props.$isVisible ? "scaleUp 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards" : 'none'; }); var LineSvg = styled.svg(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n overflow: visible;\n opacity: ", ";\n transition: opacity 0.3s ease-in-out;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n overflow: visible;\n opacity: ", ";\n transition: opacity 0.3s ease-in-out;\n"])), function (props) { return (props.$isVisible ? 1 : 0); }); var Path = styled.path(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n stroke-dasharray: 1000;\n stroke-dashoffset: ", ";\n transition: stroke-dashoffset 0.6s ease-in-out;\n"], ["\n stroke-dasharray: 1000;\n stroke-dashoffset: ", ";\n transition: stroke-dashoffset 0.6s ease-in-out;\n"])), function (props) { return (props.$isVisible ? 0 : 1000); }); function getOffset(offset) { if (Array.isArray(offset)) { return offset; } return [offset, offset]; } function getDirection(offset) { var h = offset[0], v = offset[1]; if (h === 0 && v === 0) return 'center'; if (h === 0) return v > 0 ? 'bottom' : 'top'; if (v === 0) return h > 0 ? 'right' : 'left'; if (h > 0) { return v > 0 ? 'bottom-right' : 'top-right'; } else { return v > 0 ? 'bottom-left' : 'top-left'; } } function getLinePoints(v, h) { var sx = h >= 0 ? 0 : Math.abs(h); var sy = v >= 0 ? 0 : Math.abs(v); var ex = h >= 0 ? h : 0; var ey = v >= 0 ? v : 0; return { sx: sx, sy: sy, ex: ex, ey: ey }; } function getLinePath(v, h, direction, curveDirection, connectorStyle) { var linePoints = getLinePoints(v, h); if (connectorStyle === 'straight') { return "M ".concat(linePoints.sx, " ").concat(linePoints.sy, " L ").concat(linePoints.ex, " ").concat(linePoints.ey); } var halfH = Math.abs(h / 2); var halfV = Math.abs(v / 2); var c1x, c1y, c2x, c2y; switch (direction) { case 'top': case 'top-right': if (curveDirection === 'cw') { c1x = linePoints.sx + halfH; c1y = linePoints.sy; c2x = linePoints.ex; c2y = linePoints.sy - halfV; } else { c1x = linePoints.sx; c1y = linePoints.sy - halfV; c2x = linePoints.sx + halfH; c2y = linePoints.ey; } break; case 'right': case 'bottom-right': if (curveDirection === 'cw') { c1x = linePoints.sx; c1y = linePoints.sy + halfV; c2x = linePoints.sx + halfH; c2y = linePoints.ey; } else { c1x = linePoints.sx + halfH; c1y = linePoints.sy; c2x = linePoints.ex; c2y = linePoints.sy + halfV; } break; case 'bottom': case 'bottom-left': if (curveDirection === 'cw') { c1x = linePoints.sx - halfH; c1y = linePoints.sy; c2x = linePoints.ex; c2y = linePoints.sy + halfV; } else { c1x = linePoints.sx; c1y = linePoints.sy + halfV; c2x = linePoints.sx - halfH; c2y = linePoints.ey; } break; case 'left': case 'top-left': if (curveDirection === 'cw') { c1x = linePoints.sx; c1y = linePoints.sy - halfV; c2x = linePoints.sx - halfH; c2y = linePoints.ey; } else { c1x = linePoints.sx - halfH; c1y = linePoints.sy; c2x = linePoints.ex; c2y = linePoints.sy - halfV; } break; default: if (curveDirection === 'cw') { c1x = halfH; c1y = linePoints.sy; c2x = linePoints.ex; c2y = halfV; } else { c1x = linePoints.sx; c1y = halfV; c2x = halfH; c2y = linePoints.ey; } } return "M ".concat(linePoints.sx, " ").concat(linePoints.sy, " C ").concat(c1x, " ").concat(c1y, " ").concat(c2x, " ").concat(c2y, " ").concat(linePoints.ex, " ").concat(linePoints.ey); } var templateObject_1, templateObject_2, templateObject_3, templateObject_4; exports.AnnotatedContent = AnnotatedContent; exports.AreaAnnotation = AreaAnnotation; exports.PointAnnotation = PointAnnotation; //# sourceMappingURL=index.js.map