Skip to content

Commit

Permalink
flow
Browse files Browse the repository at this point in the history
  • Loading branch information
YuFengjie97 committed Oct 7, 2023
1 parent 871726b commit bb68c36
Show file tree
Hide file tree
Showing 3 changed files with 168 additions and 162 deletions.
4 changes: 2 additions & 2 deletions src/views/cache/drawImg.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import Stats from 'stats.js'
import { getBufferCanvas, initCanvas, random, randomRGB } from '@/utils'
const con = ref<HTMLElement>()
const particleCount = 1000
const particleCount = 10
const stats = new Stats()
document.body.append(stats.dom)
Expand Down Expand Up @@ -58,7 +58,7 @@ onMounted(() => {
}
function animate() {
stats.update()
ctx.fillStyle = 'rgba(0,0,0,0.3)'
ctx.fillStyle = 'rgba(100,100,0,0.3)'
ctx.fillRect(0, 0, width, height)
// ctx.clearRect(0, 0, width, height)
particles.forEach((p) => {
Expand Down
320 changes: 160 additions & 160 deletions src/views/grid/flow.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,201 +3,200 @@ import { Vector } from 'p5'
import { onMounted, ref } from 'vue'
import colors from 'nice-color-palettes'
import Stats from 'stats.js'
import { lerp, noise, random } from '@/utils'
import { getBufferCanvas, lerp, map, noise, random } from '@/utils'
const stats = new Stats()
document.body.appendChild(stats.dom)
const con = ref<HTMLElement>()
const canvas = ref<HTMLCanvasElement>()
let ctx: CanvasRenderingContext2D | null = null
const W = 400
const H = 400
const cellSize = 40
const rows = Math.floor(W / cellSize)
const cols = Math.floor(H / cellSize)
const particleCount = 100
const cellSize = 30
const palettes = random(colors)
const showArrow = true
const particleCount = 1000
const cells: Cell[] = []
class Cell {
u: number
v: number
pos = new Vector(0, 0)
vel = new Vector(0, 0)
color: string
xOff = 0
yOff = 0
a = 0
constructor(u: number, v: number) {
this.u = u
this.v = v
const x = lerp(0, W, u)
const y = lerp(0, H, v)
this.pos.set(x, y)
this.xOff = u * 0.3
this.yOff = v * 1.4
this.color = palettes[Math.floor(lerp(0, palettes.length, noise(x, y)))]
onMounted(() => {
const { width, height } = con.value!.getBoundingClientRect()
const ctx = initCanvas()
const cells: Cell[] = []
const rows = Math.ceil(height / cellSize)
const cols = Math.ceil(width / cellSize)
const particles: Particle[] = []
function initCanvas() {
const ctx = canvas.value!.getContext('2d')
canvas.value!.width = width
canvas.value!.height = height
return ctx!
}
draw() {
const c = ctx as CanvasRenderingContext2D
c.save()
c.beginPath()
// c.strokeStyle = '#000'
// c.strokeRect(this.pos.x, this.pos.y, cellSize, cellSize)
// c.stroke()
// c.fillStyle = this.color
// c.fillRect(this.pos.x, this.pos.y, cellSize, cellSize)
class Cell {
pos = new Vector(0, 0)
vel = new Vector(0, 0)
xOff = 0
yOff = 0
a = 0
bufferCtx: CanvasRenderingContext2D
constructor(x: number, y: number) {
this.bufferCtx = getBufferCanvas({
width: cellSize,
height: cellSize,
})
this.xOff = map(x, 0, 1, 0, width)
this.yOff = map(y, 0, 1, 0, height)
this.pos.set(x, y)
this.cache()
}
// this.drawArrow()
c.restore()
}
draw() {
if (showArrow)
this.drawArrow()
}
drawArrow() {
const c = ctx as CanvasRenderingContext2D
c.save()
c.font = '28px Arial bolder'
c.fillStyle = this.color
c.textBaseline = 'middle'
c.translate(this.pos.x, this.pos.y)
c.rotate(this.a)
c.fillText('', 0, 0)
c.restore()
}
cache() {
this.bufferCtx.save()
this.bufferCtx.font = '28px Arial bolder'
this.bufferCtx.fillStyle = '#00cec9'
this.bufferCtx.textAlign = 'center'
this.bufferCtx.textBaseline = 'middle'
this.bufferCtx.translate(cellSize / 2, cellSize / 2)
this.bufferCtx.fillText('', 0, 0)
this.bufferCtx.restore()
}
update() {
this.xOff += 0.003
this.yOff += 0.003
const n = noise(this.xOff, this.yOff)
this.a = lerp(0, Math.PI * 2, n)
this.vel = Vector.fromAngle(this.a, 1)
}
}
drawCell() {
ctx.beginPath()
ctx.strokeStyle = 'red'
ctx.strokeRect(this.pos.x, this.pos.y, cellSize, cellSize)
ctx.stroke()
}
class Particle {
pos = new Vector(0, 0)
vel = new Vector(0, 0)
color = '#000'
r = 0
constructor() {
const { pos, vel } = this.getRandom()
drawArrow() {
ctx.save()
ctx.translate(this.pos.x, this.pos.y)
ctx.rotate(this.a)
ctx.drawImage(this.bufferCtx.canvas, 0, 0, cellSize, cellSize)
ctx.restore()
}
this.pos.set(pos)
this.vel.set(vel)
update() {
this.xOff += 0.0005
this.yOff += 0.0005
const n = noise(this.xOff, this.yOff)
this.a = lerp(0, Math.PI * 7, n)
this.vel = Vector.fromAngle(this.a, lerp(1, 10, n))
}
}
draw() {
const c = ctx as CanvasRenderingContext2D
c.beginPath()
c.fillStyle = this.color
c.arc(this.pos.x, this.pos.y, this.r, 0, Math.PI * 2)
c.fill()
}
class Particle {
pos = new Vector(0, 0)
vel = new Vector(0, 0)
color = '#000'
r = 1
r_cur = 0
constructor() {
const { pos, vel } = this.getRandom()
this.color = random(palettes)
this.pos.set(pos)
this.vel.set(vel)
}
update(vel: Vector, color: string, r: number) {
if (this.isOutBound()) {
this.reSet()
draw() {
const c = ctx as CanvasRenderingContext2D
c.beginPath()
c.fillStyle = this.color
c.arc(this.pos.x, this.pos.y, this.r_cur, 0, Math.PI * 2)
c.fill()
}
else {
this.vel.set(vel)
this.pos.add(this.vel)
this.color = color
this.r = r
update(vel: Vector) {
if (this.isOutBound()) {
this.reSet()
}
else {
this.vel.set(vel)
this.pos.add(this.vel)
}
if (this.r_cur <= this.r)
this.r_cur += 0.1
}
}
reSet() {
const { pos, vel } = this.getRandom()
this.pos.set(pos)
this.vel.set(vel)
reSet() {
const { pos, vel } = this.getRandom()
this.pos.set(pos)
this.vel.set(vel)
this.r = 0
this.color = '#000'
}
this.color = palettes[Math.floor(palettes.length * random())]
this.r = Math.floor(random(1, 6))
this.r_cur = 0
}
getRandom() {
const velBase = 0.01
const pos = new Vector(random(W), random(H))
const vel = new Vector(random(velBase), random(velBase))
return { pos, vel }
}
getRandom() {
const velBase = 0.01
const pos = new Vector(random(width), random(height))
const vel = new Vector(random(velBase), random(velBase))
return { pos, vel }
}
isOutBound() {
return this.pos.x <= 0 || this.pos.x >= W || this.pos.y <= 0 || this.pos.y >= H
}
isOutBound() {
return this.pos.x <= 0 || this.pos.x >= width || this.pos.y <= 0 || this.pos.y >= height
}
toString() {
return `pos:${this.pos.toString()},vel:${this.vel.toString()}`
toString() {
return `pos:${this.pos.toString()},vel:${this.vel.toString()}`
}
}
}
function initCells() {
for (let col = 0; col < cols; col++) {
for (let row = 0; row < rows; row++) {
const u = col / cols
const v = row / rows
cells.push(new Cell(u, v))
function initCells() {
for (let col = 0; col < cols; col++) {
for (let row = 0; row < rows; row++)
cells.push(new Cell(col * cellSize, row * cellSize))
}
}
}
function updateCells() {
cells.forEach((c) => {
c.update()
c.draw()
})
}
const particles: Particle[] = []
function initParticles() {
for (let i = 0; i < particleCount; i += 1)
particles.push(new Particle())
}
function updateCells() {
cells.forEach((c) => {
c.update()
c.draw()
})
}
function updateParticles() {
particles.forEach((p) => {
if (p.isOutBound()) {
p.reSet()
}
else {
const { pos } = p
const cellInd = Math.floor(pos.y / cellSize) * cols + Math.floor(pos.x / cellSize)
const cell = cells[cellInd]
const r = lerp(0, 10, noise(cell.xOff + 500, cell.yOff + 500))
p.update(cell.vel, cell.color, r)
p.draw()
}
})
}
function initParticles() {
for (let i = 0; i < particleCount; i += 1)
particles.push(new Particle())
}
function animate() {
stats.begin()
function updateParticles() {
particles.forEach((p) => {
if (p.isOutBound()) {
p.reSet()
}
else {
const { pos } = p
const cellInd = Math.floor(pos.y / cellSize) * cols + Math.floor(pos.x / cellSize)
const cell = cells[cellInd]
p.update(cell.vel)
p.draw()
}
})
}
ctx!.fillStyle = '#fff'
// ctx!.clearRect(0, 0, W, H)
ctx!.fillStyle = 'rgba(100,100,100,0.2)'
ctx!.fillRect(0, 0, W, H)
updateCells()
function animate() {
stats.update()
updateParticles()
// ctx!.fillStyle = '#fff'
// ctx!.fillStyle = 'rgba(100,100,100,0.2)'
// ctx!.fillRect(0, 0, width, height)
ctx!.clearRect(0, 0, width, height)
stats.end()
requestAnimationFrame(animate)
}
updateCells()
updateParticles()
onMounted(() => {
ctx = canvas.value!.getContext('2d')
canvas.value!.style.cssText = `
width: ${W}px;
height: ${H}px;
`
canvas.value!.width = W
canvas.value!.height = H
requestAnimationFrame(animate)
}
initCells()
initParticles()
Expand All @@ -207,7 +206,7 @@ onMounted(() => {

<template>
<div ref="con" class="h-100vh w-full grid place-items-center">
<canvas ref="canvas" />
<canvas ref="canvas" class="h-full w-full" />
</div>
</template>

Expand All @@ -218,5 +217,6 @@ onMounted(() => {
canvas{
display: block;
box-shadow: 0 0 4px #333;
background: #333;
}
</style>
Loading

0 comments on commit bb68c36

Please sign in to comment.