Code Sketch


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