Apple Watch Website in Framer

Nandi Muzsik

How can I improve Framer Uni?

Let me know if there’s a missing feature or something that could be improved.

Share feedback

How to Make $10K+ with Framer in 60 days

$10k Undercover Event

Animation

Apple Watch Website in Framer

I recreated the Apple Watch website in Framer, using very little code (almost none). Feel free to remix this project and see for yourself how capable Framer is. Explore how far you can go with this tool in terms of building complex animations and effects.

image of Nandi Muzsik

Created by

Apple Watch Website in Framer

About the resource

This website is 99% no-code. The only element that required code is the 3D render video that begins playing as you start scrolling down the page.

For this, I used the video component in Framer and applied a code override to it. I've provided the code below for you to copy and use in your projects.

Video scroll scrub override

You can also copy this code to create a code override from scratch in your project, which will enable the video to progress as you scroll down the website.

About the resource

This website is 99% no-code. The only element that required code is the 3D render video that begins playing as you start scrolling down the page.

For this, I used the video component in Framer and applied a code override to it. I've provided the code below for you to copy and use in your projects.

Video scroll scrub override

You can also copy this code to create a code override from scratch in your project, which will enable the video to progress as you scroll down the website.

About the resource

This website is 99% no-code. The only element that required code is the 3D render video that begins playing as you start scrolling down the page.

For this, I used the video component in Framer and applied a code override to it. I've provided the code below for you to copy and use in your projects.

Video scroll scrub override

You can also copy this code to create a code override from scratch in your project, which will enable the video to progress as you scroll down the website.

import type { ComponentType } from "react"
import { useState, useEffect } from "react"
import type { MotionValue, Transition } from "framer-motion"
import { useViewportScroll, useTransform } from "framer-motion"
import { gsap } from "gsap"

export function withScrolledProgress(Component): ComponentType {
    const startY = 0
    const distance = 6000
    const endY = startY + distance
    return (props) => {
        const { scrollY } = useViewportScroll()
        const progress = useTransform(scrollY, [startY, endY], [0, 1])
        useEffect(() => {
            const video = document.getElementById("video") as HTMLVideoElement
            gsap.to(video, {
                scrollTrigger: {
                    trigger: ".scroll-container",
                    start: "top top",
                    end: "bottom bottom",
                    scrub: 1,
                    markers: true,
                },
                keyframes: [
                    { progress: 0 },
                    { progress: 0.1 },
                    { progress: 0.2 },
                    { progress: 0.3 },
                    { progress: 0.4 },
                    { progress: 0.5 },
                    { progress: 0.6 },
                    { progress: 0.7 },
                    { progress: 0.8 },
                    { progress: 0.9 },
                    { progress: 1 },
                ],
                ease: "linear",
                duration: 10,
            })

            return () => {
                gsap.killTweensOf(video)
            }
        }, [scrollY, distance])

        return <Component {...props} progress={progress} />
    }
}
import type { ComponentType } from "react"
import { useState, useEffect } from "react"
import type { MotionValue, Transition } from "framer-motion"
import { useViewportScroll, useTransform } from "framer-motion"
import { gsap } from "gsap"

export function withScrolledProgress(Component): ComponentType {
    const startY = 0
    const distance = 6000
    const endY = startY + distance
    return (props) => {
        const { scrollY } = useViewportScroll()
        const progress = useTransform(scrollY, [startY, endY], [0, 1])
        useEffect(() => {
            const video = document.getElementById("video") as HTMLVideoElement
            gsap.to(video, {
                scrollTrigger: {
                    trigger: ".scroll-container",
                    start: "top top",
                    end: "bottom bottom",
                    scrub: 1,
                    markers: true,
                },
                keyframes: [
                    { progress: 0 },
                    { progress: 0.1 },
                    { progress: 0.2 },
                    { progress: 0.3 },
                    { progress: 0.4 },
                    { progress: 0.5 },
                    { progress: 0.6 },
                    { progress: 0.7 },
                    { progress: 0.8 },
                    { progress: 0.9 },
                    { progress: 1 },
                ],
                ease: "linear",
                duration: 10,
            })

            return () => {
                gsap.killTweensOf(video)
            }
        }, [scrollY, distance])

        return <Component {...props} progress={progress} />
    }
}
import type { ComponentType } from "react"
import { useState, useEffect } from "react"
import type { MotionValue, Transition } from "framer-motion"
import { useViewportScroll, useTransform } from "framer-motion"
import { gsap } from "gsap"

export function withScrolledProgress(Component): ComponentType {
    const startY = 0
    const distance = 6000
    const endY = startY + distance
    return (props) => {
        const { scrollY } = useViewportScroll()
        const progress = useTransform(scrollY, [startY, endY], [0, 1])
        useEffect(() => {
            const video = document.getElementById("video") as HTMLVideoElement
            gsap.to(video, {
                scrollTrigger: {
                    trigger: ".scroll-container",
                    start: "top top",
                    end: "bottom bottom",
                    scrub: 1,
                    markers: true,
                },
                keyframes: [
                    { progress: 0 },
                    { progress: 0.1 },
                    { progress: 0.2 },
                    { progress: 0.3 },
                    { progress: 0.4 },
                    { progress: 0.5 },
                    { progress: 0.6 },
                    { progress: 0.7 },
                    { progress: 0.8 },
                    { progress: 0.9 },
                    { progress: 1 },
                ],
                ease: "linear",
                duration: 10,
            })

            return () => {
                gsap.killTweensOf(video)
            }
        }, [scrollY, distance])

        return <Component {...props} progress={progress} />
    }
}

Learn how can one go from 0 to $11.5k with Framer in 60 days.

From no followers, no portfolio, no reputation, to making thousands with a profitable Framer business.

Nandi portrait's background

Learn how can one go from 0 to $11.5k with Framer in 60 days.

From no followers, no portfolio, no reputation, to making thousands with a profitable Framer business.

Nandi portrait's background

Learn how can one go from 0 to $11.5k with Framer in 60 days.

From no followers, no portfolio, no reputation, to making thousands with a profitable Framer business.

Nandi portrait's background

More resources

More resources

  • Business growth cards: Zero to One, Scaling, Quick solutions

    3D Image Split Scroll Animation in Framer

    Animation

    Business growth cards: Zero to One, Scaling, Quick solutions

    3D Image Split Scroll Animation in Framer

    Animation

  • WordPress showcase hero with featured brand logos

    Unmask Sections On Scroll in Framer

    Animation

    WordPress showcase hero with featured brand logos

    Unmask Sections On Scroll in Framer

    Animation