<!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>