canvas#main-canvas
canvas#star-canvas
.planets
.planet
.crater
.crater
.planet
.planet-background
.crater
.crater
#cursor
.rocket.floating.shadow <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 178.62 203.18"><path d="M1015.59,714.44l171.81-.62a3.4,3.4,0,0,0,2.9-5.16l-86.46-143.28a3.4,3.4,0,0,0-5.84,0l-85.35,143.9A3.4,3.4,0,0,0,1015.59,714.44Z" transform="translate(-1012.17 -531.96)" fill="#b5b4ff"/><path d="M1101.5,563.8V714.13l-85.91.31a3.4,3.4,0,0,1-2.93-5.14L1098,565.4A3.34,3.34,0,0,1,1101.5,563.8Z" transform="translate(-1012.17 -531.96)" fill="#fff"/><ellipse cx="89.15" cy="101.59" rx="48.79" ry="101.59" fill="#fff"/><path d="M1101.5,532c26.95,0,48.79,45.48,48.79,101.59s-21.84,101.59-48.79,101.59V532Z" transform="translate(-1012.17 -531.96)" fill="#d9d9ff"/><path d="M1101.5,532c28.48,0.6,48.61,45.48,48.61,101.59s-17,77.64-19.2,81.07c0,0,2.78-44.72.74-85.46C1127.54,547.08,1101.5,532,1101.5,532Z" transform="translate(-1012.17 -531.96)" fill="#b5b4ff"/><circle cx="1101.5" cy="592.37" r="18.83" transform="translate(-1108.42 420.42) rotate(-45)" fill="#1a0a53" stroke="#fff" stroke-miterlimit="10" stroke-width="5"/><path d="M1106.71,582.26c-2.14.16-4.34,5-3.94,10.41s3.27,9.34,5.41,9.18,4.37-4.92,4-10.33S1108.85,582.1,1106.71,582.26Z" transform="translate(-1012.17 -531.96)" fill="#fff"/></svg>
HTML
格式化
支持Emmet,输入 p 后按 Tab键试试吧!
<head> ... </head>
<body>
</body>
body {
width: 100%;
height: 100%;
overflow: hidden;
cursor: none;
background: #281154;
* {
cursor: inherit;
}
}
canvas {
z-index:1;
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
}
canvas#main-canvas {
z-index:3;
}
#cursor {
z-index: 9999;
position: absolute;
will-change: transform;
pointer-events: none;
transition: 0.25s ease font-size;
-webkit-transform-origin: 50%;
transform-origin: 50%;
top: -20px;
left: -30px;
width: 60px;
height: 60px;
// border:1px solid white;
.rocket {
will-change: transform;
width: 100%;
height: 100%;
pointer-events: none;
position: absolute;
top: 50%;
left: 50%;
-webkit-transform: translate(-50%, -50%);
transform: translate(-50%, -50%);
-webkit-transform-origin: 0 0;
transform-origin: 0 0;
}
}
.shadow {
&:after {
content:'';
background-color: rgba(0, 0, 0, 0.2);
width:100%;
height:20px;
position: absolute;
bottom:-40px;
left:0;
border-radius: 100%;
}
}
@keyframes floating {
50% {
top: calc(50% - 3px);
}
}
.floating {
z-index: auto;
animation: floating 0.5s infinite ease-in-out;
}
.planets {
width:100%;
height:100%;
top:0;
left:0;
position: absolute;
}
.planet {
z-index:2;
position: absolute;
bottom: 0;
background-color: #FED705;
width: 600px;
height: 500px;
bottom: -350px;
border-radius: 50%;
box-shadow: inset -60px -40px 0 rgba(0, 0, 0, 0.2);
.crater {
position: absolute;
border-radius: 100%;
background: rgba(0, 0, 0, 0.15);
box-shadow: inset 8px 8px 0 rgba(0, 0, 0, 0.2);
}
.crater:first-child {
width: 100px;
height: 100px;
top: 90px;
left: 90px;
}
.crater:nth-child(2) {
width: 170px;
height: 150px;
top: 40px;
right: 120px;
}
}
.planet:first-child {
margin-left: auto;
margin-right: auto;
left: 0;
right: 0;
}
.planet:nth-child(2) {
background-color: #281154;
width: 150px;
height: 150px;
top: 100px;
right: 100px;
position: absolute;
;
.crater {
box-shadow: inset 4px 4px 0 rgba(0, 0, 0, 0.2);
}
.crater:first-child {
width: 30px;
height: 30px;
top: 20px;
left: 20px;
}
.crater:nth-child(2) {
width: 60px;
height: 60px;
top: 70px;
left: 70px;
}
.planet-background {
background-color: #ffffff;
opacity: 0.4;
width:100%;
height:100%;
border-radius: 100%;
box-shadow: inset -20px -20px 0 rgba(0, 0, 0, 0.2)
}
}
var canvas = document.getElementById("main-canvas");
var ctx = canvas.getContext("2d");
var width = (canvas.width = window.innerWidth);
var height = (canvas.height = window.innerHeight);
var starCanvas = document.getElementById("star-canvas");
var ctx2 = starCanvas.getContext("2d");
starCanvas.width = window.innerWidth;
starCanvas.height = window.innerHeight;
var rocket = document.querySelector(".rocket");
var showers = [];
var stars = [];
var moving = !1;
var hasMoved = !1;
var timeout;
var colors = [
"#EAEAFE",
"#16FAE7",
"#CF267E ",
"#FED705",
"#A33EEC",
"#F578DF"
];
var gravity = 0.05;
var particlesDensity = 7;
let cursorPos = { x: width / 2, y: height - 200 };
window.addEventListener("mousemove", mousemove);
window.addEventListener("touchmove", touchmove);
function mousemove(e) {
hasMoved = !0;
if (hasMoved) rocket.classList.remove("shadow");
mouseHasStopped();
cursorPos = {
x: e.offsetX,
y: e.offsetY
};
}
function touchmove(e) {
hasMoved = !0;
if (hasMoved) rocket.classList.remove("shadow");
mouseHasStopped();
cursorPos = {
x: e.targetTouches[0].offsetX,
y: e.targetTouches[0].offsetY
};
}
window.addEventListener("resize", resize);
function resize() {
width = canvas.width = window.innerWidth;
height = canvas.height = window.innerHeight;
starCanvas.width = window.innerWidth;
starCanvas.height = window.innerHeight;
makeStars.createStars();
}
function mouseHasStopped() {
clearTimeout(timeout);
moving = !0;
timeout = setTimeout(function() {
moving = !1;
}, 100);
}
function random(min, max) {
if (max == null) {
max = min;
min = 0;
}
return Math.random() * (max - min) + min;
}
var makeParticles = (function() {
function Particle(x, y, vx, vy, size, color, life) {
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.size = size;
this.color = color;
this.life = life;
this.opacity = 1;
this.update = () => {
this.opacity -= this.opacity / (life / 0.1);
this.size -= this.size / (life / 0.1);
if (this.size < 0) this.size = 0;
this.life -= 0.1;
this.vy += gravity;
this.x += this.vx;
this.y += this.vy;
this.draw();
};
this.draw = () => {
ctx.beginPath();
ctx.globalAlpha = this.opacity;
ctx.fillStyle = this.color;
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
ctx.fill();
ctx.closePath();
};
this.remove = () => {
return this.life <= 0;
};
}
function Shower(x, y) {
this.particles = [];
this.initParticles = function() {
for (var i = 1; i <= particlesDensity; i++) {
var vx = -2 + random(0, 4);
var vy = random(0, 2);
var size = random(1, 5);
var life = random(7, 9);
var color = colors[Math.floor(Math.random() * colors.length)];
var p = new Particle(x, y, vx, vy, size, color, life);
this.particles.push(p);
}
};
if (moving) this.initParticles();
this.explode = function() {
for (var i = 0; i < this.particles.length; i++) {
this.particles[i].update();
if (this.particles[i].remove() == true) {
this.particles.splice(i, 1);
}
}
};
}
function animate() {
ctx.clearRect(0, 0, width, height);
var n = new Shower(cursorPos.x, cursorPos.y);
showers.push(n);
for (var i = 0; i < showers.length; i++) {
showers[i].explode();
}
window.requestAnimationFrame(animate);
}
return {
init: () => {
animate();
}
};
})();
var rotateCursor = (function() {
let lastCursorPos = { x: 0, y: 0 };
let angle = 0;
let cursor = document.getElementById("cursor");
function updateCursor() {
const delta = {
x: lastCursorPos.x - cursorPos.x,
y: lastCursorPos.y - cursorPos.y
};
if (Math.abs(delta.x) < 10 && Math.abs(delta.y) < 10) return;
angle = Math.atan2(delta.y, delta.x) * 180 / Math.PI;
// set cursor css
if (moving) {
cursor.style.transform = `translate(${cursorPos.x}px, ${
cursorPos.y
}px) rotate(${angle - 90}deg) `;
} else {
cursor.style.transform = `translate(${cursorPos.x}px, ${cursorPos.y}px)`;
}
lastCursorPos = cursorPos;
}
function render() {
updateCursor();
requestAnimationFrame(render);
}
return {
init: function() {
render();
}
};
})();
var makeStars = (function() {
function Star(x, y, size, opacity) {
this.x = x;
this.y = y;
this.size = size;
this.opacity = opacity;
this.addOpacity = 0.005;
this.update = () => {
if (this.opacity < 0.1) {
this.addOpacity = -this.addOpacity;
}
if (this.opacity > 0.8) {
this.addOpacity = -this.addOpacity;
}
this.opacity -= this.addOpacity;
this.draw();
};
this.draw = () => {
ctx2.beginPath();
ctx2.globalAlpha = this.opacity;
ctx2.fillStyle = "#ffffff";
ctx2.arc(this.x, this.y, this.size, 0, Math.PI * 2, false);
ctx2.fill();
ctx2.closePath();
};
}
var createStars = function() {
stars = [];
for (var i = 1; i <= 150; i++) {
var x = random(0, width);
var y = random(0, height);
var size = random(0.1, 1.5);
var opacity = random(0.1, 0.8);
var s = new Star(x, y, size, opacity);
stars.push(s);
}
};
function animate() {
ctx2.clearRect(0, 0, width, height);
for (var i = 0; i < stars.length; i++) {
stars[i].update();
}
window.requestAnimationFrame(animate);
}
return {
init: () => {
createStars();
animate();
},
createStars: () => {
createStars();
}
};
})();
document.addEventListener("DOMContentLoaded", () => {
rotateCursor.init();
makeParticles.init();
makeStars.init();
});