normalDraw = { draw: function(){ color("#aaa" ) ctx.fillRect(0, 0, WIDTH, HEIGHT) for(var i = 0; i < HEIGHT; i+=4){ color("#ccc" ) ctx.fillRect(0, i, WIDTH, 2) } // Where each message bottom is let bottomY = HEIGHT/2; for(var i = 0; i < messages.length; i++){ let message = messages[i]; let totalHeigt; switch(message.type){ case 0: color("#111") totalHeigt = roundedRect(0, bottomY, 3, 10); color("#888") roundedRect(1, bottomY-1, 3, 8, true); color("#444") roundedRect(1, bottomY-1, 3, 8); color("#111") font(10, "NANO CHAT", 3, bottomY - totalHeigt + 3) break; case 1: color("#111") totalHeigt = roundedRect(0, bottomY, 3, 10); color("#000") roundedRect(1, bottomY-1, 3, 8, true); color("#444") roundedRect(1, bottomY-1, 3, 8); color("yellow") font(10, "Now entering: ", 3, bottomY - totalHeigt + 3) color("#ccc") font(10, message.text, 85, bottomY - totalHeigt + 3) break; case 2: totalHeigt = drawMessage(0, bottomY, message.from, message.text, message.pixels) break; } bottomY -= totalHeigt; // stop drawing if we are beyond the screen if(bottomY < 0) break; } // Draw current message drawMessage(0, HEIGHT * 3 / 4, username, currentMessageText, currentMessagePixels, true) // Draw send button color("#444") roundedRect(WIDTH - 50, HEIGHT - 48, 3, 39, true, 55) roundedRect(WIDTH - 50, HEIGHT - 2, 3, 39, true, 53) color("#bbb") roundedRect(WIDTH - 49, HEIGHT - 49, 3, 37, true, 55) roundedRect(WIDTH - 49, HEIGHT - 3, 3, 37, true, 55) color("#444") ctx.beginPath() ctx.moveTo(WIDTH - 30, HEIGHT - 62) ctx.lineTo(WIDTH - 30, HEIGHT - 72) ctx.lineTo(WIDTH - 35, HEIGHT - 72) ctx.lineTo(WIDTH - 26, HEIGHT - 82) ctx.lineTo(WIDTH - 17, HEIGHT - 72) ctx.lineTo(WIDTH - 22, HEIGHT - 72) ctx.lineTo(WIDTH - 22, HEIGHT - 62) ctx.fill() let centerX = WIDTH - 26 let centerY = HEIGHT - 30 let radius = 10; for(var i = 0; i < 8; i++){ var x = centerX + Math.cos(Math.PI / 4 * i) * radius var y = centerY + Math.sin(Math.PI / 4 * i) * radius ctx.beginPath() ctx.moveTo(x-1, y-1) ctx.lineTo(x+1, y-1) ctx.lineTo(x+1, y+1) ctx.lineTo(x-1, y+1) ctx.fill() } ctx.fillText("SEND", WIDTH - 39, HEIGHT - 60) ctx.fillText("CLEAR", WIDTH - 41, HEIGHT - 14) drawKeyboard() } } function drawMessage(x, y, from, text, pixels, current=false){ var parts = split_into_parts(text) var trueHeight = Math.max(parts.length, 1) * 14 + 7 if(current || pixels.length != 0){ trueHeight = 91 } color("white") roundedRect(x, y , 3, trueHeight-6, true); color("blue") roundedRect(x, y , 3, trueHeight-6); color("#b3b3ff") roundedRect(x, y - trueHeight + 18 , 3, 12, true, 88); color("blue") roundedRect(x, y - trueHeight + 18, 3, 12, false, 88); font(12, from, 3, y - trueHeight+6) color("black") font(12, text, 3, y - trueHeight+6, true) color("black") for(var i = 0; i < pixels.length; i++){ var pixel = pixels[i] ctx.fillRect(pixel.x, pixel.y + y, 2, 2) } return trueHeight } var capsOn = false var shiftOn = false function drawKeyboard(){ color("#444") roundedRect(1, HEIGHT - 1, 3, HEIGHT/4 - 10, true, WIDTH-52) color("#bbb") roundedRect(2, HEIGHT - 2, 3, HEIGHT/4 - 12, true, WIDTH-54) ctx.font = 12 + "px Mono"; var keys = [ ["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "-", "="], ["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"], ["a", "s", "d", "f", "g", "h", "j", "k", "l"], ["z", "x", "c", "v", "b", "n", "m", ",", ".", "/"] ] var d1 = Math.floor( (WIDTH-54) / 12) - 1 var d2 = Math.ceil( (WIDTH-54) / 12) - 1 for(var j = 0; j < keys.length; j++){ var x = 6 + 8*j var y = HEIGHT / 4 * 3 + 5 + (d1+1)*j for(var i = 0; i < keys[j].length; i++){ color("#ddd") ctx.fillRect(x, y, d1, d1) color("#444") var char = keys[j][i] if(capsOn || shiftOn){ char = char.toUpperCase() } ctx.fillText(char, x + 4, y + 3) x += d2 } } // space color("#ddd") ctx.fillRect(6, HEIGHT - 27, WIDTH-65, 24) color("#444") ctx.fillText("space", 80, HEIGHT-20) ctx.font = 7 + "px Mono"; // shift color("#ddd") ctx.fillRect(6, HEIGHT - 27 - d2, d1+8, d1) color("#444") ctx.fillText("shift", 7, HEIGHT - 22 - d2) // caps color("#ddd") ctx.fillRect(6, HEIGHT - 27 - 2 * d2, d1, d1) color("#444") ctx.fillText("cap", 7, HEIGHT - 22 - 2 * d2) // enter color("#ddd") ctx.fillRect(d1*11+1, HEIGHT - 27 - 2 * d2, d1*2+1, d1) color("#444") ctx.fillText("enter", d1*11+5, HEIGHT - 22 - 2 * d2) // backspace color("#ddd") ctx.fillRect(d1*11.5+1.5, HEIGHT - 27 - 3 * d2, d1+8, d1) color("#444") ctx.fillText("del", d1*11.5+5.5, HEIGHT - 22 - 3 * d2) } function roundedRect(x, y, radius, height, fill = false, width = WIDTH){ ctx.beginPath(); ctx.arc(x + radius, y - radius - height, radius, 3/2 * Math.PI, Math.PI, true) ctx.arc(x + radius, y - radius, radius, Math.PI, 1/2 * Math.PI, true) ctx.arc(x + width - radius, y-radius, radius, 1/2 * Math.PI, 0, true) ctx.arc(x + width - radius, y-radius - height, radius, 0, 3/2 * Math.PI, true) ctx.lineTo(x + radius, y - (radius * 2 ) - height) if(fill){ ctx.fill(); } else { ctx.stroke(); } return radius*2 + height } function color(c) { ctx.fillStyle = c; ctx.strokeStyle = c; } function font(size, what, x, y, wrap = false) { ctx.textBaseline = "top" ctx.font = size + "px Mono"; if(wrap){ var parts = split_into_parts(what, true); parts.forEach((element, i) => { ctx.fillText(element, x, y + i*(size + 2)); }); } else { ctx.fillText(what, x, y); } } function split_into_parts(what, drawing=false){ var parts = []; var line = ""; if(drawing){ line = " " } for(var i = 0; i < what.length; i++){ if(what.charAt(i) == "\n"){ parts.push(line + "\n"); line = "" } else if(line.length == 34){ parts.push(line); line = what.charAt(i); } else { line += what.charAt(i) } if(parts.length == 6){ break; } } if(line.length != 0 && parts.length < 6){ parts.push(line) } return parts; }