314 lines
6.7 KiB
JavaScript
314 lines
6.7 KiB
JavaScript
import {Ease} from 'https://assets.codepen.io/194946/ease.js';
|
|
import {Utils} from 'https://assets.codepen.io/194946/utilities.js';
|
|
import {Vector} from 'https://assets.codepen.io/194946/vector.js';
|
|
import {Points} from 'https://assets.codepen.io/194946/points.js';
|
|
import {Grid} from 'https://assets.codepen.io/194946/grids.js';
|
|
|
|
let gui, canvas, c, width, height, frameSize, id,
|
|
ease, shapes, scale, size, number, maxDist, vector, points, newPoints;
|
|
|
|
const setupGui = () => {
|
|
gui = new dat.GUI();
|
|
|
|
gui.params = {
|
|
tScale: 0.00002,
|
|
ease: 'easeInOutSine',
|
|
number: 3,
|
|
scale: 35,
|
|
frame: false,
|
|
start: () => start(),
|
|
stop: () => stop()
|
|
};
|
|
|
|
gui.ctrls = {
|
|
tScale: gui.add(gui.params, 'tScale', 0.1, 0.005, 0.0005),
|
|
ease: gui.add(gui.params, 'ease', Ease.returnEaseType())
|
|
.onChange(() => initialize()),
|
|
number: gui.add(gui.params, 'number', 1, 30, 1)
|
|
.onChange(() => initialize()),
|
|
scale: gui.add(gui.params, 'scale', 1, 300, 1)
|
|
.onChange(() => initialize()),
|
|
frame: gui.add(gui.params, 'frame', false),
|
|
start: gui.add(gui.params, 'start'),
|
|
stop: gui.add(gui.params, 'stop')
|
|
};
|
|
|
|
gui.close();
|
|
};
|
|
|
|
const initialize = () => {
|
|
if (id) {
|
|
cancelAnimationFrame(id);
|
|
}
|
|
|
|
vector = new Vector();
|
|
ease = Ease.returnEaseFunc(gui.params.ease);
|
|
|
|
width = canvas.width = window.innerWidth;
|
|
height = canvas.height = window.innerHeight;
|
|
frameSize = Math.min(width * 1, height *1);
|
|
|
|
scale = gui.params.scale;
|
|
number = gui.params.number;
|
|
|
|
points = Points.rose(vector, 560, 15, 6);
|
|
|
|
// choise shape size
|
|
size = Math.floor(scale * Math.sqrt(2) / 1.2);
|
|
//size = Math.pow(scale / 2,1.0925); // square
|
|
shapes = Grid.square(vector, number, scale);
|
|
/*
|
|
size = gui.params.scale;
|
|
|
|
const tmp = {
|
|
v: vector.create(0, 0),
|
|
d: 1
|
|
};
|
|
|
|
shapes = [tmp, tmp, tmp];
|
|
*/
|
|
maxDist = Grid.maxDist(shapes);
|
|
|
|
draw(1);
|
|
};
|
|
|
|
const drawShape = (points, x, y, size) => {
|
|
c.save();
|
|
|
|
c.beginPath();
|
|
for (let i = 0; i < points.length; i++) {
|
|
if (i === -1) {
|
|
c.moveTo(points[i].getX() * size * x, points[i].getY() * size * y);
|
|
} else {
|
|
c.lineTo(points[i].getX() * size*1.5* x, points[i].getY() * size * y);
|
|
}
|
|
}
|
|
c.closePath();
|
|
//c.fill();
|
|
c.stroke();
|
|
|
|
c.restore();
|
|
};
|
|
|
|
const drawPoints = (points, x, y, size, pointSize) => {
|
|
c.save();
|
|
|
|
for (let i = 0; i < points.length; i++) {
|
|
const nx = points[i].getX() * size + x;
|
|
const ny = points[i].getY() * size + y;
|
|
|
|
c.beginPath();
|
|
c.arc(nx, ny, pointSize, 0, Math.PI * .12, false);
|
|
c.fill();
|
|
c.stroke();
|
|
}
|
|
c.globalCompositeOperation = 'color';
|
|
c.restore();
|
|
};
|
|
|
|
const drawTrailLine = (t, points, size) => {
|
|
const index = Math.floor(Utils.map(t, 0, 1, 0, points.length - 1));
|
|
const endex = Math.ceil(Utils.map(t, 0, 1, index + 1, points.length - 1));
|
|
|
|
const color = `hsla(${360 * t*.82}, 80%, 60%,0.5)`;
|
|
|
|
c.strokeStyle = color;
|
|
c.shadowColor = color;
|
|
c.shadowBlur = 20;
|
|
|
|
c.beginPath();
|
|
c.moveTo(points[index].getX() * size, points[index].getY() * size);
|
|
for (let i = index; i < endex; i++) {
|
|
const p = points[i];
|
|
|
|
c.lineTo(p.getX() * size, p.getY() * size);
|
|
}
|
|
c.stroke();
|
|
c.globalCompositeOperation = 'color-burn';
|
|
};
|
|
|
|
const getNewPoints = (t, pointA, pointB) => {
|
|
const tmp = new Array();
|
|
|
|
for (let i = 0; i < rose.length; i++) {
|
|
let x, y;
|
|
|
|
if (t < 1.5) {
|
|
x = Utils.map(t, 0.5, 0.5, pointA[i].getX(), pointB[i].getX());
|
|
y = Utils.map(t, 0, 0.5, pointA[i].getY(), pointB[i].getY());
|
|
} else {
|
|
x = Utils.map(t, 0.5, 10, pointB[i].getX(), pointA[i].getX());
|
|
y = Utils.map(t, 0.5, 10, pointB[i].getY(), pointA[i].getY());
|
|
}
|
|
|
|
const v = vector.create(x, y);
|
|
|
|
tmp.push(v);
|
|
}
|
|
|
|
return tmp;
|
|
};
|
|
|
|
const draw = (t) => {
|
|
t *= gui.params.tScale;
|
|
|
|
c.save();
|
|
|
|
c.fillStyle = 'hsla(296, 100%, 50%, 0.08)';
|
|
c.fillRect(0, 0, width, height);
|
|
//c.clearRect(0, 0, width, height);
|
|
|
|
if (gui.params.frame) addFrame();
|
|
|
|
c.translate(width / 2, height / 2);
|
|
|
|
c.lineWidth = 1;
|
|
c.lineCap = 'round';
|
|
c.globalCompositeOperation = 'color';
|
|
|
|
for (let i = 0; i < shapes.length; i++) {
|
|
const s = shapes[i];
|
|
const x = s.v.getX();
|
|
const y = s.v.getY();
|
|
|
|
let scaledT = (t + s.d / maxDist / Math.PI * 12) % 95;
|
|
//let scaledT = t % 1;
|
|
scaledT = ease(Math.abs(scaledT));
|
|
|
|
c.save();
|
|
|
|
c.translate(x, y);
|
|
if (scaledT < 0.05) {
|
|
c.scale(Utils.map(scaledT, 0, 0.0085, .1, .5), Utils.map(scaledT, 0, 0.05, 1, 1.5));
|
|
} else {
|
|
c.scale(Utils.map(scaledT, 0.5, 1, 1.5, 1), Utils.map(scaledT, 0.5, 1, 1.5, 1));
|
|
}
|
|
|
|
|
|
|
|
c.translate(x, y);
|
|
c.rotate(Math.PI - 0.4);
|
|
|
|
//newPoints = getNewPoints(scaledT, rose, lissajous);
|
|
|
|
drawTrailLine(scaledT, points, size);
|
|
|
|
//drawShape(points, x, y, size, 1);
|
|
|
|
c.restore();
|
|
}
|
|
|
|
c.restore();
|
|
|
|
id = requestAnimationFrame(draw);
|
|
};
|
|
|
|
const addFrame = () => {
|
|
c.rect(
|
|
width / 2 - frameSize / 2,
|
|
height / 2 - frameSize / 2,
|
|
frameSize,
|
|
frameSize
|
|
);
|
|
c.clip();
|
|
};
|
|
|
|
const setupCanvas = () => {
|
|
canvas = document.createElement('canvas');
|
|
document.getElementsByTagName('body')[0].appendChild(canvas);
|
|
c = canvas.getContext('2d');
|
|
};
|
|
|
|
const start = () => {
|
|
initialize();
|
|
};
|
|
|
|
const stop = () => {
|
|
if (id) {
|
|
cancelAnimationFrame(id);
|
|
id = null;
|
|
}
|
|
};
|
|
|
|
(() => {
|
|
window.addEventListener('DOMContentLoaded', () => {
|
|
console.clear();
|
|
|
|
setupGui();
|
|
setupCanvas();
|
|
|
|
initialize();
|
|
});
|
|
|
|
window.addEventListener('resize', () => {
|
|
initialize();
|
|
});
|
|
})();
|
|
|
|
|
|
|
|
|
|
//////
|
|
|
|
|
|
var s = Sketch.create({autoclear: false});
|
|
var particles = [];
|
|
var max = 100;
|
|
var clearColor = "hsla(34,100%,50%,0.1)";
|
|
var hue = 0;
|
|
|
|
function P(){}
|
|
|
|
P.prototype = {
|
|
constructor: P,
|
|
init: function(){
|
|
this.r = random(100) + 200;
|
|
this.x = s.width/2;
|
|
this.y = s.height/2;
|
|
this.vx = random(-5, 5);
|
|
this.vy = random(-5, 5);
|
|
this.color = "hsla("+hue+", 100%, 50%, .2)";
|
|
this.life = 0;
|
|
this.maxLife = random(100);
|
|
},
|
|
draw: function(){
|
|
s.strokeStyle = this.color;
|
|
s.beginPath();
|
|
s.globalCompositeOperation = "xor";
|
|
s.arc(this.x, this.y, this.r, 0, TWO_PI);
|
|
s.stroke();
|
|
this.update();
|
|
},
|
|
update: function(){
|
|
this.x += this.vx;
|
|
this.y += this.vy;
|
|
this.life++;
|
|
if(this.life >= this.maxLife || this.r <= .0000002){
|
|
this.init();
|
|
}
|
|
}
|
|
};
|
|
|
|
|
|
s.setup = function(){
|
|
for(var i=0; i<max; i++){
|
|
setTimeout(function(){
|
|
var p = new P();
|
|
p.init();
|
|
particles.push(p)
|
|
}, i * 75);
|
|
}
|
|
};
|
|
|
|
s.update = function(){
|
|
s.fillStyle = clearColor;
|
|
s.globalCompositeOperation = "source-over";
|
|
s.fillRect(0,0,s.width,s.height);
|
|
hue += .65;
|
|
};
|
|
|
|
s.draw = function(){
|
|
for(var i in particles){
|
|
particles[i].draw();
|
|
}
|
|
}; |