SVG 夜晚的灯塔案例(use、mask、clipPath ...)

简介: SVG 夜晚的灯塔案例(use、mask、clipPath ...)
  • 案例效果

  • 案例代码
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    html,body {
      margin: 0;
      padding: 0;
      /* 全屏 */
      width: 100%;
      height: 100%;
      /* 清空字号,免得影响 svg */
      line-height: 0;
      font-size: 0;
      /* 天空颜色 */
      background-color: #001122;
    }
  </style>
</head>
<body>
  <!-- svg -->
  <svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="-400 -300 800 600">
    <!-- 模板 -->
    <defs>
      <!-- 星星 -->
      <polygon id="star" points="0 -10 2 -2 10 0 2 2 0 10 -2 2 -10 0 -2 -2" fill="#fff"/>
    </defs>
    <!-- 真实:天空 + 灯塔 -->
    <g id="real">
      <!-- 星星组 -->
      <g id="star-group"></g>
      <!-- 灯塔 -->
      <g id="light-tower">
        <!-- 模板 -->
        <defs>
          <!-- 灯塔颜色渐变 -->
          <linearGradient id="tower" x1="0" y1="0" x2="1" y2="0">
            <stop offset="0" stop-color="#999"/>
            <stop offset="1" stop-color="#333"/>
          </linearGradient>
          <!-- 灯光颜色渐变 -->
          <radialGradient id="light" cx="0.5" cx="0.5" r="0.5">
            <stop offset="0" stop-color="rgba(255, 255, 255, 0.8)"/>
            <stop offset="1" stop-color="rgba(255, 255, 255, 0)"/>
          </radialGradient>
          <!-- 灯光裁剪范围 -->
          <clipPath id="light-clip">
            <!-- 灯光 -->
            <polygon points="0 0 -400 -15 -400 15" fill="rgba(255, 0, 0, 0.5)"/>
            <!-- 灯点 -->
            <circle cx="0" cy="0" r="2"/>
            <!-- 灯光旋转动画 -->
            <animateTransform attributeName="transform"
              attributeType="XML"
              type="rotate"
              from="0"
              to="360"
              dur="10s"
              repeatCount="indefinite"/>
          </clipPath>
        </defs>
        <!-- 灯塔 -->
        <polygon points="0 0 5 50 -5 50" fill="url(#tower)"/>
        <!-- 灯塔光 -->
        <ellipse cx="0" cy="0" rx="300" ry="100" fill="url(#light)" clip-path="url(#light-clip)"/>
      </g>
      <!-- 月亮 -->
      <g id="moon-group">
        <!-- 月亮蒙板,颜色越亮可见,越黑不可见 -->
        <mask id="moon-mask">
          <circle cx="-300" cy="-150" r="100" fill="white"/>
          <circle cx="-260" cy="-180" r="100" fill="black"/>
        </mask>
        <!-- 月亮形状 -->
        <circle cx="-300" cy="-150" r="100" fill="yellow" mask="url(#moon-mask)"/>
      </g>
    </g>
    <!-- 反射:天空 + 灯塔 -->
    <g id="reflact" mask="url(#fading)">
      <!-- 模板 -->
      <defs>
        <!-- 海面渐变 -->
        <linearGradient id="fade" x1="0" y1="0" x2="0" y2="1">
          <stop offset="0" stop-color="rgba(255, 255, 255, 0.5)"/>
          <stop offset="0.5" stop-color="rgba(255, 255, 255, 0)"/>
        </linearGradient>
        <!-- 海面蒙板,颜色越亮可见,越黑不可见 -->
        <mask id="fading">
          <!-- 海面 -->
          <rect x="-800" y="0" width="1600" height="600" fill="url(#fade)"/>
        </mask>
      </defs>
      <!-- 将 真实 进行反转 -->
      <use xlink:href="#real" transform="scale(1, -1)  translate(0, -100)"/>
    </g>
    <!-- 分割线 -->
    <line x1="-800" y1="50" x2="800" y2="50" stroke="#fff"/>
  </svg>
  <script>
    // 命名空间
    var SVG_NS = 'http://www.w3.org/2000/svg'
    var XLINK_NS = 'http://www.w3.org/1999/xlink'
    // 画布
    var paper = document.querySelector('svg')
    // 渲染星星
    function renderSatr () {
      // 获取星星模板
      var starRef = document.getElementById('star')
      // 获取星星画板
      var starGroup = document.getElementById('star-group')
      // 星星数量
      var starCount = 1000
      // 当前星星
      var star
      while (starCount--) {
        // 通过 use 标签使用星星模板
        star = use(starRef)
        // 星星透明度
        star.setAttribute('opacity', random(0.1, 0.4))
        // 星星摆放位置
        star.setAttribute('transform', `translate(${random(-800, 800)}, ${random(-300, 50)}) scale(${random(0.1, 0.6)})`)
        // 添加到星星画板
        starGroup.append(star)
      }
    }
    // 开始渲染星星
    renderSatr()
    // 创建 use 标签
    function use(origin) {
      var _use = document.createElementNS(SVG_NS, 'use')
      _use.setAttributeNS(XLINK_NS, 'xlink:href', `#${origin.id}`)
      return _use
    }
    // 随机函数
    function random(min, max) {
      return min + (max - min) * Math.random()
    }
  </script>
</body>
</html>



相关文章
|
3月前
|
数据可视化
ggGenshin&Genshinpalette|SCI绘图遇上原神,不输于CNS正刊调色板
本文介绍了两个R包——`ggGenshin`和`Genshinpalette`,它们提供了基于热门游戏《原神》角色色彩的调色板,用于数据可视化。`ggGenshin`包包含了一系列与游戏角色相关的颜色,可以方便地应用到`ggplot2`图形中,而`Genshinpalette`包则提供了更多角色的配色选项。通过这两个包,用户可以直接使用预设的配色方案,提升图表的视觉效果。文中还展示了使用这些调色板绘制的一些示例图表。
162 0
|
机器学习/深度学习 编解码 算法
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
CV之NoGAN:利用图像增强技术(图片上色)实现对旧图像和电影片段进行着色和修复(爱因斯坦、鲁迅旧照/清末官员生活场景等案例)
|
前端开发
看图说话,新 CSS 单位 “svh” “dvh” 原来如此
看图说话,新 CSS 单位 “svh” “dvh” 原来如此
|
前端开发 容器
「CSS畅想」七夕寄情,我绘制了一副双色莲花图
用技术实现梦想,用梦想打开创意之门。七夕寄情,我用CSS绘制了一副双色莲花图。
172 1
「CSS畅想」七夕寄情,我绘制了一副双色莲花图
|
图形学 开发者
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
343 0
Unity【Dynamic Bone】- 关于人物模型头发、衣物等细节的处理
|
算法框架/工具 计算机视觉 Python
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时脸部表情检测
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时脸部表情检测
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时脸部表情检测
|
算法 算法框架/工具 计算机视觉
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略(二)
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略(二)
|
算法 计算机视觉
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略(一)
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略
CV之NS:图像风格迁移(Neural Style 图像风格变换)算法简介、过程思路、关键步骤配图、案例应用之详细攻略(一)
|
算法框架/工具 计算机视觉 Python
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别&脸部表情检测
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别&脸部表情检测
CV:基于keras利用cv2自带两步检测法对《跑男第六季第五期》之如花片段(或调用摄像头)进行实时性别&脸部表情检测