Site icon Puneet Sharma – Freelance Web Developer

Hero with cool spotlight effect and cursor tracking

hero section layout with spotlight effect and cursor tracking
Hero section layout with spotlight effect and cursor tracking

Here is HTML, CSS, JS code for a very cool hero section that has a spotlight effect, cursor tracking, and menu. The code uses the GSAP JavaScript library. The menu is also very cool that opens up with expanding animation. Everything is responsive as well.

Check out this demo below first and then you can have a look at the source code that you can directly copy-paste to your local HTML file and run it as it is.

DEMO

Open demo in full window – https://demos.webdevpuneet.com/set1/hero-cursor-tracking/index.html


Source Code

<!-- webdevpuneet.com -->
<!DOCTYPE html>
<html lang="en">
<head>
  <title>Hero with cursor tracking and menu using GSAP</title>
  <meta name="description" content="Demo for Hero with cursor tracking and menu using GSAP" />
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
  <meta name="robots" content="INDEX,FOLLOW" />
  <script src="https://unpkg.co/gsap@3/dist/gsap.min.js"></script>
  <style>
  @import url("https://fonts.googleapis.com/css?family=Montserrat:700");

* {
	box-sizing: border-box;
}

:root {
	--bg: rgb(9, 14, 23);
	--gradientBg: linear-gradient(45deg, #40e0d0, #9932cc, #ff1493, orange);
}

body {
	font-family: Montserrat, sans-serif;
	min-height: 100vh;
	margin: 0;
	padding: 0;
	background-color: var(--bg);
	color: #ffffff;
}

/* Reset */
a {
	color: inherit;
}

ul {
	list-style: none;
}

button {
	border-radius: 0.4em;
	background: var(--bg);
	color: white;
	border: none;
	padding: 0.5rem;
	font-size: inherit;
	cursor: pointer;
}

.wrapper {
	position: relative;
}

/* Text */
.hero__heading {
	font-size: clamp(2rem, 5vw, 8rem);
	text-transform: uppercase;
	margin: 0;
}

/* Menu */
.menu {
	width: 100%;
	height: 100%;
	top: 0;
	left: 0;
	position: fixed;
	text-align: center;
	display: flex;
	justify-content: center;
	align-items: center;
	pointer-events: none;
	background: var(--gradientBg);
	clip-path: circle(0 at calc(100% - 2rem) 2rem);
	transition: clip-path 500ms;
	z-index: 1;
	font-size: clamp(1rem, 2vw, 4rem);
}

.menu.is-open {
	clip-path: circle(200% at calc(100% - 2rem) 2rem);
	pointer-events: all;
}

.menu a {
	display: block;
	padding: 0.5em;
}

.menu-button {
	position: fixed;
	top: 1rem;
	right: 1rem;
	z-index: 2;
}

.menu-button span:last-child,
.menu-button.is-active span:first-child {
	display: none;
}

.menu-button.is-active span:last-child {
	display: inline;
}

/* Hero */
.hero {
	min-height: 100vh;
	padding: clamp(1rem, 2vw, 5rem);
	display: flex;
	align-items: center;
}

.hero--secondary {
	--mask: radial-gradient(
		circle at var(--x, 50%) var(--y, 50%),
    black var(--maskSize1, 0),
		transparent 0,
		transparent var(--maskSize2, 0),
    black var(--maskSize2, 0),
		black var(--maskSize3, 0),
		transparent 0);
	position: absolute;
	top: 0;
	left: 0;
	width: 100%;
	height: 100%;
	background: var(--gradientBg);
	color: rgb(9, 14, 23);
	-webkit-mask-image: var(--mask);
	mask-image: var(--mask);
}


  </style>
</head>
<body>

  <header>
  	<button class="menu-button" data-btn="menu">
  		<span>Menu</span>
  		<span>Close</span>
  	</button>
  	<nav class="menu" data-menu>
  		<ul>
  			<li>
  				<a href="">About me</a>
  			</li>
  			<li>
  				<a href="">Projects</a>
  			</li>
  			<li>
  				<a href="">Writing</a>
  			</li>
  		</ul>
  	</nav>
  </header>


  <div class="wrapper">
  	<div class="hero">
  		<h1 class="hero__heading">Welcome to my website</h1>
  	</div>

  	<div class="hero hero--secondary" aria-hidden="true" data-hero>
  		<p class="hero__heading">Welcome to my website</p>
  	</div>
  </div>

  <div class="article-link" style="margin-bottom:20px;">
    <a href="https://webdevpuneet.com/hero-with-cool-spotlight-effect-and-cursor-tracking/" target="_blank" style="display: inline-block; color:blue:!important;text-decoration: none;border:1px solid blue;color:blue;line-height:1;border-radius:25px;font-size:14px;padding:5px 20px;display:inline-block;">View article and source code &raquo;</a>
  </div>

  <script>
    const hero = document.querySelector('[data-hero]')

    /* Menu */
    const menuButton = document.querySelector('[data-btn="menu"]')
    const menu = document.querySelector('[data-menu]')

    menuButton.addEventListener('click', () => {
    	menu.classList.toggle('is-open')
    	menuButton.classList.toggle('is-active')
    })

    /* Timeline */
    const tl = gsap.timeline()

    tl
    	.to(hero, {
    		'--maskSize1': '20%',
    		duration: 0.5,
        ease: 'back.out(2)',
    	})
    	.to(hero, {
    		'--maskSize2': '28%',
        '--maskSize3': 'calc(28% + 0.1rem)',
    		duration: 0.5,
        delay: 0.5,
        ease: 'back.out(2)',
    	})

    /* Cursor */
    window.addEventListener('mousemove', (e) => {
    	const { clientX, clientY } = e
      const x = Math.round((clientX / window.innerWidth) * 100)
      const y = Math.round((clientY / window.innerHeight) * 100)

    	gsap.to(hero, {
        '--x': `${x}%`,
        '--y': `${y}%`,
        duration: 0.3,
        ease: 'sine.out',
      })
    })
  </script>
</body>
</html>

Screenshots

Exit mobile version