https://www.thesun.co.uk/travel/7739308/pilot-lands-plane-cockpit-thunderstorm/
code to my quick slider mechanism animation
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Quick Return Mechanism with Animated Rocket Slider</title>
    <style>
        body {
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #f0f0f0;
        }
        canvas {
            border: 1px solid #333;
        }
    </style>
</head>
<body>
<canvas id="mechanismCanvas" width="800" height="600"></canvas>
<script>
    const canvas = document.getElementById('mechanismCanvas');
    const ctx = canvas.getContext('2d');
    // Image sources with your custom images
    const images = {
        background: 'https://i.imgur.com/RZzBNla.png',
        bullGear: 'https://i.imgur.com/HAeRZEh.png',
        crankArm: 'https://i.imgur.com/lxvIFR9.png',
        slottedLever: 'https://i.imgur.com/L84iEiZ.png',
        slider: 'https://i.imgur.com/JvZKDfw.gif',
    };
    // Load images with fallback handling
    const imageElements = {};
    Object.keys(images).forEach((key) => {
        const img = new Image();
        img.src = images[key];
        img.onload = () => (imageElements[key] = img);
        img.onerror = () => (imageElements[key] = null);
    });
    // Mechanism parameters
    const pivotX = 300;
    const pivotY = 300;
    const bullGearRadius = 100;
    const crankLength = 100;
    const slottedLeverLength = 400;
    const secondaryPivotX = pivotX + 200;
    const secondaryPivotY = pivotY + 150;
    let angle = 0;
    let gearRotationAngle = 0;
    const speed = 0.03;
    const tracePoints = [];
    let previousX = 0;
    let currentRotation = 0;
    let targetRotation = 0;
    let isFlipping = false;
    const rocketSize = 80;
    // Function to draw the custom background
    function drawBackground() {
        const img = imageElements.background;
        if (img) {
            ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
        } else {
            ctx.fillStyle = '#f0f0f0';
            ctx.fillRect(0, 0, canvas.width, canvas.height);
        }
    }
    // Function to draw the rotating bull gear
    function drawBullGear() {
        const img = imageElements.bullGear;
        ctx.save();
        ctx.translate(pivotX, pivotY);
        ctx.rotate(gearRotationAngle);
        if (img) {
            ctx.drawImage(img, -bullGearRadius, -bullGearRadius, bullGearRadius * 2, bullGearRadius * 2);
        } else {
            ctx.strokeStyle = '#ff8800';
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.arc(0, 0, bullGearRadius, 0, 2 * Math.PI);
            ctx.stroke();
        }
        ctx.restore();
    }
    // Function to draw the custom crank arm
    function drawCrankArm() {
        const crankX = pivotX + crankLength * Math.cos(angle);
        const crankY = pivotY + crankLength * Math.sin(angle);
        const img = imageElements.crankArm;
        if (img) {
            ctx.save();
            ctx.translate(pivotX, pivotY);
            ctx.rotate(angle);
            ctx.drawImage(img, -10, -10, crankLength + 20, 20);
            ctx.restore();
        } else {
            ctx.strokeStyle = '#0000ff';
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.moveTo(pivotX, pivotY);
            ctx.lineTo(crankX, crankY);
            ctx.stroke();
        }
        ctx.fillStyle = '#0000ff';
        ctx.beginPath();
        ctx.arc(crankX, crankY, 8, 0, 2 * Math.PI);
        ctx.fill();
        return { crankX, crankY };
    }
    // Function to draw the flipped slotted lever
    function drawSlottedLever(crankX, crankY) {
        const leverAngle = Math.atan2(crankY - secondaryPivotY, crankX - secondaryPivotX);
        const leverEndX = secondaryPivotX + slottedLeverLength * Math.cos(leverAngle);
        const leverEndY = secondaryPivotY + slottedLeverLength * Math.sin(leverAngle);
        const img = imageElements.slottedLever;
        if (img) {
            ctx.save();
            ctx.translate(secondaryPivotX, secondaryPivotY);
            ctx.rotate(leverAngle);
            ctx.scale(-1, 1);
            ctx.drawImage(img, -slottedLeverLength, -10, slottedLeverLength, 20);
            ctx.restore();
        } else {
            ctx.strokeStyle = '#ff00aa';
            ctx.lineWidth = 4;
            ctx.beginPath();
            ctx.moveTo(secondaryPivotX, secondaryPivotY);
            ctx.lineTo(leverEndX, leverEndY);
            ctx.stroke();
        }
        ctx.fillStyle = '#ff00ff';
        ctx.beginPath();
        ctx.arc(secondaryPivotX, secondaryPivotY, 10, 0, 2 * Math.PI);
        ctx.fill();
        return { leverEndX, leverEndY };
    }
    // Function to smoothly rotate the rocket slider
    function drawSlider(leverEndX, leverEndY) {
        const img = imageElements.slider;
        if (leverEndX < previousX && !isFlipping) {
            targetRotation = Math.PI;
            isFlipping = true;
        } else if (leverEndX > previousX && isFlipping) {
            targetRotation = 0;
            isFlipping = false;
        }
        previousX = leverEndX;
        currentRotation += (targetRotation - currentRotation) * 0.1;
        if (img) {
            ctx.save();
            ctx.translate(leverEndX, leverEndY);
            ctx.rotate(currentRotation);
            ctx.drawImage(img, -rocketSize / 2, -rocketSize / 2, rocketSize, rocketSize);
            ctx.restore();
        }
        tracePoints.push({ x: leverEndX, y: leverEndY });
        if (tracePoints.length > 300) tracePoints.shift();
        ctx.strokeStyle = '#FFFF00';
        ctx.lineWidth = 2;
        ctx.beginPath();
        for (let i = 0; i < tracePoints.length - 1; i++) {
            ctx.moveTo(tracePoints[i].x, tracePoints[i].y);
            ctx.lineTo(tracePoints[i + 1].x, tracePoints[i + 1].y);
        }
        ctx.stroke();
    }
    // Function to draw the overlay text
    function drawOverlayText() {
        ctx.fillStyle = '#FFFFFF';
        ctx.font = '16px Arial';
        ctx.fillText('Ramses Suarez Valerio', 10, 20);
        ctx.fillText('Student ID: 24070499', 10, 40);
        ctx.fillText('EMT 1220 HW3 EXTRA CREDIT CODE', 10, 60);
    }
    // Animation loop
    function animate() {
        drawBackground();
        drawBullGear();
        const { crankX, crankY } = drawCrankArm();
        const { leverEndX, leverEndY } = drawSlottedLever(crankX, crankY);
        drawSlider(leverEndX, leverEndY);
        drawOverlayText();
        angle += speed;
        gearRotationAngle += speed;
        if (angle >= 2 * Math.PI) angle = 0;
        if (gearRotationAngle >= 2 * Math.PI) gearRotationAngle = 0;
        requestAnimationFrame(animate);
    }
    animate();
</script>
</body>
</html>