javascript - 如何使用函数在画布中创建五个尖角星?
问题描述
我怎样才能在画布上创建这 3 颗星使用
function filledStar(x,y,a){code}
filledStar(40,50,75);
filledStar(130,120,100);
filledStar(250,220,150);
应该显示:
谢谢
解决方案
对形状中的点数进行循环。在一个 5 尖星的情况下是 10 点,因为你有外部点来制造尖峰,而内部点又回到形状中。
在循环内,您可以找到每个连续点(x,y 坐标)以绘制一条线,例如使用ctx.lineTo(x, y);
.
为此,我将使用如下所示的正弦和余弦:
const x = xOffset+Math.sin(angle)*radius;
const y = yOffset+Math.cos(angle)*radius;
您只需要提供偏移量、角度和半径,它就会为您提供 x、y 坐标。
从星中每个点的循环开始:
for(let i = 0; i < 10; i ++){ ... }
并使用正弦/余弦代码获取点的 x,y 坐标,因此您可以使用ctx.lineTo(x,y)
.
正弦和余弦是以弧度为单位的函数。0 and 2pi
那是或之间的角度-pi/2 to +pi/2
。
为了获得这些函数可以理解的围绕恒星中心的角度,您需要将 i 归一化为 0 和 1 之间而不是 0 和 10,因此您将其除以 10。然后将其乘以 2pi 以获得介于0 和 2pi。现在,这会为循环的每次迭代提供一个角度,从而形成一个完整的圆。
接下来,您要获取半径,它只是您提供的用于给出星大小的像素距离值。但是,内部点需要小于最大半径,以便它实际上产生尖峰。为此,您可以使用模运算符来确定您是否处于循环中的奇数或偶数迭代中。例如i%2
。使用此值更改将要创建点的半径。
const canv = document.getElementById('c');
const ctx = canv.getContext('2d');
const w = window.innerWidth;
const h = window.innerHeight
canv.width = w;
canv.height = h;
ctx.clearRect(0,0,w,h);
//offset x,y, size, spokes, rotation 0 to 1.
function star(ox, oy, s = 10, n = 5, r = 0.25){
ctx.beginPath();
for(let i=0;i<n*2;i++){
let rotation = Math.PI*2*r;
let angle = (i/(n*2))*Math.PI*2+rotation;
let dist = s*(i%2)+s;
let x = ox+Math.cos(angle)*dist;
let y = oy+Math.sin(angle)*dist;
if(i === 0) {
ctx.moveTo(x, y);
continue; //skip
}
ctx.lineTo(x, y);
}
ctx.closePath();
}
ctx.fillStyle = 'magenta';
star(w/2, h/2, 10, 4, 0.125);
ctx.fill();
ctx.fillStyle = 'red';
star(w*0.2, h*0.2, 5, 5);
ctx.fill();
ctx.fillStyle = 'orange';
star(w*0.33, h*0.33, 20, 5);
ctx.fill();
ctx.fillStyle = 'yellow';
star(w*0.66, h*0.25, 30, 6);
ctx.fill();
ctx.fillStyle = 'green';
star(w*0.2, h*0.75, 40, 7);
ctx.fill();
ctx.fillStyle = 'cyan';
star(w*0.82, h*0.8, 50, 8, 1/16);
ctx.fill();
canvas {
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
overflow: hidden;
background-color: black;
}
<canvas id="c"></canvas>
推荐阅读
- uwp - 如何在 HockeyApp 上将电子邮件附加到崩溃日志
- javascript - Javascript Object.create:设置数据时内存会发生什么?
- java - Confluent Cloud 上的 Kafka 流:值为“600000”的“segment.ms”超出内部重新分区主题的最小限制 14400000
- google-api - 通过谷歌开发者控制台项目ID找出使用的电子邮件帐户
- arrays - 在scala中查找给定数组的最小值和最大值
- postgresql - 如何在非英语语言中使用 GraphQL 枚举?后记
- bash - 如何找到 bash 文件的位置?
- .net - PowerShell 中的进程、实例和运行空间
- jelastic - 无法登录 Jelastic intellij 插件
- javascript - 将数组的值从一个函数实例化为jquery中的另一个函数