A Pen by Toshiya Marukubo on CodePen.
Created
June 1, 2022 15:20
-
-
Save afektmedia/dd21a82eecdc83aec386525fa28a58e8 to your computer and use it in GitHub Desktop.
Practice / Canvas
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {Ease} from 'https://assets.codepen.io/3919397/ease.js'; | |
import {Utils} from 'https://assets.codepen.io/3919397/utilities.js'; | |
import {Vector} from 'https://assets.codepen.io/3919397/vector.js'; | |
import {Points} from 'https://assets.codepen.io/3919397/points.js'; | |
import {Grid} from 'https://assets.codepen.io/3919397/grid.js'; | |
/** | |
* @class - sketch class | |
*/ | |
function Sketch() { | |
this.vector = new Vector(); | |
this.setupGUI(); | |
this.setupCanvas(); | |
this.setupEvents(); | |
this.initialize(); | |
} | |
Sketch.prototype.setupGUI = function() { | |
this.gui = new dat.GUI(); | |
let that = this; | |
this.gui.params = { | |
scaleToTime: 0.0001, | |
ease: 'easeInBounce', | |
number: 1, | |
scale: 300, | |
frame: false, | |
start: () => that.start(), | |
stop: () => that.stop() | |
}; | |
this.gui.ctrls = { | |
scaleToTime: that.gui.add(that.gui.params, 'scaleToTime', 0.0001, 0.005, 0.0001), | |
ease: that.gui.add(that.gui.params, 'ease', Ease.returnEaseType()) | |
.onChange(() => that.initialize()), | |
number: that.gui.add(that.gui.params, 'number', 1, 30, 1) | |
.onChange(() => that.initialize()), | |
scale: that.gui.add(that.gui.params, 'scale', 1, 500, 1) | |
.onChange(() => that.initialize()), | |
frame: that.gui.add(that.gui.params, 'frame', false), | |
start: that.gui.add(that.gui.params, 'start'), | |
stop: that.gui.add(that.gui.params, 'stop') | |
}; | |
this.gui.close(); | |
}; | |
Sketch.prototype.setupCanvas = function() { | |
this.canvas = document.createElement('canvas'); | |
document.getElementsByTagName('body')[0].appendChild(this.canvas); | |
this.ctx = this.canvas.getContext('2d'); | |
this.canvas.style.display = 'block'; | |
this.canvas.style.height = '100%'; | |
this.canvas.style.width = '100%'; | |
this.canvas.style.position = 'absolute'; | |
this.canvas.style.top = '0'; | |
this.canvas.style.left = '0'; | |
this.canvas.style.zIndex = '-1'; | |
this.canvas.style.background = '#000'; | |
}; | |
Sketch.prototype.setupEvents = function() { | |
window.addEventListener('resize', this.onResize.bind(this)); | |
}; | |
Sketch.prototype.onResize = function() { | |
this.initialize(); | |
}; | |
Sketch.prototype.start = function() { | |
this.initialize(); | |
}; | |
Sketch.prototype.stop = function() { | |
if (this.id) { | |
cancelAnimationFrame(this.id); | |
this.id = null; | |
} | |
}; | |
Sketch.prototype.addFrame = function() { | |
this.ctx.rect( | |
this.width / 2 - this.frameSize / 2, | |
this.height / 2 - this.frameSize / 2, | |
this.frameSize, | |
this.frameSize | |
); | |
this.ctx.clip(); | |
}; | |
Sketch.prototype.initialize = function() { | |
if (this.id) { | |
cancelAnimationFrame(this.id); | |
this.id = null; | |
} | |
this.ease = Ease.returnEaseFunc(this.gui.params.ease); | |
this.width = this.canvas.width = Math.floor(window.innerWidth); | |
this.height = this.canvas.height = Math.floor(window.innerHeight); | |
this.frameSize = Math.min(this.width * 0.9, this.height * 0.9); | |
this.scale = this.gui.params.scale; | |
this.number = this.gui.params.number; | |
this.setupShapes(); | |
this.draw(0); | |
}; | |
Sketch.prototype.setupShapes = function() { | |
// choise shape size | |
//this.size = Math.floor(this.scale * Math.sqrt(2) / 2); | |
this.size = Math.floor(this.scale / 2); // square | |
//this.size = Math.floor(Math.sqrt(3) * this.scale / 2 / 2); // hex | |
//this.size = Math.floor(this.scale * 0.4 * 2 * Math.PI / this.number / 2); // circle | |
// choise shape pattern | |
this.pointsB = Points.rose(this.vector, 360, 6, 1); | |
this.pointsA = Points.rose(this.vector, 360, 318, 217); | |
// choise grid or ... | |
//this.shapes = Grid.square(this.vector, this.number, this.scale); | |
let shape = { | |
v: this.vector.create(0, 0), | |
d: 1 | |
}; | |
this.shapes = [shape, shape, shape]; | |
// calculate max distance | |
this.maxDist = Grid.maxDist(this.shapes); | |
}; | |
Sketch.prototype.draw = function(t) { | |
t *= this.gui.params.scaleToTime; | |
this.ctx.save(); | |
if (this.gui.params.frame) this.addFrame(); | |
this.ctx.clearRect(0, 0, this.width, this.height); | |
this.ctx.translate(this.width / 2, this.height / 2); | |
this.ctx.globalCompositeOperation = 'lighter'; | |
this.ctx.lineWidth = 1; | |
this.ctx.lineJoin = "round"; | |
for (let i = 0; i < this.shapes.length; i++) { | |
if (i === 0) this.ctx.strokeStyle = '#FF0000'; | |
if (i === 1) this.ctx.strokeStyle = '#00FF00'; | |
if (i === 2) this.ctx.strokeStyle = '#0000FF'; | |
let x = this.shapes[i].v.getX(); | |
let y = this.shapes[i].v.getY(); | |
let st = (t - (i * 0.005)) % 1; | |
st = this.ease(st); | |
this.ctx.save(); | |
this.ctx.translate(x, y); | |
if (st < 0.33) { | |
let s = Utils.map(st, 0, 0.33, 1, 1.5); | |
this.ctx.scale(s, s); | |
} else if (st >= 0.33 && st < 0.66) { | |
let s = Utils.map(st, 0.33, 0.66, 1.5, 1.5); | |
this.ctx.scale(s, s); | |
this.ctx.rotate(Utils.map(st, 0.33, 0.66, 0, Math.PI / 2)); | |
} else { | |
let s = Utils.map(st, 0.66, 1, 1.5, 1); | |
this.ctx.scale(s, s); | |
} | |
this.ctx.translate(-x, -y); | |
let newPoints = this.getNewPoints(st, this.pointsA, this.pointsB); | |
this.drawShape(this.ctx, newPoints, x, y, this.size); | |
this.ctx.restore(); | |
} | |
this.ctx.restore(); | |
this.id = requestAnimationFrame(this.draw.bind(this)); | |
}; | |
Sketch.prototype.drawShape = function(ctx, points, x, y, size) { | |
ctx.save(); | |
ctx.beginPath(); | |
for (let i = 0; i < points.length; i++) { | |
let p = points[i]; | |
if (i === 0) { | |
this.ctx.moveTo(p.getX() * this.size + x, p.getY() * this.size + y); | |
} else { | |
this.ctx.lineTo(p.getX() * this.size + x, p.getY() * this.size + y); | |
} | |
} | |
ctx.closePath(); | |
//ctx.fill(); | |
ctx.stroke(); | |
ctx.restore(); | |
}; | |
Sketch.prototype.drawPoints = function(ctx, points, x, y, size, pointSize) { | |
ctx.save(); | |
for (let i = 0; i < points.length; i++) { | |
let nx = points[i].getX() * size + x; | |
let ny = points[i].getY() * size + y; | |
ctx.beginPath(); | |
ctx.arc(nx, ny, pointSize, 0, Math.PI * 2, false); | |
ctx.fill(); | |
//c.stroke(); | |
} | |
ctx.restore(); | |
}; | |
Sketch.prototype.drawTrailLine = function(ctx, points, t, size) { | |
let index = Math.floor(Utils.map(t, 0, 1, 0, points.length - 1)); | |
let endex = Math.ceil(Utils.map(t, 0, 1, index + 1, points.length - 1)); | |
//let color = `hsl(${360 * t}, 80%, 60%)`; | |
let color = 'black'; | |
ctx.strokeStyle = color; | |
ctx.shadowColor = color; | |
ctx.shadowBlur = 20; | |
ctx.beginPath(); | |
ctx.moveTo(points[index].getX() * size, points[index].getY() * size); | |
for (let i = index; i < endex; i++) { | |
let p = points[i]; | |
ctx.lineTo(p.getX() * size, p.getY() * size); | |
} | |
ctx.stroke(); | |
}; | |
Sketch.prototype.getNewPoints = function(t, pointA, pointB) { | |
let newPointArray = []; | |
for (let i = 0; i < pointA.length; i++) { | |
let aP = pointA[i]; | |
let bP = pointB[i]; | |
let x, y; | |
if (t < 0.33) { | |
x = Utils.map(t, 0, 0.33, aP.getX(), bP.getX()); | |
y = Utils.map(t, 0, 0.33, aP.getY(), bP.getY()); | |
} else if (t >= 0.33 && t < 0.66) { | |
x = Utils.map(t, 0.33, 0.66, bP.getX(), bP.getX()); | |
y = Utils.map(t, 0.33, 0.66, bP.getY(), bP.getY()); | |
} else { | |
x = Utils.map(t, 0.66, 1, bP.getX(), aP.getX()); | |
y = Utils.map(t, 0.66, 1, bP.getY(), aP.getY()); | |
} | |
let v = this.vector.create(x, y); | |
newPointArray.push(v); | |
} | |
return newPointArray; | |
}; | |
(function() { | |
window.addEventListener('load', function() { | |
console.clear(); | |
new Sketch(); | |
}); | |
})(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.7/dat.gui.min.js"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
* | |
margin: 0; | |
padding: 0; | |
html, body | |
height: 100%; | |
width: 100%; | |
font-family: serif; | |
overflow: hidden; | |
position: relative; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Here is a preview of this magick.