Code Sketch
yadnesh shahare
cleari()
originBottomLeft()
// ============================================================
// GOLDEN BUDDHA - 10 SECOND PARTICLE REVEAL
// WISDOM / PEACE / KNOWLEDGE
// CLEAN KOJO SCALA VERSION
// ============================================================
// ============================================================
// GLOBAL ANIMATION
// ============================================================
var t = 0.0
var rayT = 0.0
var glowT = 0.0
var waterT = 0.0
var lotusT = 0.0
var sparklePhase = 0.0
var revealTime = 0.0
var revealFinished = false
var meditation = false
// ============================================================
// STAR FIELD
// ============================================================
val starCount = 170
val starX =
Array.fill(starCount)(
10.0 + math.random * (cwidth - 20.0)
)
val starY =
Array.fill(starCount)(
180.0 + math.random * (cheight - 200.0)
)
val starSize =
Array.fill(starCount)(
1.0 + math.random * 2.5
)
// ============================================================
// PARTICLE STRUCTURE
// ============================================================
case class RevealParticle(
var startX: Double,
var startY: Double,
var targetX: Double,
var targetY: Double,
var size: Double,
var r: Int,
var g: Int,
var b: Int,
var phase: Double
)
val revealParticles =
scala.collection.mutable.ArrayBuffer.empty[RevealParticle]
// ============================================================
// ADD REVEAL PARTICLE
// ============================================================
def addRevealParticle(
tx: Double,
ty: Double,
size: Double,
r: Int,
g: Int,
b: Int
): Unit = {
val sx =
if (math.random < 0.5)
-50.0 - math.random * 250.0
else
cwidth + 50.0 + math.random * 250.0
val sy =
40.0 +
math.random * (cheight - 80.0)
revealParticles.append(
RevealParticle(
sx,
sy,
tx,
ty,
size,
r,
g,
b,
math.random * 6.28
)
)
}
// ============================================================
// SUN / HALO PARTICLES
// ============================================================
for (i <- 0 until 170) {
val a =
math.random * math.Pi * 2.0
val rr =
110.0 +
math.random * 70.0
val tx =
cwidth / 2.0 +
math.cos(a) * rr
val ty =
385.0 +
math.sin(a) * rr
addRevealParticle(
tx,
ty,
1.5 + math.random * 2.5,
255,
205,
75
)
}
// ============================================================
// BUDDHA FACE
// ============================================================
for (i <- 0 until 160) {
val a =
math.random * math.Pi * 2.0
val rx =
37.0 +
math.random * 3.0
val ry =
45.0 +
math.random * 3.0
val tx =
cwidth / 2.0 +
math.cos(a) * rx
val ty =
300.0 +
math.sin(a) * ry
addRevealParticle(
tx,
ty,
1.4 + math.random * 2.3,
207,
148,
108
)
}
// ============================================================
// HAIR
// ============================================================
for (i <- 0 until 90) {
val a =
math.random * math.Pi * 2.0
val rr =
math.random * 35.0
val tx =
cwidth / 2.0 +
math.cos(a) * rr
val ty =
338.0 +
math.sin(a) * 18.0 +
math.random * 22.0
addRevealParticle(
tx,
ty,
1.5 + math.random * 2.0,
45,
29,
22
)
}
// ============================================================
// EARS
// ============================================================
for (i <- 0 until 44) {
var side = -1.0
if (i % 2 == 1) {
side = 1.0
}
val tx =
cwidth / 2.0 +
side * (
40.0 +
math.random * 7.0
)
val ty =
300.0 +
(math.random - 0.5) * 38.0
addRevealParticle(
tx,
ty,
1.8 + math.random * 1.5,
190,
127,
91
)
}
// ============================================================
// EYES
// ============================================================
for (i <- 0 until 28) {
var side = -1.0
if (i >= 14) {
side = 1.0
}
val tx =
cwidth / 2.0 +
side * (
14.0 +
(i % 7) * 1.8
)
val ty =
304.0 +
math.sin(i) * 1.5
addRevealParticle(
tx,
ty,
1.8 + math.random * 1.2,
70,
42,
35
)
}
// ============================================================
// NOSE
// ============================================================
for (i <- 0 until 24) {
val tx =
cwidth / 2.0 -
(i % 5) * 1.8
val ty =
288.0 -
i * 0.7
addRevealParticle(
tx,
ty,
1.7 + math.random * 1.2,
115,
78,
58
)
}
// ============================================================
// MOUTH
// ============================================================
for (i <- 0 until 28) {
val tx =
cwidth / 2.0 -
14.0 +
i * 1.0
val ty =
271.0 +
math.sin(i * 0.45) * 1.5
addRevealParticle(
tx,
ty,
1.7 + math.random * 1.2,
85,
45,
38
)
}
// ============================================================
// WISDOM MARK
// ============================================================
for (i <- 0 until 20) {
val tx =
cwidth / 2.0 +
(math.random - 0.5) * 6.0
val ty =
324.0 +
i * 0.8
addRevealParticle(
tx,
ty,
2.0 + math.random * 1.5,
255,
200,
55
)
}
// ============================================================
// NECK
// ============================================================
for (i <- 0 until 70) {
val tx =
cwidth / 2.0 +
(math.random - 0.5) * 38.0
val ty =
242.0 +
math.random * 45.0
addRevealParticle(
tx,
ty,
1.8 + math.random * 2.0,
194,
132,
95
)
}
// ============================================================
// ROBE
// ============================================================
for (i <- 0 until 210) {
val a =
math.random * math.Pi * 2.0
val rx =
120.0 +
math.random * 22.0
val ry =
68.0 +
math.random * 22.0
val tx =
cwidth / 2.0 +
math.cos(a) * rx
val ty =
160.0 +
math.sin(a) * ry
addRevealParticle(
tx,
ty,
1.7 + math.random * 3.0,
180,
105,
54
)
}
// ============================================================
// HANDS
// ============================================================
for (i <- 0 until 90) {
val a =
math.random * math.Pi
val tx =
cwidth / 2.0 +
math.cos(a) * 42.0
val ty =
145.0 +
math.sin(a) * 18.0
addRevealParticle(
tx,
ty,
1.8 + math.random * 2.0,
207,
148,
108
)
}
// ============================================================
// LEGS
// ============================================================
for (i <- 0 until 140) {
var side = -1.0
if (i % 2 == 1) {
side = 1.0
}
val tx =
cwidth / 2.0 +
side * (
30.0 +
math.random * 55.0
)
val ty =
135.0 +
math.random * 60.0
addRevealParticle(
tx,
ty,
1.8 + math.random * 2.5,
195,
120,
65
)
}
// ============================================================
// LOTUS
// ============================================================
for (i <- 0 until 150) {
val angle =
-math.Pi / 1.2 +
math.random * (
math.Pi / 0.6
)
val radius =
25.0 +
math.random * 45.0
val tx =
cwidth / 2.0 +
math.cos(angle) * radius
val ty =
67.0 +
math.sin(angle) * 25.0
addRevealParticle(
tx,
ty,
1.4 + math.random * 2.8,
245,
185,
75
)
}
// ============================================================
// TREE PARTICLES
// ============================================================
for (i <- 0 until 130) {
var tx = 0.0
if (i % 2 == 0) {
tx =
70.0 +
math.random * 180.0
} else {
tx =
cwidth -
70.0 -
math.random * 180.0
}
val ty =
260.0 +
math.random * 180.0
addRevealParticle(
tx,
ty,
1.2 + math.random * 2.5,
45,
95,
50
)
}
// ============================================================
// SMOOTH STEP
// ============================================================
def smoothStep(
x: Double
): Double = {
var v = x
if (v < 0.0) {
v = 0.0
}
if (v > 1.0) {
v = 1.0
}
v * v * (3.0 - 2.0 * v)
}
// ============================================================
// PARTICLE REVEAL
// ============================================================
def drawParticleReveal(
c: CanvasDraw
): Unit = {
val progress =
smoothStep(
revealTime / 10.0
)
revealParticles.foreach { p =>
val waveX =
math.sin(
p.phase +
revealTime * 5.0
) *
(1.0 - progress) *
5.0
val waveY =
math.cos(
p.phase +
revealTime * 4.0
) *
(1.0 - progress) *
5.0
val curX =
p.startX +
(p.targetX - p.startX) *
progress +
waveX
val curY =
p.startY +
(p.targetY - p.startY) *
progress +
waveY
var alpha = 255
if (progress < 0.10) {
alpha =
(progress / 0.10 * 255.0).toInt
}
c.fill(
p.r,
p.g,
p.b,
alpha
)
c.noStroke()
c.ellipse(
curX,
curY,
p.size,
p.size
)
}
val percent =
(progress * 100.0).toInt
c.fill(
255,
220,
150,
220
)
c.noStroke()
c.text(
"WISDOM REVEAL " +
percent +
"%",
cwidth / 2.0 - 60.0,
35.0
)
}
// ============================================================
// SKY
// ============================================================
def drawSky(
c: CanvasDraw
): Unit = {
c.background(
8,
12,
20
)
c.fill(
70,
42,
24,
70
)
c.noStroke()
c.rect(
0,
145,
cwidth,
cheight - 145
)
for (i <- 0 until starCount) {
val alpha =
(
60 +
math.abs(
math.sin(
t * 2.0 + i
)
) *
180
).toInt
c.fill(
255,
225,
145,
alpha
)
c.ellipse(
starX(i),
starY(i),
starSize(i),
starSize(i)
)
}
}
// ============================================================
// MOUNTAINS
// ============================================================
def drawMountains(
c: CanvasDraw
): Unit = {
c.fill(
48,
68,
74
)
c.noStroke()
c.beginShape()
c.vertex(0, 125)
c.vertex(80, 225)
c.vertex(155, 155)
c.vertex(245, 235)
c.vertex(340, 165)
c.vertex(450, 240)
c.vertex(550, 155)
c.vertex(cwidth, 225)
c.vertex(cwidth, 125)
c.endShape()
}
// ============================================================
// WATER
// ============================================================
def drawWater(
c: CanvasDraw
): Unit = {
c.fill(
15,
35,
40
)
c.noStroke()
c.rect(
0,
0,
cwidth,
95
)
for (i <- 0 until 20) {
val y =
8.0 +
i * 4.0
val w =
80.0 +
i * 25.0 +
math.abs(
math.sin(
waterT + i * 0.4
)
) * 30.0
c.stroke(
150,
190,
175,
55
)
c.strokeWeight(1)
c.line(
cwidth / 2.0 - w / 2.0,
y,
cwidth / 2.0 + w / 2.0,
y
)
}
}
// ============================================================
// TREE
// ============================================================
def drawTree(
c: CanvasDraw
): Unit = {
val cx =
cwidth / 2.0
c.fill(
52,
31,
22
)
c.stroke(
30,
18,
14
)
c.strokeWeight(3)
c.rect(
cx - 105,
105,
210,
310
)
c.stroke(
48,
28,
20
)
c.strokeWeight(11)
c.line(
cx - 50,
310,
cx - 190,
430
)
c.line(
cx - 35,
350,
cx - 120,
470
)
c.line(
cx + 50,
310,
cx + 190,
430
)
c.line(
cx + 35,
350,
cx + 120,
470
)
c.stroke(
100,
65,
40,
160
)
c.strokeWeight(4)
c.line(
cx - 60,
125,
cx - 28,
360
)
c.line(
cx - 10,
125,
cx + 2,
350
)
c.line(
cx + 55,
125,
cx + 32,
350
)
for (i <- 0 until 30) {
val a =
i * 12.0 +
t * 2.0
val rad =
math.toRadians(a)
val radius =
120.0 +
(i % 5) * 24.0
val x =
cx +
math.cos(rad) * radius
val y =
395.0 +
math.sin(rad) * 80.0
if (i % 2 == 0)
c.fill(38, 100, 48)
else
c.fill(48, 125, 55)
c.noStroke()
c.ellipse(
x,
y,
75,
50
)
}
}
// ============================================================
// SUN
// ============================================================
def drawSun(
c: CanvasDraw
): Unit = {
val cx =
cwidth / 2.0
val cy =
385.0
val pulse =
1.0 +
math.sin(glowT) *
0.035
c.fill(
255,
170,
30,
18
)
c.noStroke()
c.ellipse(
cx,
cy,
420 * pulse,
420 * pulse
)
c.fill(
255,
190,
45,
35
)
c.ellipse(
cx,
cy,
350 * pulse,
350 * pulse
)
c.fill(
255,
220,
90,
55
)
c.ellipse(
cx,
cy,
280 * pulse,
280 * pulse
)
c.fill(
255,
198,
55
)
c.stroke(
255,
235,
150
)
c.strokeWeight(4)
c.ellipse(
cx,
cy,
215 * pulse,
215 * pulse
)
}
// ============================================================
// KNOWLEDGE RAYS
// ============================================================
def drawKnowledgeRays(
c: CanvasDraw
): Unit = {
val cx =
cwidth / 2.0
val cy =
385.0
for (i <- 0 until 56) {
val angle =
rayT +
i * 360.0 / 56.0
val rad =
math.toRadians(angle)
val inner =
110.0
val outer =
170.0 +
math.abs(
math.sin(
t * 2.0 + i
)
) * 70.0
var alpha = 95
if (i % 4 == 0) {
alpha = 180
}
c.stroke(
255,
215,
100,
alpha
)
c.strokeWeight(
1.0 +
math.abs(
math.sin(
rayT + i
)
) * 1.5
)
c.line(
cx + math.cos(rad) * inner,
cy + math.sin(rad) * inner,
cx + math.cos(rad) * outer,
cy + math.sin(rad) * outer
)
}
}
// ============================================================
// HALO
// ============================================================
def drawHalo(
c: CanvasDraw
): Unit = {
val breathe =
1.0 +
math.sin(
t * 1.5
) * 0.03
c.noFill()
c.stroke(
255,
235,
175,
150
)
c.strokeWeight(4)
c.ellipse(
cwidth / 2.0,
300,
205 * breathe,
205 * breathe
)
c.stroke(
255,
190,
65,
75
)
c.strokeWeight(7)
c.ellipse(
cwidth / 2.0,
300,
240 * breathe,
240 * breathe
)
}
// ============================================================
// DETAILED BUDDHA
// ============================================================
def drawBuddha(
c: CanvasDraw
): Unit = {
val cx =
cwidth / 2.0
val faceY =
300.0 +
math.sin(
t * 1.4
) * 2.0
// ----------------------------------------------------------
// ROBE
// ----------------------------------------------------------
c.fill(
180,
105,
54
)
c.stroke(
105,
60,
34
)
c.strokeWeight(2)
c.ellipse(
cx,
155,
245,
150
)
c.fill(
195,
120,
66
)
c.ellipse(
cx,
195,
155,
190
)
// robe folds
c.stroke(
110,
62,
35,
170
)
c.strokeWeight(2)
for (i <- 0 until 11) {
c.arc(
cx,
105 + i * 12.0,
180 - i * 5.0,
30,
0,
math.Pi
)
}
// ----------------------------------------------------------
// NECK
// ----------------------------------------------------------
c.fill(
194,
132,
95
)
c.noStroke()
c.rect(
cx - 18,
235,
36,
48
)
// neck lines
c.stroke(
145,
92,
65
)
c.strokeWeight(1.5)
c.line(
cx - 12,
250,
cx + 12,
250
)
c.line(
cx - 13,
260,
cx + 13,
260
)
c.line(
cx - 12,
270,
cx + 12,
270
)
// ----------------------------------------------------------
// FACE
// ----------------------------------------------------------
c.fill(
207,
148,
108
)
c.stroke(
125,
77,
55
)
c.strokeWeight(2)
c.ellipse(
cx,
faceY,
77,
91
)
// ----------------------------------------------------------
// EARS
// ----------------------------------------------------------
c.fill(
190,
127,
91
)
c.ellipse(
cx - 42,
faceY,
17,
37
)
c.ellipse(
cx + 42,
faceY,
17,
37
)
c.noFill()
c.stroke(
135,
85,
65
)
c.strokeWeight(1.5)
c.arc(
cx - 42,
faceY,
10,
22,
0,
math.Pi
)
c.arc(
cx + 42,
faceY,
10,
22,
0,
math.Pi
)
// ----------------------------------------------------------
// HAIR
// ----------------------------------------------------------
c.fill(
45,
29,
22
)
c.noStroke()
c.ellipse(
cx,
faceY + 37,
54,
40
)
for (i <- 0 until 20) {
val ang =
i * 18.0
val rad =
math.toRadians(ang)
c.fill(
48,
31,
23
)
c.ellipse(
cx + math.cos(rad) * 18,
faceY + 38 +
math.sin(rad) * 12,
12,
12
)
}
// ----------------------------------------------------------
// EYEBROWS
// ----------------------------------------------------------
c.stroke(
85,
48,
38
)
c.strokeWeight(2)
c.line(
cx - 27,
faceY + 11,
cx - 10,
faceY + 12
)
c.line(
cx + 10,
faceY + 12,
cx + 27,
faceY + 11
)
// ----------------------------------------------------------
// EYES
// ----------------------------------------------------------
c.noFill()
c.stroke(
75,
43,
36
)
c.strokeWeight(2.4)
c.arc(
cx - 16,
faceY + 4,
24,
13,
math.Pi,
math.Pi * 2
)
c.arc(
cx + 16,
faceY + 4,
24,
13,
math.Pi,
math.Pi * 2
)
c.fill(
40,
25,
20
)
c.noStroke()
c.ellipse(
cx - 16,
faceY + 1,
3,
3
)
c.ellipse(
cx + 16,
faceY + 1,
3,
3
)
// ----------------------------------------------------------
// NOSE
// ----------------------------------------------------------
c.stroke(
115,
78,
58
)
c.strokeWeight(2)
c.line(
cx,
faceY - 3,
cx - 3,
faceY - 19
)
c.arc(
cx - 2,
faceY - 19,
10,
7,
0,
math.Pi
)
// ----------------------------------------------------------
// LIPS
// ----------------------------------------------------------
c.stroke(
100,
52,
45
)
c.strokeWeight(2)
c.arc(
cx,
faceY - 28,
30,
15,
math.Pi,
math.Pi * 2
)
c.line(
cx - 11,
faceY - 28,
cx + 11,
faceY - 28
)
// ----------------------------------------------------------
// WISDOM MARK
// ----------------------------------------------------------
c.fill(
255,
198,
55
)
c.noStroke()
c.ellipse(
cx,
faceY + 25,
8,
12
)
c.fill(
255,
245,
180
)
c.ellipse(
cx,
faceY + 26,
3,
6
)
// ----------------------------------------------------------
// SHOULDERS
// ----------------------------------------------------------
c.fill(
180,
105,
54
)
c.ellipse(
cx - 65,
205,
70,
70
)
c.ellipse(
cx + 65,
205,
70,
70
)
// ----------------------------------------------------------
// MEDITATION HANDS
// ----------------------------------------------------------
c.stroke(
194,
128,
92
)
c.strokeWeight(8)
c.line(
cx - 42,
165,
cx - 15,
150
)
c.line(
cx + 42,
165,
cx + 15,
150
)
c.fill(
207,
148,
108
)
c.noStroke()
c.ellipse(
cx,
151,
62,
22
)
// fingers
c.stroke(
155,
96,
72
)
c.strokeWeight(2)
for (i <- 0 until 5) {
c.line(
cx - 22 + i * 11,
146,
cx - 20 + i * 11,
154
)
}
}
// ============================================================
// LOTUS
// ============================================================
def drawLotus(
c: CanvasDraw
): Unit = {
val cx =
cwidth / 2.0
val base =
67.0
val open =
math.sin(
lotusT
) * 3.0
c.fill(
255,
190,
70,
25
)
c.noStroke()
c.ellipse(
cx,
35,
200,
26
)
for (i <- 0 until 11) {
val angle =
-90 +
i * 18
val rad =
math.toRadians(angle)
val px =
cx +
math.cos(rad) * 48
val py =
base +
math.sin(rad) * 20
c.fill(
245,
185,
75
)
c.stroke(
205,
132,
45
)
c.strokeWeight(1.5)
c.ellipse(
px,
py,
48 + open,
82
)
}
c.fill(
255,
215,
100
)
c.noStroke()
c.ellipse(
cx,
base + 4,
55,
72
)
c.fill(
255,
242,
175
)
c.ellipse(
cx,
base + 20,
21,
32
)
}
// ============================================================
// FULL GOLDEN PARTICLES AFTER REVEAL
// ============================================================
def drawGoldenParticles(
c: CanvasDraw
): Unit = {
revealParticles.foreach { p =>
val pulse =
p.size +
math.abs(
math.sin(
sparklePhase +
p.phase
)
) * 2.0
c.fill(
p.r,
p.g,
p.b,
105
)
c.noStroke()
c.ellipse(
p.targetX,
p.targetY,
pulse,
pulse
)
}
}
// ============================================================
// MEDITATION WAVE
// ============================================================
def drawMeditationWave(
c: CanvasDraw
): Unit = {
if (meditation == false) {
return
}
val r =
100 +
math.abs(
math.sin(
glowT
)
) * 40
c.noFill()
c.stroke(
255,
230,
155,
110
)
c.strokeWeight(2)
c.ellipse(
cwidth / 2.0,
300,
r * 2,
r * 1.25
)
c.stroke(
255,
245,
190,
50
)
c.ellipse(
cwidth / 2.0,
300,
r * 1.45,
r * 0.9
)
}
// ============================================================
// COMPLETE SCENE
// ============================================================
def drawFullScene(
c: CanvasDraw
): Unit = {
drawSky(c)
drawMountains(c)
drawWater(c)
drawTree(c)
drawSun(c)
drawKnowledgeRays(c)
drawHalo(c)
drawBuddha(c)
drawGoldenParticles(c)
drawLotus(c)
drawMeditationWave(c)
c.fill(
255,
225,
145
)
c.noStroke()
c.text(
"WISDOM PEACE KNOWLEDGE",
cwidth / 2.0 - 105,
cheight - 30
)
}
// ============================================================
// FINAL FLASH
// ============================================================
def drawFinishFlash(
c: CanvasDraw
): Unit = {
val afterTime =
revealTime - 10.0
if (
afterTime >= 0.0 &&
afterTime < 1.0
) {
val strength =
1.0 - afterTime
c.fill(
255,
235,
170,
(strength * 80.0).toInt
)
c.noStroke()
c.rect(
0,
0,
cwidth,
cheight
)
}
}
// ============================================================
// MAIN ANIMATION
// ============================================================
animateWithCanvasDraw { c =>
t += 0.04
rayT += 0.35
glowT += 0.05
waterT += 0.07
lotusT += 0.035
sparklePhase += 0.05
// Update reveal timer
if (revealFinished == false) {
revealTime += 0.04
}
// ----------------------------------------------------------
// PARTICLE REVEAL
// ----------------------------------------------------------
if (revealFinished == false) {
c.background(
7,
10,
18
)
// stars
for (i <- 0 until starCount) {
val alpha =
(
60 +
math.abs(
math.sin(
t * 2.0 + i
)
) * 150
).toInt
c.fill(
255,
220,
140,
alpha
)
c.noStroke()
c.ellipse(
starX(i),
starY(i),
starSize(i),
starSize(i)
)
}
// moving particles
drawParticleReveal(c)
// finish at ten seconds
if (revealTime >= 10.0) {
revealTime = 10.0
revealFinished = true
}
} else {
// --------------------------------------------------------
// FULL IMAGE AFTER 10 SEC
// --------------------------------------------------------
drawFullScene(c)
drawFinishFlash(c)
}
// ----------------------------------------------------------
// MEDITATION EFFECT
// ----------------------------------------------------------
if (isMousePressed) {
meditation = true
}
}