xxxxxxxxxx
121
let pg;
function setup() {
createCanvas(800, 800);
pg = createGraphics(width, height);
pg.fill('#222831');
pg.noStroke();
}
function draw() {
background(220);
const ast = new Astroid(100);
pg.push();
pg.translate(pg.width/2,pg.height/2);
const t = map(frameCount/10, 0, 120, 0, 1);
const easing_time = map(easeInOutBack(t), -0, 1, 0, 120);
ast.draw(pg,easing_time);
pg.pop();
image(pg,0,0);
}
class Astroid {
/**
* アステロイドクラスのコンストラクタ
* @constructor
* @param {number} p - p5.jsのインスタンス
* @param {number} r - 円の半径
*/
constructor(r) {
this.r = r;
this.a = 3;
this.points = [];
this.init();
}
/**
* アステロイドを描画する
*/
init() {
for (let i = 0; i < 120; i++) {
const angle = radians(map(i, 0, 120, 0, 360));
const x = (this.r / 4) * this.a * pow(cos(angle), 3);
const y = (this.r / 4) * this.a * pow(sin(angle), 3);
this.points.push(createVector(x, y));
}
}
draw(pg,r) {
const points = this.points;
pg.push();
pg.beginShape();
pg.strokeWeight(3);
//pg.translate(pg.width / 2, pg.height / 2);
for (let i = 0; i < points.length; i++) {
const xy = afin_scale(points[i].x, points[i].y,0,0,r,r);
pg.vertex(xy[0], xy[1]);
}
pg.endShape(CLOSE);
pg.pop();
}
}
//行列計算
const afin = (a, b) => {
let x;
let y;
for (let k = 0; k < 3; k++) {
let a0 = a[k][0] * b[0];
let a1 = a[k][1] * b[1];
let a2 = a[k][2] * b[2];
if (k == 0) {
x = a0 + a1 + a2;
} else if (k == 1) {
y = a0 + a1 + a2;
}
}
return [x, y];
};
//平行移動
const afin_translate = (x, y, tx, ty) => {
let a = [
[1, 0, tx],
[0, 1, ty],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
};
//回転
const afin_rotate = (shita, x, y, tx, ty) => {
let a = [
[Math.cos(shita), -Math.sin(shita), tx - tx * Math.cos(shita) + ty * Math.sin(shita)],
[Math.sin(shita), Math.cos(shita), ty - tx * Math.sin(shita) - ty * Math.cos(shita)],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
};
//拡大縮小
const afin_scale = (x, y, tx, ty, sx, sy) =>{
let a = [
[sx, 0, tx - tx * sx],
[0, sy, ty - ty * sy],
[0, 0, 1],
];
let b = [x, y, 1];
return afin(a, b);
};
// 参考:https://github.com/AndrewRayCode/easing-utils/blob/master/src/easing.js
function easeInOutBack(x) {
const c1 = 1.70158;
const c2 = c1 * 1.525;
return x < 0.5
? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
: (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
}