Spotlight-default-Method

SVG Spotlight using the default userSpaceOnUse and objectBoundingBox methods on filter.

by Alex Grant

HTML

<body>
  <div class="scene-container content">
    <h2>Here's a spotlight.</h2>
    <svg class="spot" viewBox="0 0 2000 3000" preserveAspectRatio="xMidYMid">
      <defs>
        <filter id="spot-light">
          <feGaussianBlur in="SourceAlpha" stdDeviation="8" result="blur1"></feGaussianBlur>
          <feSpecularLighting result="specOut" in="blur1" specularConstant="1.8" specularExponent="5" lighting-color="#ffffff">
            <feSpotLight x="1000" y="-300" z="100" pointsAtX="1000" pointsAtY="1800" pointsAtZ="25" limitingConeAngle="9.5"></feSpotLight>
          </feSpecularLighting>
          <feComposite in="SourceGraphic" in2="specOut" operator="arithmetic" k1="0" k2="1" k3="1" k4="0"></feComposite>
        </filter>
        <clipPath id="spot-clip">
          <rect x="-50" y="2840" width="2200" height="200"></rect>
        </clipPath>
        <filter id="spot-blur">
          <feGaussianBlur in="SourceGraphic" stdDeviation="15"></feGaussianBlur>
        </filter>
      </defs>
      <g transform="translate(0, -175)" filter="url(#spot-light)">
        <ellipse cx="50%" cy="95.333%" rx="27%" ry="130" fill="#fff" clip-path="url(#spot-clip)" filter="url(#spot-blur)"></ellipse>
        <rect x="25%" y="43.667%" width="50%" height="50%" stroke="peru" stroke-width="3%" stroke-linejoin="round" fill="#000"></rect>
      </g>
    </svg>
  </div>
</body>

CSS

body {
  margin: 0;
  padding: 0;
  font-family: sans-serif;
  font-size: 16px;
  color: #fff;
}

* {
  transform-origin: 50% 50% 0;
}

.scene-container {
  display: flex;
  flex-flow: column nowrap;
  justify-content: center;
  align-items: center;
}

.scene-container.content {
  position: relative;
  width: 100%;
  height: 150vh;
  background-image: linear-gradient(hsla(240, 90%, 8%, 1) 0%, 99%, hsla(217, 24%, 71%, 0) 100%);
  box-shadow: 0px -10px 20px hsl(240, 90%, 8%);
}

.spot {
  height: 100%;
  width: 100%;
}