Skip to content

Marquee along SVG scaling issue #59

@dancrump1

Description

@dancrump1

When implementing a different SVG path than the provided example, an issue came up for me. The offsetPath on the motion.div does not scale the same as the <svg><path></svg> above it. The size of the travel the images takes depends on the string value for path.

Sorry if this isn't explained well. I can get the SVG to scale, but the mapped motion.div's remain the size outlined by the value i pass to d={path}. Moving the motion.div inside the SVG doesn't do anything, but making the motion.div a motion.g now allows the SVG to scale the offset-path value.

UPDATED RETURN for marquee:

return (
		<div
			ref={container}
			onPointerDown={handlePointerDown}
			onPointerMove={handlePointerMove}
			onPointerUp={handlePointerUp}
			onPointerCancel={handlePointerUp}
			className={cn("relative", className)}
		>
			<svg
				xmlns="http://www.w3.org/2000/svg"
				width={width}
				height={height}
				viewBox={viewBox}
				preserveAspectRatio={preserveAspectRatio}
			>
				{/* Path for visualization */}
				<path
					id={id}
					d={path}
					className="w-full"
					stroke={showPath ? "currentColor" : "none"}
					fill="none"
					ref={pathRef}
				/>

				{/* Animate each item along the path */}
				{items.map(({ child, repeatIndex, itemIndex, key }) => {
					const itemOffset = useTransform(baseOffset, (v) => {
						const position = (itemIndex * 100) / items.length;
						const wrappedValue = wrap(0, 100, v + position);
						return easing
							? easing(wrappedValue / 100) * 100
							: wrappedValue;
					});

					const x = useMotionValue(0);
					const y = useMotionValue(0);
					const zIndex = useTransform(currentOffsetDistance, (value) =>
						calculateZIndex(value)
					);

					useEffect(() => {
						const pathEl = pathRef.current;
						if (!pathEl) return;

						const totalLength = pathEl.getTotalLength();

						const unsubscribe = itemOffset.on(
							"change",
							(value: string) => {
								const percent = parseFloat(value) / 100;
								const point = pathEl.getPointAtLength(
									percent * totalLength
								);
								x.set(point.x);
								y.set(point.y);
							}
						);

						return unsubscribe;
					}, [itemOffset]);

					const cssVariables = Object.fromEntries(
						(cssVariableInterpolation || []).map(
							({ property, from, to }) => [
								property,
								useTransform(
									currentOffsetDistance,
									[0, 100],
									[from, to]
								),
							]
						)
					);

					return (
						<motion.g
							key={key}
							className={cn(
								"along-element relative",
								draggable && grabCursor && "cursor-grab"
							)}
							style={{
								offsetDistance: itemOffset,
								zIndex: enableRollingZIndex ? zIndex : undefined,
								translateX: x,
								translateY: y,
								...cssVariables,
							}}
							aria-hidden={repeatIndex > 0}
							onMouseEnter={() => (isHovered.current = true)}
							onMouseLeave={() => (isHovered.current = false)}
						>
							{child}
						</motion.g>
					);
				})}
			</svg>
		</div>
	);

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions