Code Sketch
sniper_0718
Category: Art
cleari()
setBackground(cm.darkGray)
disablePanAndZoom()
val cb = canvasBounds
var inputStr = "0"
var storedValue: Double = 0.0
var pendingOp: String = ""
var resetScreen = false
// Title Banner
val banner = Picture.text("Scala Kojo Animated Calc").withPenColor(cm.cyan)
banner.setPosition(cb.x + 40, cb.y + 450)
draw(banner)
// Screen Display Box (Black Box Container)
val boxX = cb.x + 50
val boxY = cb.y + 360
val screenBox = Picture.rectangle(290, 55).withFillColor(cm.black).withPenColor(cm.gold)
screenBox.setPosition(boxX, boxY)
draw(screenBox)
// Display text strictly locked inside the black box, starting from the left with large font
var displayPic = Picture.text(inputStr).withPenColor(cm.green)
displayPic.scale(1.5)
displayPic.setPosition(boxX + 15, boxY + 15)
draw(displayPic)
def refreshDisplay(s: String): Unit = {
displayPic.erase()
displayPic = Picture.text(s).withPenColor(cm.green)
displayPic.scale(1.5)
displayPic.setPosition(boxX + 15, boxY + 15)
draw(displayPic)
}
def appendDigit(d: String): Unit = {
if (inputStr == "0" || resetScreen) {
inputStr = d
resetScreen = false
} else {
if (inputStr.length < 10) {
inputStr = inputStr + d
}
}
refreshDisplay(inputStr)
}
def handleOp(op: String): Unit = {
storedValue = inputStr.toDouble
pendingOp = op
resetScreen = true
}
def calculate(): Unit = {
val currentValue = inputStr.toDouble
val res = pendingOp match {
case "+" => storedValue + currentValue
case "-" => storedValue - currentValue
case "*" => storedValue * currentValue
case "/" => if (currentValue != 0) storedValue / currentValue else 0.0
case _ => currentValue
}
inputStr = res.toString
refreshDisplay(inputStr)
resetScreen = true
triggerSparkles()
}
def clearAll(): Unit = {
inputStr = "0"
storedValue = 0.0
pendingOp = ""
refreshDisplay(inputStr)
}
val startX = cb.x + 50
val startY = cb.y + 120
val w = 65
val h = 50
val gap = 10
def button(label: String, col: Int, row: Int, action: => Unit): Unit = {
val x = startX + col * (w + gap)
val y = startY + row * (h + gap)
val bg = Picture.rectangle(w, h).withFillColor(cm.darkBlue).withPenColor(cm.lightGray)
val txt = Picture.text(label).withPenColor(cm.white)
val btn = picStackCentered(bg, txt)
btn.setPosition(x, y)
btn.draw()
btn.onMouseClick { (_, _) =>
action
}
}
// Layout Calculator Grid Buttons (AC for clear)
button("7", 0, 3, appendDigit("7"))
button("8", 1, 3, appendDigit("8"))
button("9", 2, 3, appendDigit("9"))
button("/", 3, 3, handleOp("/"))
button("4", 0, 2, appendDigit("4"))
button("5", 1, 2, appendDigit("5"))
button("6", 2, 2, appendDigit("6"))
button("*", 3, 2, handleOp("*"))
button("1", 0, 1, appendDigit("1"))
button("2", 1, 1, appendDigit("2"))
button("3", 2, 1, appendDigit("3"))
button("-", 3, 1, handleOp("-"))
button("0", 0, 0, appendDigit("0"))
button("AC", 1, 0, clearAll())
button("=", 2, 0, calculate())
button("+", 3, 0, handleOp("+"))
// Ambient background floating particles
val ambientParticles = (1.to(18)).map { _ =>
val p = Picture.circle(math.random() * 3 + 1).withFillColor(cm.gray).withNoPen
p.setPosition(cb.x + math.random() * 350, cb.y + math.random() * 500)
draw(p)
p
}
// Calculation Explosion Sparkles State
var showSparkles = false
var sparkleCount = 0
val sparks = (1.to(12)).map { _ =>
val s = Picture.circle(5).withFillColor(cm.yellow).withNoPen
s.setPosition(boxX + 145, boxY + 28)
s
}
def triggerSparkles(): Unit = {
sparks.foreach { s =>
s.setPosition(boxX + 145, boxY + 28)
draw(s)
}
sparkleCount = 0
showSparkles = true
}
// High-Performance Animation Loop
animate {
ambientParticles.foreach { p =>
p.translate(0, 0.5)
val pos = p.position
if (pos.y > cb.y + 500) {
p.setPosition(pos.x, cb.y)
}
}
if (showSparkles) {
sparkleCount += 1
sparks.foreach { s =>
s.translate((math.random() - 0.5) * 8, (math.random() - 0.5) * 8)
s.rotate(15)
}
if (sparkleCount > 35) {
sparks.foreach(_.erase())
showSparkles = false
}
}
}
activateCanvas()