update
This commit is contained in:
parent
e6fa24bda3
commit
89746e449b
@ -3,7 +3,7 @@
|
||||
<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="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<title>作品模板</title>
|
||||
<script src="/p5/p5.min.js"></script>
|
||||
|
@ -3,7 +3,7 @@
|
||||
<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="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<script src="/p5/p5.min.js"></script>
|
||||
<script src="/p5/addons/p5.sound.js"></script>
|
||||
|
79
2.太阳公公钟.html
79
2.太阳公公钟.html
@ -3,7 +3,7 @@
|
||||
<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="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<title>太阳公公钟</title>
|
||||
<script src="/p5/p5.min.js"></script>
|
||||
@ -13,95 +13,92 @@
|
||||
const 分钟毫秒数 = 60 * 1000;
|
||||
const 小时毫秒数 = 3600 * 1000;
|
||||
const 半天毫秒数 = 3600 * 12 * 1000;
|
||||
const 一天毫秒数 = 3600 * 24 * 1000;
|
||||
const 时针角度除数 = 半天毫秒数 / 360;
|
||||
const 分针角度除数 = 小时毫秒数 / 360;
|
||||
const 秒针角度除数 = 分钟毫秒数 / 360;
|
||||
const 时针角度除数 = 半天毫秒数 / 360; // 120000
|
||||
const 分针角度除数 = 小时毫秒数 / 360; // 10000
|
||||
const 秒针角度除数 = 分钟毫秒数 / 360; // 1000/6
|
||||
|
||||
function setup() {
|
||||
createCanvas(400, 400);
|
||||
angleMode(DEGREES);
|
||||
frameRate(60);
|
||||
noCursor();
|
||||
}
|
||||
|
||||
function draw() {
|
||||
background("skyblue");
|
||||
let x = width / 2 || mouseX;
|
||||
let y = height / 2 || mouseY;
|
||||
|
||||
push();
|
||||
translate(width / 2, height / 2);
|
||||
|
||||
// 画阳光
|
||||
push();
|
||||
translate(x, y);
|
||||
stroke(255, 255, 0, 128);
|
||||
stroke(255, 255, 0, 64);
|
||||
strokeWeight(4);
|
||||
let distance = 1 + (frameCount % 30);
|
||||
for (let i = 0, n = 36; i < n; i++) {
|
||||
line(0, -50 - distance * 10, 0, -100 - distance * 10);
|
||||
rotate(360 / n);
|
||||
const 阳光数量 = 36;
|
||||
const 阳光飞行距离 = 10 + (frameCount % 40) * 10;
|
||||
for (let i = 0; i < 阳光数量; i++) {
|
||||
line(0, -阳光飞行距离, 0, -阳光飞行距离 - 50);
|
||||
rotate(360 / 阳光数量);
|
||||
}
|
||||
// 画太阳
|
||||
|
||||
// 画太阳轮廓
|
||||
stroke(255, 255, 0, 255);
|
||||
fill("#FFCC00");
|
||||
strokeWeight(8);
|
||||
circle(0, 0, 100);
|
||||
fill("#FFCC00");
|
||||
circle(0, 0, 200);
|
||||
|
||||
// 画太阳表情
|
||||
noFill();
|
||||
arc(-20, 0, 20, 20, -135, -45);
|
||||
arc(20, 0, 20, 20, -135, -45);
|
||||
arc(0, 10, 40, 40, 45, 135);
|
||||
arc(-40, 0, 40, 40, -135, -45);
|
||||
arc(40, 0, 40, 40, -135, -45);
|
||||
arc(0, 20, 80, 80, 45, 135);
|
||||
|
||||
// 画时刻度
|
||||
strokeWeight(2);
|
||||
strokeWeight(4);
|
||||
for (let i = 0, n = 12; i < n; i++) {
|
||||
line(0, 40, 0, 50);
|
||||
line(0, 85, 0, 100);
|
||||
rotate(360 / n);
|
||||
}
|
||||
|
||||
// 画分刻度
|
||||
strokeWeight(1);
|
||||
for (let i = 0, n = 60; i < n; i++) {
|
||||
line(0, 45, 0, 50);
|
||||
line(0, 90, 0, 100);
|
||||
rotate(360 / n);
|
||||
}
|
||||
pop();
|
||||
|
||||
const 当前时间 = Date.now() + 小时毫秒数 * 8;
|
||||
const angleHour = (当前时间 % 半天毫秒数) / 时针角度除数;
|
||||
const angleMinute = (当前时间 % 小时毫秒数) / 分针角度除数;
|
||||
const angleSecond = (当前时间 % 分钟毫秒数) / 秒针角度除数;
|
||||
|
||||
push();
|
||||
translate(x, y);
|
||||
// 画时针
|
||||
push();
|
||||
stroke(0);
|
||||
strokeWeight(3);
|
||||
strokeWeight(4);
|
||||
rotate(angleHour);
|
||||
line(0, 5, 0, -30);
|
||||
line(0, 10, 0, -60);
|
||||
pop();
|
||||
|
||||
// 画分针
|
||||
push();
|
||||
stroke(0);
|
||||
strokeWeight(3);
|
||||
strokeWeight(4);
|
||||
rotate(angleMinute);
|
||||
line(0, 5, 0, -40);
|
||||
line(0, 10, 0, -80);
|
||||
pop();
|
||||
|
||||
// 画秒针
|
||||
push();
|
||||
strokeWeight(2);
|
||||
stroke(255, 0, 0);
|
||||
strokeWeight(1);
|
||||
rotate(angleSecond);
|
||||
line(0, 5, 0, -45);
|
||||
circle(0, 0, 2);
|
||||
pop();
|
||||
line(0, 10, 0, -85);
|
||||
fill(0);
|
||||
circle(0, 0, 5);
|
||||
pop();
|
||||
|
||||
translate(0, 0);
|
||||
noStroke();
|
||||
fill(0);
|
||||
text("作品:太阳公公钟", 30, height - 70);
|
||||
text("作者:赵海洋爸爸", 30, height - 50);
|
||||
text("日期:2022/12/11", 30, height - 30);
|
||||
pop();
|
||||
|
||||
textInfo("太阳公公钟", "2022-12-11");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
92
3.火把.html
92
3.火把.html
@ -3,7 +3,7 @@
|
||||
<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="shortcut icon" href="/favicon.ico" type="image/x-icon" />
|
||||
<link rel="stylesheet" href="/css/style.css" />
|
||||
<title>火把</title>
|
||||
<script src="/p5/p5.min.js"></script>
|
||||
@ -11,57 +11,61 @@
|
||||
<script src="/lib/utils.js"></script>
|
||||
<script src="/lib/particle.js"></script>
|
||||
<script>
|
||||
let x, y;
|
||||
let 粒子贴图;
|
||||
let isDragging = false;
|
||||
let particles = [];
|
||||
let img;
|
||||
|
||||
function setup() {
|
||||
createCanvas(600, 600);
|
||||
angleMode(DEGREES);
|
||||
imageMode(CENTER);
|
||||
frameRate(60);
|
||||
noStroke();
|
||||
noCursor();
|
||||
img = loadImage("/img/transparencyfade.png");
|
||||
cursor(HAND);
|
||||
x = width / 2;
|
||||
y = height - 100;
|
||||
粒子贴图 = loadImage("/img/transparencyfade.png");
|
||||
}
|
||||
|
||||
function draw() {
|
||||
火把();
|
||||
// 落珠();
|
||||
}
|
||||
|
||||
function 火把() {
|
||||
clear();
|
||||
background(0);
|
||||
drawGrid();
|
||||
const x = mouseIsPressed ? mouseX : 300;
|
||||
const y = mouseIsPressed ? mouseY : 500;
|
||||
drawGrid(32);
|
||||
|
||||
if (
|
||||
mouseIsPressed &&
|
||||
!isDragging &&
|
||||
isMouseIn(x - 5, y, 10, 80)
|
||||
) {
|
||||
isDragging = true;
|
||||
} else if (!mouseIsPressed) {
|
||||
isDragging = false;
|
||||
}
|
||||
|
||||
if (isDragging) (x += movedX), (y += movedY);
|
||||
// 添加新粒子
|
||||
for (let i = 0; i < 1; i++) {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
const p = new Particle(x, y);
|
||||
p.velocity = p5.Vector.random2D().mult(random(10, 50));
|
||||
p.life = 0.5;
|
||||
particles.push(p);
|
||||
}
|
||||
|
||||
// 绘制火把
|
||||
fill("lightgray");
|
||||
rect(x - 5, y, 10, 80);
|
||||
fill("gray");
|
||||
rect(x - 7, y, 14, 20);
|
||||
|
||||
// 更新并绘制所有粒子
|
||||
push();
|
||||
tint(255, 128, 64, 100);
|
||||
image(img, x, y, 512, 512);
|
||||
blendMode(ADD);
|
||||
tint(255, 128, 64, 64);
|
||||
image(粒子贴图, x, y - 20, 512, 512);
|
||||
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));
|
||||
let wind = map(noise(frameCount / 60), 0, 1, -1000, 1000);
|
||||
p.applyForce(createVector(wind, 0));
|
||||
p.applyForce(createVector(0, -1500));
|
||||
p.move();
|
||||
if (p.finished) {
|
||||
@ -70,46 +74,20 @@
|
||||
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);
|
||||
image(粒子贴图, p.position.x, p.position.y, size, size);
|
||||
// fill(255, 128, 64, alpha);
|
||||
// circle(p.position.x, p.position.y, size, size);
|
||||
}
|
||||
}
|
||||
pop();
|
||||
|
||||
textInfo("火把", "2022/12/11");
|
||||
}
|
||||
|
||||
function 落珠() {
|
||||
background(0);
|
||||
drawGrid();
|
||||
const x = mouseIsPressed ? mouseX : 300;
|
||||
const y = mouseIsPressed ? mouseY : 50;
|
||||
// 添加新粒子
|
||||
if (particles.length < 1) {
|
||||
for (let i = 0; i < 1; i++) {
|
||||
const p = new Particle(x, y);
|
||||
p.velocity.x = random(-50, 50);
|
||||
p.life = 5;
|
||||
particles.push(p);
|
||||
}
|
||||
}
|
||||
push();
|
||||
for (let i = particles.length - 1; i >= 0; i--) {
|
||||
const p = particles[i];
|
||||
p.applyForce(createVector(0, 100));
|
||||
p.move(true);
|
||||
if (p.finished) {
|
||||
particles.splice(i, 1);
|
||||
} else {
|
||||
const alpha = map(p.duration, 0, p.life, 255, 0);
|
||||
stroke(255, alpha);
|
||||
fill(128, alpha);
|
||||
circle(p.position.x, p.position.y, 4);
|
||||
}
|
||||
}
|
||||
pop();
|
||||
textInfo("落珠", "2022/12/12");
|
||||
function isMouseIn(x, y, w, h) {
|
||||
let mx = mouseX - x;
|
||||
let my = mouseY - y;
|
||||
return mx > 0 && mx < x + w && my > 0 && my < y + h;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
69
4.柏林噪声.html
69
4.柏林噪声.html
@ -13,70 +13,55 @@
|
||||
let x,
|
||||
y,
|
||||
time = 0,
|
||||
size = 10,
|
||||
粒子贴图,
|
||||
path = [];
|
||||
|
||||
function setup() {
|
||||
createCanvas(600, 600);
|
||||
noiseDetail(2, 0.5);
|
||||
angleMode(DEGREES);
|
||||
imageMode(CENTER);
|
||||
colorMode(HSB);
|
||||
cursor(CROSS);
|
||||
frameRate(60);
|
||||
x = width / 2;
|
||||
y = height / 2;
|
||||
粒子贴图 = loadImage("/img/transparencyfade.png");
|
||||
}
|
||||
|
||||
function draw() {
|
||||
一维柏林噪声();
|
||||
// 二维柏林噪声();
|
||||
}
|
||||
|
||||
function 二维柏林噪声() {
|
||||
time += deltaTime / 2000;
|
||||
background(0);
|
||||
drawGrid(32);
|
||||
noStroke();
|
||||
time += deltaTime / 1000;
|
||||
for (let j = 0; j < height; j += size) {
|
||||
for (let i = 0; i < width; i += size) {
|
||||
const r = map(
|
||||
noise(i / 100 + time, j / 100),
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
10
|
||||
);
|
||||
circle(i, j, r);
|
||||
}
|
||||
}
|
||||
textInfo("二维柏林噪声", "2022/12/12");
|
||||
二维柏林噪声();
|
||||
一维柏林噪声();
|
||||
}
|
||||
|
||||
function 一维柏林噪声() {
|
||||
background(0);
|
||||
drawGrid(32);
|
||||
time += deltaTime / 1000;
|
||||
y = map(noise(time), 0, 1, 0, width);
|
||||
h = map(y, 0, height, 0, 255);
|
||||
path.push(h);
|
||||
path = path.slice(-height);
|
||||
y = map(noise(time), 0, 1, 0, height);
|
||||
path.push(y);
|
||||
path = path.slice(-width);
|
||||
push();
|
||||
noFill();
|
||||
stroke(255);
|
||||
strokeWeight(2);
|
||||
beginShape();
|
||||
path.forEach((h, i) => vertex(i, h));
|
||||
endShape();
|
||||
strokeWeight(8);
|
||||
path.forEach((h, i) => {
|
||||
strokeWeight(4);
|
||||
path.forEach((y, i) => {
|
||||
let h = map(y, 0, height, 0, 255);
|
||||
stroke(h, 255, 255, 1);
|
||||
point(i, height / 2);
|
||||
fill(h, 255, 255, 1);
|
||||
line(i, y, i + 1, path[i + 1]);
|
||||
});
|
||||
noStroke();
|
||||
fill(h, 255, 255, 1);
|
||||
circle(x, y, 16);
|
||||
circle(width, y, 8);
|
||||
pop();
|
||||
textInfo("一维柏林噪声", "2022/12/12");
|
||||
textInfo("柏林噪声", "2022/12/12");
|
||||
}
|
||||
|
||||
function 二维柏林噪声() {
|
||||
noStroke();
|
||||
for (let j = 0; j < height; j += 10) {
|
||||
for (let i = 0; i < width; i += 10) {
|
||||
const v = noise(i / 100 + time, j / 100);
|
||||
const d = map(v, 0, 1, 0, 10) * 1.5;
|
||||
image(粒子贴图, i, j, d, d);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
33
5.醉汉模拟.html
33
5.醉汉模拟.html
@ -14,40 +14,43 @@
|
||||
function setup() {
|
||||
createCanvas(600, 600);
|
||||
angleMode(DEGREES);
|
||||
blendMode(ADD);
|
||||
cursor(CROSS);
|
||||
frameRate(60);
|
||||
stroke(255, 32);
|
||||
walker = new Walker(width / 2, height / 2);
|
||||
stroke(255, 128, 192, 1);
|
||||
strokeWeight(4);
|
||||
background(0);
|
||||
drawGrid(32);
|
||||
walker = new Walker(width / 2, height / 2);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
// background(255);
|
||||
strokeWeight(1);
|
||||
strokeWeight(4);
|
||||
for (let i = 0; i < 10; i++) {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
walker.move();
|
||||
walker.show();
|
||||
}
|
||||
textInfo("醉汉模拟", "2022-12-10");
|
||||
}
|
||||
|
||||
class Walker {
|
||||
class Walker extends p5.Vector {
|
||||
constructor(x, y) {
|
||||
this.pos = createVector(x, y);
|
||||
this.count = 0;
|
||||
super(x, y);
|
||||
}
|
||||
move() {
|
||||
this.count++;
|
||||
let step = p5.Vector.random2D().mult(2);
|
||||
this.pos.add(step);
|
||||
if (this.count++ > 10000) {
|
||||
this.pos = createVector(width / 2, height / 2);
|
||||
this.count = 0;
|
||||
this.add(step);
|
||||
if (
|
||||
this.x < 0 ||
|
||||
this.x > width ||
|
||||
this.y < 0 ||
|
||||
this.y > height
|
||||
) {
|
||||
this.x = width / 2;
|
||||
this.y = height / 2;
|
||||
}
|
||||
}
|
||||
show() {
|
||||
point(this.pos.x, this.pos.y);
|
||||
point(this.x, this.y);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
43
8.小车的运动.html
43
8.小车的运动.html
@ -11,10 +11,10 @@
|
||||
<script src="/lib/utils.js"></script>
|
||||
<script src="/lib/vehicle.js"></script>
|
||||
<script>
|
||||
let time = 0;
|
||||
let vehicle1;
|
||||
let vehicle2;
|
||||
let path;
|
||||
let time = 0;
|
||||
|
||||
function setup() {
|
||||
createCanvas(600, 600);
|
||||
@ -23,62 +23,54 @@
|
||||
vehicle1 = new Vehicle(300, 300, "#CCCCCC");
|
||||
vehicle1.velocity = createVector(6, 0);
|
||||
vehicle2 = new Vehicle(300, 300, "#CC3333");
|
||||
vehicle2.velocity = randomVector(6);
|
||||
vehicle2.velocity = randomVector(8);
|
||||
vehicle2.maxVelocity = 8;
|
||||
path = new Path(0, 300, 600, 300, 20);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
background(0);
|
||||
drawGrid(32);
|
||||
let n = Math.floor(frameCount / 300) % 6;
|
||||
[追逐鼠标, 逃避鼠标, 小车追逐, 小车巡游, 小车巡线, 道路追逐][
|
||||
n
|
||||
]();
|
||||
let b = [
|
||||
"追逐鼠标",
|
||||
"逃避鼠标",
|
||||
"小车追逐",
|
||||
"小车巡游",
|
||||
"小车巡线",
|
||||
"道路追逐",
|
||||
][n];
|
||||
textInfo(`小车的运动 - ${b}`, "2022-12-12");
|
||||
playdemos([追逐鼠标, 小车追逐, 小车巡游, 小车巡线], 10);
|
||||
}
|
||||
|
||||
function 追逐鼠标() {
|
||||
vehicle1.seek(createVector(mouseX, mouseY));
|
||||
vehicle1.move();
|
||||
vehicle1.turn();
|
||||
vehicle1.drawPath();
|
||||
vehicle1.drawPath(128);
|
||||
vehicle1.show();
|
||||
textInfo("小车的运动 - 追逐鼠标", "2022-12-12");
|
||||
}
|
||||
|
||||
function 逃避鼠标() {
|
||||
vehicle1.flee(createVector(mouseX, mouseY));
|
||||
vehicle1.move();
|
||||
vehicle1.turn();
|
||||
vehicle1.drawPath();
|
||||
vehicle1.drawPath(128);
|
||||
vehicle1.show();
|
||||
textInfo("小车的运动 - 逃避鼠标", "2022-12-12");
|
||||
}
|
||||
|
||||
function 小车追逐() {
|
||||
vehicle1.seek(vehicle2.position, 20);
|
||||
vehicle2.move();
|
||||
vehicle1.move();
|
||||
if (vehicle2.turn())
|
||||
vehicle2.velocity = randomVector(random(2, 5));
|
||||
if (vehicle2.turn()) vehicle2.velocity = randomVector(8);
|
||||
vehicle1.turn();
|
||||
vehicle1.drawPath();
|
||||
vehicle2.show("point");
|
||||
vehicle1.drawPath(128);
|
||||
vehicle2.show();
|
||||
vehicle1.show();
|
||||
textInfo("小车的运动 - 小车追逐", "2022-12-12");
|
||||
}
|
||||
|
||||
function 小车巡游() {
|
||||
vehicle1.wander();
|
||||
vehicle1.move();
|
||||
vehicle1.turn();
|
||||
vehicle1.drawPath();
|
||||
vehicle1.drawPath(128);
|
||||
vehicle1.show();
|
||||
textInfo("小车的运动 - 小车巡游", "2022-12-12");
|
||||
}
|
||||
|
||||
function 小车巡线() {
|
||||
@ -87,8 +79,9 @@
|
||||
vehicle1.move();
|
||||
vehicle1.turn();
|
||||
path.show();
|
||||
vehicle1.drawPath();
|
||||
vehicle1.drawPath(128);
|
||||
vehicle1.show();
|
||||
textInfo("小车的运动 - 小车巡线", "2022-12-12");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -105,8 +98,8 @@
|
||||
vehicle2.turn();
|
||||
vehicle1.turn();
|
||||
path.show();
|
||||
vehicle2.drawPath();
|
||||
vehicle1.drawPath();
|
||||
vehicle2.drawPath(128);
|
||||
vehicle1.drawPath(128);
|
||||
vehicle2.show();
|
||||
vehicle1.show();
|
||||
}
|
||||
|
@ -4,6 +4,11 @@ function loadJavaScript(path) {
|
||||
document.head.appendChild(script);
|
||||
}
|
||||
|
||||
function playdemos(list, delay = 10) {
|
||||
let n = Math.floor((frameCount / (delay * 60)) % list.length);
|
||||
list[n]();
|
||||
}
|
||||
|
||||
function drawGrid(fade = 64) {
|
||||
push();
|
||||
colorMode(RGB);
|
||||
|
@ -63,7 +63,7 @@ class Vehicle {
|
||||
target.add(x, y);
|
||||
|
||||
noStroke();
|
||||
fill("#F063A4");
|
||||
fill("#00FF00");
|
||||
circle(target.x, target.y, 5);
|
||||
|
||||
const steering = target.sub(this.position);
|
||||
@ -162,8 +162,8 @@ class Vehicle {
|
||||
push();
|
||||
noFill();
|
||||
stroke(255, 64);
|
||||
strokeWeight(1);
|
||||
if (this.path.length >= length) this.path.shift();
|
||||
strokeWeight(2);
|
||||
this.path = this.path.slice(-length);
|
||||
beginShape();
|
||||
this.path.forEach((v) => {
|
||||
if (!v) {
|
||||
@ -184,7 +184,7 @@ class Vehicle {
|
||||
stroke(this.color);
|
||||
fill(this.color);
|
||||
if (mode == "point") circle(0, 0, 5);
|
||||
else triangle(0, 0, -10, 2.5, -10, -2.5);
|
||||
else triangle(0, 0, -20, 5, -20, -5);
|
||||
pop();
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user