Code Sketch
yadnesh shahare
cleari()
originBottomLeft()
// ============================================================
// TRICOLOR WISDOM PORTRAIT
// ADVANCED KOJO SCALA ANIMATION
// ============================================================
var t = 0.0
var chakraAngle = 0.0
var birdPhase = 0.0
var glowPhase = 0.0
var lightPhase = 0.0
var brushPhase = 0.0
// ------------------------------------------------------------
// BIRDS
// ------------------------------------------------------------
case class Bird(
var x: Double,
var y: Double,
var speed: Double,
var size: Double,
var phase: Double
)
val birds =
scala.collection.mutable.ArrayBuffer.empty[Bird]
for (i <- 0 until 24) {
birds.append(
Bird(
350.0 + math.random * 270.0,
250.0 + math.random * 170.0,
0.25 + math.random * 0.55,
4.0 + math.random * 4.0,
math.random * 6.28
)
)
}
// ------------------------------------------------------------
// LIGHT PARTICLES
// ------------------------------------------------------------
case class LightDot(
var x: Double,
var y: Double,
var speed: Double,
var size: Double,
var phase: Double
)
val lightDots =
scala.collection.mutable.ArrayBuffer.empty[LightDot]
for (i <- 0 until 45) {
lightDots.append(
LightDot(
40.0 + math.random * (cwidth - 80.0),
100.0 + math.random * 350.0,
0.10 + math.random * 0.25,
1.0 + math.random * 3.0,
math.random * 6.28
)
)
}
// ============================================================
// UPDATE BIRDS
// ============================================================
def updateBirds(): Unit = {
birds.foreach { b =>
b.x += b.speed
b.y +=
math.sin(
birdPhase + b.phase
) * 0.35
if (b.x > cwidth + 30) {
b.x = 340.0
b.y =
250.0 +
math.random * 160.0
}
}
}
// ============================================================
// UPDATE LIGHT
// ============================================================
def updateLightDots(): Unit = {
lightDots.foreach { p =>
p.y += p.speed
p.x +=
math.sin(
lightPhase + p.phase
) * 0.18
if (p.y > cheight + 20) {
p.y = 90.0
p.x =
30.0 +
math.random *
(cwidth - 60.0)
}
}
}
// ============================================================
// BACKGROUND
// ============================================================
def drawBackground(
c: CanvasDraw
): Unit = {
c.background(
245,
244,
238
)
// ------------------------------------------
// Saffron brush area
// ------------------------------------------
c.noStroke()
for (i <- 0 until 20) {
val x =
-30.0 +
i * 42.0 +
math.sin(
brushPhase + i
) * 6.0
val y =
cheight - 30 -
math.abs(
math.sin(
brushPhase * 0.7 + i
)
) * 18
c.fill(
245,
105,
30,
18
)
c.ellipse(
x,
y,
150,
70
)
}
// ------------------------------------------
// Green brush area
// ------------------------------------------
for (i <- 0 until 18) {
val x =
-20.0 +
i * 48.0
val y =
95.0 +
math.sin(
brushPhase + i
) * 8.0
c.fill(
30,
150,
75,
20
)
c.ellipse(
x,
y,
160,
65
)
}
// ------------------------------------------
// White center glow
// ------------------------------------------
c.fill(
255,
255,
255,
100
)
c.ellipse(
cwidth / 2.0,
275,
500,
360
)
}
// ============================================================
// ASHOKA CHAKRA
// ============================================================
def drawChakra(
c: CanvasDraw
): Unit = {
val cx =
cwidth * 0.68
val cy =
295.0
val radius =
125.0 +
math.sin(
glowPhase
) * 3.0
// Outer glow
c.noFill()
c.stroke(
20,
105,
175,
30
)
c.strokeWeight(10)
c.ellipse(
cx,
cy,
radius * 2.0,
radius * 2.0
)
// Outer blue ring
c.stroke(
12,
105,
175,
180
)
c.strokeWeight(6)
c.ellipse(
cx,
cy,
radius * 2.0,
radius * 2.0
)
// Hub
c.fill(
16,
100,
175
)
c.noStroke()
c.ellipse(
cx,
cy,
17,
17
)
// 24 spokes
for (i <- 0 until 24) {
val ang =
chakraAngle +
i * 15.0
val rad =
math.toRadians(
ang
)
val x =
cx +
math.cos(rad) * radius
val y =
cy +
math.sin(rad) * radius
c.stroke(
20,
105,
175,
175
)
c.strokeWeight(2)
c.line(
cx,
cy,
x,
y
)
}
}
// ============================================================
// PORTRAIT FACE
// ============================================================
def drawLeaderPortrait(
c: CanvasDraw
): Unit = {
val cx =
cwidth * 0.35
val faceY =
285.0 +
math.sin(
t * 0.8
) * 1.2
// ------------------------------------------
// Neck
// ------------------------------------------
c.fill(
192,
152,
125
)
c.noStroke()
c.rect(
cx - 32,
178,
64,
86
)
// ------------------------------------------
// White shirt
// ------------------------------------------
c.fill(
240,
240,
236
)
c.beginShape()
c.vertex(
cx - 35,
205
)
c.vertex(
cx - 65,
175
)
c.vertex(
cx + 65,
175
)
c.vertex(
cx + 35,
205
)
c.endShape()
// ------------------------------------------
// Black suit
// ------------------------------------------
c.fill(
23,
24,
29
)
c.stroke(
12,
12,
16
)
c.strokeWeight(2)
c.beginShape()
c.vertex(
cx - 40,
185
)
c.vertex(
cx - 105,
125
)
c.vertex(
cx - 130,
50
)
c.vertex(
cx + 130,
50
)
c.vertex(
cx + 105,
125
)
c.vertex(
cx + 40,
185
)
c.endShape()
// ------------------------------------------
// Shirt collar
// ------------------------------------------
c.fill(
245,
245,
242
)
c.noStroke()
c.beginShape()
c.vertex(
cx - 32,
205
)
c.vertex(
cx,
170
)
c.vertex(
cx + 32,
205
)
c.vertex(
cx + 22,
214
)
c.vertex(
cx - 22,
214
)
c.endShape()
// ------------------------------------------
// Tie
// ------------------------------------------
c.fill(
18,
20,
24
)
c.beginShape()
c.vertex(
cx,
201
)
c.vertex(
cx - 10,
183
)
c.vertex(
cx + 10,
183
)
c.vertex(
cx + 8,
115
)
c.vertex(
cx,
101
)
c.vertex(
cx - 8,
115
)
c.vertex(
cx - 8,
183
)
c.endShape()
// ------------------------------------------
// Face
// ------------------------------------------
c.fill(
193,
153,
126
)
c.stroke(
105,
78,
65
)
c.strokeWeight(2)
c.ellipse(
cx,
faceY,
135,
175
)
// ------------------------------------------
// Ears
// ------------------------------------------
c.fill(
186,
145,
120
)
c.noStroke()
c.ellipse(
cx - 67,
faceY,
22,
42
)
c.ellipse(
cx + 67,
faceY,
22,
42
)
// ------------------------------------------
// Hair
// ------------------------------------------
c.fill(
18,
20,
27
)
c.noStroke()
c.ellipse(
cx,
faceY + 77,
123,
68
)
// Hair side sweep
c.beginShape()
c.vertex(
cx - 55,
faceY + 50
)
c.vertex(
cx - 80,
faceY + 86
)
c.vertex(
cx - 70,
faceY + 115
)
c.vertex(
cx - 45,
faceY + 105
)
c.endShape()
// ------------------------------------------
// Glasses
// ------------------------------------------
c.noFill()
c.stroke(
35,
40,
45
)
c.strokeWeight(2.5)
c.rect(
cx - 49,
faceY + 20,
43,
29
)
c.rect(
cx + 6,
faceY + 20,
43,
29
)
c.line(
cx - 6,
faceY + 34,
cx + 6,
faceY + 34
)
// glasses arms
c.line(
cx - 49,
faceY + 35,
cx - 65,
faceY + 48
)
c.line(
cx + 49,
faceY + 35,
cx + 65,
faceY + 48
)
// ------------------------------------------
// Eyes
// ------------------------------------------
c.fill(
25,
27,
30
)
c.noStroke()
c.ellipse(
cx - 27,
faceY + 32,
7,
5
)
c.ellipse(
cx + 27,
faceY + 32,
7,
5
)
// ------------------------------------------
// Nose
// ------------------------------------------
c.stroke(
120,
88,
72
)
c.strokeWeight(2)
c.line(
cx,
faceY + 28,
cx - 7,
faceY - 5
)
// ------------------------------------------
// Mouth
// ------------------------------------------
c.line(
cx - 13,
faceY - 26,
cx + 13,
faceY - 26
)
// ------------------------------------------
// Jacket highlight
// ------------------------------------------
c.stroke(
70,
72,
78,
160
)
c.strokeWeight(2)
c.line(
cx - 94,
120,
cx - 60,
175
)
c.line(
cx + 94,
120,
cx + 60,
175
)
}
// ============================================================
// PARLIAMENT BUILDING
// ============================================================
def drawParliament(
c: CanvasDraw
): Unit = {
val px =
cwidth * 0.58
val py =
55.0
// shadow
c.fill(
0,
0,
0,
40
)
c.noStroke()
c.ellipse(
px,
py + 5,
300,
35
)
// main building
c.fill(
150,
152,
145
)
c.stroke(
90,
92,
90
)
c.strokeWeight(2)
c.rect(
px - 145,
py,
290,
60
)
// columns
for (i <- 0 until 18) {
val x =
px - 132 +
i * 15.5
c.fill(
178,
178,
168
)
c.rect(
x,
py + 4,
7,
52
)
}
// upper platform
c.fill(
125,
127,
122
)
c.rect(
px - 150,
py + 53,
300,
8
)
// dome
c.fill(
167,
168,
158
)
c.stroke(
90,
92,
88
)
c.strokeWeight(2)
c.arc(
px,
py + 61,
85,
72,
math.Pi,
math.Pi * 2
)
// dome top
c.fill(
175,
176,
166
)
c.ellipse(
px,
py + 91,
14,
10
)
// building lights
for (i <- 0 until 12) {
val x =
px - 115 +
i * 21
c.fill(
255,
220,
120,
70
)
c.ellipse(
x,
py + 39,
4,
4
)
}
}
// ============================================================
// FLYING BIRDS
// ============================================================
def drawBirds(
c: CanvasDraw
): Unit = {
birds.foreach { b =>
val wing =
math.sin(
birdPhase * 4.0 +
b.phase
) * 4.0
c.stroke(
20,
120,
185,
210
)
c.strokeWeight(
1.5
)
c.noFill()
c.arc(
b.x,
b.y,
b.size * 2,
b.size,
math.Pi,
math.Pi * 2
)
c.arc(
b.x + b.size,
b.y,
b.size * 2,
b.size + wing,
math.Pi,
math.Pi * 2
)
}
}
// ============================================================
// LIGHT RAYS
// ============================================================
def drawLightRays(
c: CanvasDraw
): Unit = {
for (i <- 0 until 12) {
val x =
50.0 +
i * 58.0
val alpha =
(
25 +
math.abs(
math.sin(
lightPhase + i
)
) * 45
).toInt
c.stroke(
255,
190,
75,
alpha
)
c.strokeWeight(
3
)
c.line(
x,
110,
x + math.sin(t + i) * 18,
230
)
}
}
// ============================================================
// LIGHT DOTS
// ============================================================
def drawLightDots(
c: CanvasDraw
): Unit = {
lightDots.foreach { p =>
val alpha =
(
60 +
math.abs(
math.sin(
lightPhase +
p.phase
)
) * 150
).toInt
c.fill(
255,
210,
100,
alpha
)
c.noStroke()
c.ellipse(
p.x,
p.y,
p.size,
p.size
)
}
}
// ============================================================
// COMPLETE SCENE
// ============================================================
def drawScene(
c: CanvasDraw
): Unit = {
drawBackground(c)
drawLightRays(c)
drawChakra(c)
drawLeaderPortrait(c)
drawParliament(c)
drawBirds(c)
drawLightDots(c)
// subtle foreground glow
c.fill(
255,
215,
120,
18
)
c.noStroke()
c.ellipse(
cwidth * 0.35,
270,
270,
330
)
// title
c.fill(
20,
80,
140,
210
)
c.noStroke()
c.text(
"KNOWLEDGE JUSTICE EQUALITY",
cwidth * 0.50,
25
)
}
// ============================================================
// MAIN ANIMATION
// ============================================================
animateWithCanvasDraw { c =>
t += 0.04
chakraAngle += 0.45
birdPhase += 0.08
glowPhase += 0.05
lightPhase += 0.04
brushPhase += 0.025
updateBirds()
updateLightDots()
drawScene(c)
}