css画布星空_使用HTML5画布制作星空背景

这篇博客介绍如何使用HTML5的Canvas元素逐步创建一个星空背景。通过算法逐像素生成,从简单的白色像素点开始,改进为绘制随机半径的圆形星星,再通过调整颜色的亮度和饱和度模拟不同颜色的星星,最终实现逼真的星空效果。同时讨论了响应式设计和进一步提升细节的可能性。
摘要由CSDN通过智能技术生成

css画布星空

Because it works on a pixel-by-pixel basis, canvas is perfectly suited to making extremely detailed images algorithmically. A good example is a starfield background; a very simple one can be built based by merely deciding if a canvas random pixel is white or not.

由于canvas是逐像素工作的,因此它非常适合通过算法制作极其详细的图像。 星空背景是一个很好的例子。 可以仅通过确定画布随机像素是否为白色来构建非常简单的像素。

Unlike most other articles on The New Code, the goal of this piece is not to show a complete example, but to improve the code in incremental steps. This is in contrast to the approach of many of my students, who often seek a single, “perfect” solution rather than taking the time to build from something simple (but well-structured) into a more complex, nuanced production.

与大多数其他有关“新代码”的文章不同,本文的目的不是显示完整的示例,而是以渐进的方式改进代码。 这与我许多学生的方法形成鲜明对比,我的学生经常寻求单一的“完美”解决方案,而不是花时间将简单(但结构良好)的东西构建成更复杂,细致的产品。

在一开始的时候 (In The Beginning)

Let’s say we have a 750 × 500 pixel <canvas> element with an id:

假设我们有一个750×500像素的id <canvas>元素:

<canvas id="starfield" width="750" height="500"></canvas>

Unlike almost every other element, <canvas> should be sized using , rather than CSS; sizing the elements with styles alone causes scaling issues, as the <canvas> element has its own default size that is distorted by using CSS width and height as its only dimension information.

与几乎所有其他元素不同, <canvas>应该使用而不是CSS来确定大小; 仅使用样式调整元素大小会导致缩放问题,因为<canvas>元素具有其自己的默认大小,该默认大小通过使用CSS widthheight作为其唯一的尺寸信息而失真。

And some CSS to fill it with black:

还有一些用黑色填充CSS:

canvas {
    background: #111;
}

To start, we’ll identify the canvas, tell JavaScript what context we are drawing in, and determine the total number of stars:

首先,我们将确定画布,告诉JavaScript我们正在绘制的上下文,并确定星星总数:

var canvas = document.getElementById("starfield"),
context = canvas.getContext("2d"),
stars = 200;

To create the stars themselves, we’ll create a simple loop that draws 1 pixel × 1 pixel squares randomly within the limits of the canvas:

为了自己创建星星,我们将创建一个简单的循环 ,在画布的范围内随机绘制1个像素×1个像素的正方形:

for (var i = 0; i < stars; i++) {
    x = Math.random() * canvas.offsetWidth;
    y = Math.random() * canvas.offsetHeight;
   context.fillStyle = "white";
    context.fillRect(x,y,1,1);
}

The result:

结果:

alt
A simple star field, with small square white stars
一个简单的星空,上面有白色的小方形星星

That’s not a bad start, but there are a few problems: the stars are fairly obviously square when viewed closely, all the same brightness, and quite small. Let’s address all of those issues at the same time by drawing circles for the stars; each circle will have a random radius.

这不是一个不好的开始,但是有一些问题:当仔细观察时,星星显然是正方形的,亮度都一样,而且很小。 让我们同时为星星画圆,以解决所有这些问题。 每个圆都有一个随机半径。

for (var i = 0; i < stars; i++) {
    var x = Math.random() * canvas.offsetWidth;
    y = Math.random() * canvas.offsetHeight,
    radius = Math.random() * 1.2;
    context.beginPath();
    context.arc(x, y, radius, 0, 360);
    context.fillStyle = "hsla(200,100%,50%,0.8)";
    context.fill();
}

Somewhat oddly, canvas does not have a fillCirc method; rather, it draws arcs. Drawing a circle is therefore a task of determining the center and radius of the circle, the starting angle (0) and the ending angle (360).

有点奇怪的是,canvas没有fillCirc方法。 相反,它绘制弧线 。 因此,绘制圆是确定圆的中心和半径,起始角度(0)和终止角度(360)的任务。

The starfield now looks like this:

现在,星空看起来像这样:

alt
An improved star field, with small blue circles for stars
改进的星场,带有蓝色小圆圈

That’s better, but all our stars are blue-shifted due to the hsla color. We want a range of color.

更好,但是由于hsla颜色,我们所有的星星都发生了蓝移。 我们想要一个颜色范围

颜色在银河系中的分布 (Distribution of color in the galaxy)

Photograph of the bright blue stars of the Pleiades cluster

