Scrollable page, animated cursor

I would like to create a page like this https://www.krissrealestate.com/, basically having one line stable and the cursor moving while scrolling and on the line have content as here https://infovis.fh-potsdam.de/decolonizing/

Would love any kind of input

Thank you

Already tried this in css and java, but I am mostly not sure how to place the images on the line and then have a box with information appearing when the user clicks on them, my intention is to make an experience based on an exhibition.




body {
    cursor: none; /* Hide the default cursor */
    margin: 0;
    padding: 0;
}

#cursor-canvas {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none; /* Ensure canvas does not interfere with other elements */
    z-index: 9999; /* Make sure it's on top */
}

.content {
    height: 300vh; /* Make content tall enough to scroll */
}

.section {
    height: 100vh;
    border-bottom: 1px solid #ddd;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2em;
}


JAVA
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('cursor-canvas');
    const ctx = canvas.getContext('2d');
    
    // Set canvas size
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // Create a longer zigzag line that spans the scrollable height
    const lineSpacing = 50; // Horizontal distance between zigzag points
    const zigzagHeight = 30; // Vertical distance for each zigzag

    const startX = canvas.width / 2 - lineSpacing / 2;
    const endX = canvas.width / 2 + lineSpacing / 2;
    
    // Create a continuous zigzag line
    const zigzagPath = [];
    for (let y = -canvas.height; y < 2 * canvas.height; y += zigzagHeight) {
        let x1 = startX;
        let x2 = endX;
        if ((y / zigzagHeight) % 2 === 0) {
            x1 += Math.random() * 20; // Asymmetric shift
            x2 -= Math.random() * 20; // Asymmetric shift
        } else {
            x1 -= Math.random() * 20; // Asymmetric shift
            x2 += Math.random() * 20; // Asymmetric shift
        }
        zigzagPath.push({ x: x1, y });
        zigzagPath.push({ x: x2, y: y + zigzagHeight });
    }

    function drawZigzag() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
  
        ctx.lineWidth = 2; // Line width
        ctx.lineCap = 'round'; // Rounded end caps for smooth lines

        // Draw zigzag path with glowing effect
        ctx.shadowColor = 'rgba(255, 0, 0, 0.8)'; // Red glowing color
        ctx.shadowBlur = 10; // Glowing intensity
  
        ctx.strokeStyle = '#ff0000'; // Line color

        ctx.beginPath();
        ctx.moveTo(zigzagPath[0].x, zigzagPath[0].y);
        for (let i = 1; i < zigzagPath.length; i++) {
            ctx.lineTo(zigzagPath[i].x, zigzagPath[i].y);
        }
        ctx.stroke();
    }

    // Track cursor movement
    let lastX, lastY;
    const lines = [];
    document.addEventListener('mousemove', (event) => {
        const x = event.clientX;
        const y = event.clientY;
  
        if (lastX !== undefined && lastY !== undefined) {
            addLine(lastX, lastY, x, y);
        }
  
        lastX = x;
        lastY = y;
    });

    // Track scroll position and update cursor trail
    function addLine(x1, y1, x2, y2) {
        lines.push({ x1, y1, x2, y2 });
        if (lines.length > 100) {
            lines.shift(); // Remove the oldest line if exceeding limit
        }
        drawZigzag();
        drawLines();
    }
  
    function drawLines() {
        ctx.beginPath();
        lines.forEach(line => {
            ctx.moveTo(line.x1, line.y1);
            ctx.lineTo(line.x2, line.y2);
        });
        ctx.stroke();
    }

    // Draw initial zigzag line
    drawZigzag();
  
    // Update canvas size on window resize
    window.addEventListener('resize', () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;`
your text`
        drawZigzag();
    });



body {
    cursor: none; /* Hide the default cursor */
    margin: 0;
    padding: 0;
}

#cursor-canvas {
    position: fixed;
    top: 0;
    left: 0;
    pointer-events: none; /* Ensure canvas does not interfere with other elements */
    z-index: 9999; /* Make sure it's on top */
}

.content {
    height: 300vh; /* Make content tall enough to scroll */
}

.section {
    height: 100vh;
    border-bottom: 1px solid #ddd;
    display: flex;
    justify-content: center;
    align-items: center;
    font-size: 2em;
}


JAVA
document.addEventListener('DOMContentLoaded', () => {
    const canvas = document.getElementById('cursor-canvas');
    const ctx = canvas.getContext('2d');
    
    // Set canvas size
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    // Create a longer zigzag line that spans the scrollable height
    const lineSpacing = 50; // Horizontal distance between zigzag points
    const zigzagHeight = 30; // Vertical distance for each zigzag

    const startX = canvas.width / 2 - lineSpacing / 2;
    const endX = canvas.width / 2 + lineSpacing / 2;
    
    // Create a continuous zigzag line
    const zigzagPath = [];
    for (let y = -canvas.height; y < 2 * canvas.height; y += zigzagHeight) {
        let x1 = startX;
        let x2 = endX;
        if ((y / zigzagHeight) % 2 === 0) {
            x1 += Math.random() * 20; // Asymmetric shift
            x2 -= Math.random() * 20; // Asymmetric shift
        } else {
            x1 -= Math.random() * 20; // Asymmetric shift
            x2 += Math.random() * 20; // Asymmetric shift
        }
        zigzagPath.push({ x: x1, y });
        zigzagPath.push({ x: x2, y: y + zigzagHeight });
    }

    function drawZigzag() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
  
        ctx.lineWidth = 2; // Line width
        ctx.lineCap = 'round'; // Rounded end caps for smooth lines

        // Draw zigzag path with glowing effect
        ctx.shadowColor = 'rgba(255, 0, 0, 0.8)'; // Red glowing color
        ctx.shadowBlur = 10; // Glowing intensity
  
        ctx.strokeStyle = '#ff0000'; // Line color

        ctx.beginPath();
        ctx.moveTo(zigzagPath[0].x, zigzagPath[0].y);
        for (let i = 1; i < zigzagPath.length; i++) {
            ctx.lineTo(zigzagPath[i].x, zigzagPath[i].y);
        }
        ctx.stroke();
    }

    // Track cursor movement
    let lastX, lastY;
    const lines = [];
    document.addEventListener('mousemove', (event) => {
        const x = event.clientX;
        const y = event.clientY;
  
        if (lastX !== undefined && lastY !== undefined) {
            addLine(lastX, lastY, x, y);
        }
  
        lastX = x;
        lastY = y;
    });

    // Track scroll position and update cursor trail
    function addLine(x1, y1, x2, y2) {
        lines.push({ x1, y1, x2, y2 });
        if (lines.length > 100) {
            lines.shift(); // Remove the oldest line if exceeding limit
        }
        drawZigzag();
        drawLines();
    }
  
    function drawLines() {
        ctx.beginPath();
        lines.forEach(line => {
            ctx.moveTo(line.x1, line.y1);
            ctx.lineTo(line.x2, line.y2);
        });
        ctx.stroke();
    }

    // Draw initial zigzag line
    drawZigzag();
  
    // Update canvas size on window resize
    window.addEventListener('resize', () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;`
your text`
        drawZigzag();
    });