css画布星空_使⽤HTML5画布制作星空背景
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 ; 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>应该使⽤⽽不是来确定⼤⼩; 仅使⽤样式调整元素⼤⼩会导致缩放问题,因为<canvas>元素具有其⾃⼰的默认⼤⼩,该默认⼤⼩通过使⽤CSS width和height作为其唯⼀的尺⼨信息⽽失真。
And some CSS to fill it with black:
还有⼀些⽤⿊⾊填充CSS:
canvas {
background: #111;
}
To start, we’ll identify the canvas, tell what context we are drawing in, and determine the total number of stars:
⾸先,我们将确定画布,告诉我们正在绘制的上下⽂,并确定星星总数:
var canvas = ElementById("starfield"),
context = Context("2d"),
stars = 200;
To create the stars themselves, we’ll create a simple 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:
结果:
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:
现在,星空看起来像这样:
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)
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 , 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.
如果您熟悉 ,则应该知道任何亮度和100%亮度的东西都会显⽰为⽩⾊。 因此,如果我们将⾊相和饱和度随机化,但保持较⾼的光度,则将获得颜⾊提⽰,但星星将主要为⽩⾊。
Our JavaScript becomes:
我们JavaScript变为:
function getRandom(min, max) {
return Math.floor(Math.random() * (max - min + 1)) + min;
}
var canvas = ElementById("starfield"),
context = Context("2d"),
stars = 500,
colorrange = [0,60,240];
html5颜代码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 , to ensure that it was always at the “back” of subsequent elements.
如所写,星空可以为页⾯提供出⾊的随机背景:您只需要使⽤即可确保它始终位于后续元素的“背⾯”。
css画布星空
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论