Code Sketch


yadnesh shahare
By: Mhalsakant School
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)
}