The perceived color of a star depends on its mass and temperature, both of which are functions of its age. Young stars in new galaxies gulp in gas, and shine a bright blue; an older galaxy will be darker, with aged stars appearing as red embers. The color distribution of main sequence stars in our galaxy is fairly typical: three-quarters of them are red and 20% yellow or orange, with the remainder scattered between white and blue.

恒星的感知颜色取决于其质量和温度,这两者都是其年龄的函数。 新星系中的年轻恒星吞噬着气体,并发出明亮的蓝色。 年龄较大的星系会更暗,年龄较大的恒星会显示为红色余烬。 我们银河系中主要序列恒星的颜色分布相当典型:四分之三是红色,而20%是黄色或橙色,其余分布在白色和蓝色之间。

Our perception of star color distribution is skewed by the fact that cool red stars are much harder to see against the black background of space. For similar reasons, humans do not see green stars: any star emitting green light will also emit red and blue, making it look white.

我们恒星颜色分布的认识因以下事实而歪曲:在太空黑色背景下,很难看到冷的红色恒星。 出于类似的原因,人类看不到绿色的恒星:任何发出绿光的恒星也将发出红色和蓝色,使其看上去呈白色。

If you’re familiar with HSL color, you should know that anything with a luminosity of 100% will appear white, no matter what the hue and saturation. So if we randomize hue and saturation but keep luminosity fairly high, we’ll get hints of color, but the stars will be predominantly white.

如果您熟悉HSL颜色 ,则应该知道任何亮度和100%亮度的东西都会显示为白色。 因此,如果我们将色相和饱和度随机化,但保持较高的光度,则将获得颜色提示,但星星将主要为白色。

Our JavaScript becomes:

我们JavaScript变为:

function getRandom(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    }           
var canvas = document.getElementById("starfield"),
context = canvas.getContext("2d"),
stars = 500,
colorrange = [0,60,240];
for (var i = 0; i < stars; i++) {
    var x = Math.random() * canvas.offsetWidth;
    y = Math.random() * canvas.offsetHeight,
    radius = Math.random() * 1.2,
    hue = colorrange[getRandom(0,colorrange.length - 1)],
    sat = getRandom(50,100);
    context.beginPath();
    context.arc(x, y, radius, 0, 360);
    context.fillStyle = "hsl(" + hue + ", " + sat + "%, 88%)";
    context.fill();
}

The getRandom function creates a random integer between two numbers (inclusive): with the hue variable, it randomly selects a value of 0, 60, or 240 (avoiding green), and for saturation, a number from 50 to 100.

getRandom函数在两个数字(包括两个数字)之间创建一个随机整数:使用hue变量,它将随机选择一个0、60或240(避免绿色)的值,并为饱和度选择一个50到100的数字。

To quickly make the <canvas> responsive, add a percentage width in CSS:

要快速使<canvas>响应,请在CSS中添加一个百分比宽度:

canvas {
    width: 100%;
    height: auto;
    background: #111;
}

现实的细腻本质 (The Fine-Grained Nature of Reality)

The final result, shown at the top of this article, is pretty good, but does lack a few features:

最终结果显示在本文的顶部,效果不错,但是缺少一些功能:

  • dust obscures a significant portion of the night sky: in our own galaxy, the most visible aspect of this phenomenon is the Great Rift, spanning across the middle of the Milky Way. These “clouds” should be rendered as well; I’ll reserve that for a future article.

    尘埃掩盖了夜空的很大一部分:在我们自己的银河系中,这种现象最明显的方面是大裂谷,横跨银河系的中部。 这些“云”也应该被渲染。 我将在以后的文章中保留它。
  • it would be nice to generate dense clusters of stars, such as nebulae and the central bar of our own Milky Way. Again, I’ll leave that for a more advanced article.

    产生密集的恒星簇(如星云和我们自己的银河系的中心条)会很好。 再次,我将其留给更高级的文章。
  • Finally, it would be good to have the script draw stars appropriate for the current viewport*: when the <canvas> is small, it tends to be overcrowded with 200 stars, while it looks a little large and scattered on larger screens. The <canvas> will be redrawn on viewport resize: that’s just its nature when it’s made responsive in this way - but it could still be improved.

    最后,最好让脚本绘制适合当前视口的星星*: <canvas>较小时,它往往拥挤了200颗星星,而它看上去又大又散在较大的屏幕上。 <canvas>将在视口调整大小时重绘:这就是它以这种方式进行响应时的本质,但是它仍可以改进。

As written, the starfield could make an excellent random background for a page: you’d just have to use absolute positioning, to ensure that it was always at the “back” of subsequent elements.

如所写,星空可以为页面提供出色的随机背景:您只需要使用绝对定位即可确保它始终位于后续元素的“背面”。

翻译自: https://thenewcode.com/81/Make-A-Starfield-Background-with-HTML5-Canvas

css画布星空

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值