p5js/7.幸运转盘.html
2022-12-30 18:50:06 +08:00

204 lines
7.4 KiB
HTML

<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="/css/style.css" />
<title>幸运转盘</title>
<script src="/lib/p5/p5.min.js"></script>
<script src="/lib/p5/addons/p5.sound.min.js"></script>
<script src="/lib/utils.js"></script>
<script src="/lib/particle.js"></script>
<script>
let 转盘;
let 抓住了指针 = false;
let 角度差 = 0;
let particles = [];
function setup() {
createCanvas(600, 600);
angleMode(DEGREES);
imageMode(CENTER);
img = loadImage("/img/transparencyfade.png");
cursor(CROSS);
frameRate(60);
转盘 = new 幸运转盘(width / 2, height / 2, [
"爸爸",
"海洋",
"妈妈",
"鱼儿",
"公公",
"婆婆",
"奶奶",
]);
}
function draw() {
clear();
background(0);
drawGrid();
转盘.update();
转盘.draw();
textInfo("幸运转盘", "2022/12/13");
}
class 幸运转盘 extends p5.Vector {
constructor(x, y, options) {
super(x, y);
this.hand = new 指针(x, y);
this.options = options;
}
update() {
if (抓住了指针) {
this.计算鼠标移动的角度差();
}
this.hand.update();
}
计算鼠标移动的角度差() {
const vp = createVector(pmouseX, pmouseY);
const vc = createVector(mouseX, mouseY);
const v1 = vp.sub(this);
const v2 = vc.sub(this);
const angle = v1.angleBetween(v2);
this.hand.heading = (this.hand.heading + angle + 360) % 360;
this.hand.angleV = angle;
}
draw() {
push();
// 绘制盘面
fill(200);
stroke(128);
strokeWeight(2);
translate(this.x, this.y);
circle(0, 0, 500);
// 绘制选项
const 每一格的角度 = 360 / this.options.length;
rotate(90);
this.options.forEach((option, i) => {
// 绘制分割线
push();
strokeWeight(1);
rotate(每一格的角度 * (i + 1));
line(0, 0, 0, -250);
pop();
// 绘制文字
push();
noStroke();
fill(0);
if (i == Math.floor(this.hand.heading / 每一格的角度)) {
fill("red");
stroke("yellow");
textSize(48);
} else {
textSize(32);
}
rotate(每一格的角度 * (i + 0.5));
translate(0, -150);
rotate(-每一格的角度 * (i + 0.5) - 90);
textAlign(CENTER);
text(option, 0, 0);
pop();
});
pop();
// 绘制指针
this.hand.draw();
}
}
class 指针 extends p5.Vector {
constructor(x, y) {
super(x, y);
this.heading = 360;
this.angleV = 0;
}
update() {
if (!抓住了指针) {
this.heading = (this.heading + this.angleV + 360) % 360;
if (this.angleV != 0) {
let s = this.angleV > 0 ? -1 : 1;
let d = map(this.angleV ** 2, 0, 10000, 0.1, 1);
this.angleV += d * s;
if (abs(this.angleV) < 0.1) this.angleV = 0;
}
}
}
draw() {
push();
fill(255);
stroke(128);
strokeWeight(2);
translate(this.x, this.y);
rotate(this.heading);
beginShape();
vertex(-200, -10);
vertex(-200, 10);
vertex(150, 10);
vertex(150, 20);
vertex(200, 0);
vertex(150, -20);
vertex(150, -10);
endShape(CLOSE);
circle(0, 0, 16);
pop();
let headingVector = createVector(0, 200).setHeading(
this.heading
);
let firePos = this.copy().add(headingVector);
火把(firePos.x, firePos.y);
}
}
function mousePressed() {
抓住了指针 = get(mouseX, mouseY)[0] == 255;
}
function mouseReleased() {
抓住了指针 = false;
}
function 火把(x, y) {
// clear();
// 添加新粒子
for (let i = 0; i < 1; i++) {
const p = new Particle(x, y);
p.velocity = p5.Vector.random2D().mult(random(10, 50));
p.life = 0.5;
particles.push(p);
}
// 更新并绘制所有粒子
push();
tint(255, 128, 64, 100);
for (let i = particles.length - 1; i >= 0; i--) {
const p = particles[i];
noiseDetail(2, 0.5);
let windForce = map(
noise(frameCount / 100),
0,
1,
-1000,
1000
);
p.applyForce(createVector(windForce, 0));
p.applyForce(createVector(0, -1500));
p.move();
if (p.finished) {
particles.splice(i, 1);
} else {
const alpha = map(p.duration, 0, p.life, 255, 0);
const size = map(p.duration, 0, p.life, 32, 64);
tint(alpha, alpha / 3, alpha / 6, alpha);
blendMode(ADD);
image(img, p.position.x, p.position.y, size, size);
}
}
pop();
}
</script>
</head>
<body>
<main></main>
</body>
</html>