import { Scene, Circle, Rectangle, Color, RadialGradient, Star, Particles }
    from "https://unpkg.com/pencil.js/dist/pencil.esm.js";

const scene = new Scene(undefined, {
    fill: new Color(),
});
const { width, height } = scene;
scene.cursorPosition.set(scene.center).subtract(0, height / 4);

const sun = new Circle(scene.center.add(0, height / 2), 100, {
    fill: "orange",
});

const ocean = new Rectangle([0, height / 2], width, height / 2, {
    fill: new RadialGradient(undefined, sun.radius * 3, {
        0: sun.options.fill,
        1: "#28488f",
    }),
});

// Base star shape used by all particles
const base = new Star(undefined, 6, 4, 0.2, {
    fill: "white",
});
const numberOfStars = 150;
// Function that generate individual particle options
const generator = () => ({
    position: scene.getRandomPosition().divide(1, 2),
    scale: Math.random(),
});
// Particles object
const stars = new Particles([0, 0], base, numberOfStars, generator);

scene
    .add(stars, sun, ocean)
    .startLoop()
    .on("draw", () => {
        sun.position.lerp(scene.cursorPosition, 0.05);

        const sunSettingRatio = (sun.position.y - height / 4) / (height / 2);
        scene.options.fill
            .set("#45a8ff")
            .lerp("#150a1b", sunSettingRatio);

        ocean.options.fill.position
            .set(sun.position.x, height / 2 - sun.position.y);

        // Update stars' opacity to sun's setting ratio squared
        stars.options.opacity = sunSettingRatio ** 2;
    }, true);

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.