204 lines
7.4 KiB
HTML
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>
|