Thanks for all the nice compliments and helpful criticisms about my canvas project! I tried to remember all the criticisms you guys had and attempted to make those changes to my project. I don't know if I got them all, but the ones I did are:
(1) making the horizon line stroke thicker to match my other lines
(2) changing the gradient order so it moves from dark to light starting from the horizon
(3) adding more subtle gradient changes for the cool-toned section so it flows/blends more
(4) moving the horizon line upward so that it doesn't line up with the neck/face line
I really like the newer version, so thank you for helping me clean up my work and make it better! :)
![]() |
After |
![]() |
Before |
New code:
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title> -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- </title>
<!-- import external .js scripts here -->
<!-- <script type="text/javascript" src="#" ></script> -->
<!-- modify CSS properties here -->
<style type="text/css">
body,td,th {
font-family: Monaco, "Courier New", "monospace";
font-size: 14px;
color: rgba(255,255,255,1);
}
body {
background-color: rgba(0,0,0,1);
}
#container {
position: relative;
text-align: left;
width: 95%;
height: 800px;
}
#fmxCanvas {
position: relative;
background-color:rgba(255,255,255,1);
border: rgba(255,255,255,1) thin dashed;
cursor: crosshair;
display: inline-block;
}
</style>
</head>
<body>
<div id="container">
<!-- START HTML CODE HERE -->
<canvas id="fmxCanvas" width="400" height="550"></canvas>
<div></div>
<!-- FINISH HTML CODE HERE -->
</div>
<script>
///////////////////////////////////////////////////////////////////////
// DECLARE requestAnimFrame
var rAF = window.requestAnimFrame ||
window.mozRequestAnimFrame ||
window.webkitRequestAnimFrame ||
window.msRequestAnimFrame;
var fps = 30;
window.requestAnimFrame = (
function(callback) {
return rAF ||
function(callback) {
window.setTimeout(callback, 1000 / fps);
};
})();
///////////////////////////////////////////////////////////////////////
// DEFINE GLOBAL VARIABLES HERE
var canvas;
var context;
canvas = document.getElementById("fmxCanvas");
context = canvas.getContext("2d");
var canvas1;
var context1;
canvas1 = document.createElement("canvas");
context1 = canvas1.getContext("2d");
canvas1.width = canvas.width;
canvas1.height = canvas.height;
var display;
display = document.getElementById('display');
var counter;
///////////////////////////////////////////////////////////////////////
// DEFINE YOUR GLOBAL VARIABLES HERE
///////////////////////////////////////////////////////////////////////
// CALL THE EVENT LISTENERS
window.addEventListener("load", setup, false);
//////////////////////////////////////////////////////////////////////
// ADD EVENT LISTENERS
canvas.addEventListener("mousemove", mousePos, false);
//////////////////////////////////////////////////////////////////////
// MOUSE COORDINATES
var stage, mouseX, mouseY;
function mousePos(event) {
stage = canvas.getBoundingClientRect();
mouseX = event.clientX - stage.left;
mouseY = event.clientY - stage.top;
}
/////////////////////////////////////////////////////////////////////
// INITIALIZE THE STARTING FUNCTION
function setup() {
/////////////////////////////////////////////////////////////////////
// DECLARE STARTING VALUES OF GLOBAL VARIABLES
counter = 0;
mouseX = canvas.width/2;
mouseY = canvas.height/2;
/////////////////////////////////////////////////////////////////////
// CALL SUBSEQUENT FUNCTIONS, as many as you need
clear(); // COVER TRANSPARENT CANVAS OR CLEAR CANVAS
draw(); // THIS IS WHERE EVERYTHING HAPPENS
}
////////////////////////////////////////////////////////////////////
// CLEAR THE CANVAS FOR ANIMATION
// USE THIS AREA TO MODIFY BKGD
function clear() {
context.clearRect(0,0,canvas.width, canvas.height);
context1.clearRect(0,0,canvas.width, canvas.height);
// clear additional contexts here if you have more than canvas1
}
////////////////////////////////////////////////////////////////////
// THIS IS WHERE EVERYTHING HAPPENS
function draw() {
counter += 0.1; // EASIER FOR SINE COSINE FUNCTIONS
if (counter > Math.PI*200) { counter = 0; } // RESET COUNTER
clear(); // USE THIS TO REFRESH THE FRAME AND CLEAR CANVAS
////////////////////////////////////////////////////////////////////
// >>>START HERE>>>START HERE>>>START HERE>>>START HERE>>>START HERE
//background
var mygrad = context.createLinearGradient (200,0,200,550);
mygrad.addColorStop (0, "#FF9826");
mygrad.addColorStop (0.65, "#D00000");
mygrad.addColorStop (0.65, "#00009B");
mygrad.addColorStop (0.88, "#49D36A");
mygrad.addColorStop (0.99, "#EEE351");
context.rect (0,0,400,550);
context.fillStyle = mygrad;
context.fill();
context.strokeStyle = "black"
context.stroke();
//horizone
context.beginPath ();
context.moveTo (0,358);
context.lineTo (400,358);
context.lineWidth = 4;
context.strokeStyle = "black"
context.stroke();
//left side of hair
context.beginPath ();
context.moveTo (70,90);
context.quadraticCurveTo (20,165,40,200);
context.quadraticCurveTo (20,225,40,250);
context.quadraticCurveTo (20,275,40,300);
context.quadraticCurveTo (20,325,40,350);
context.quadraticCurveTo (20,375,40,400);
context.quadraticCurveTo (20,425,50,450);
context.lineTo (145,380);
context.lineTo (230,380);
context.lineJoin = "round"
context.closePath ();
context.lineWidth = 5;
context.fillStyle = "rgba(0,0,0,1.00)"
context.fill();
context.strokeStyle = "white"
context.stroke();
// right side of hair
context.beginPath ();
context.moveTo (327,90);
context.quadraticCurveTo (360,115,335,150);
context.quadraticCurveTo (360,180,335,210);
context.quadraticCurveTo (360,235,335,265);
context.quadraticCurveTo (360,290,335,320);
context.quadraticCurveTo (360,345,335,375);
context.quadraticCurveTo (360,400,335,440);
context.lineTo (230,380);
context.lineTo (230,90);
context.lineWidth = 5;
context.fillStyle = "rgba(0,0,0,1.00)"
context.fill();
context.strokeStyle = "white"
context.stroke();
// right side of face color
context.beginPath ();
context.moveTo (280,90);
context.bezierCurveTo (300,230,280,350,230,380);
context.lineTo (190,270);
context.lineTo (170,90);
context.closePath ();
context.fillStyle = "rgba(3,208,128,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
//lips
context.beginPath ();
context.moveTo (200,270);
context.lineTo (145,380);
context.lineTo (235,380);
context.lineTo (220,355);
context.lineTo (240,330);
context.lineTo (220,315);
context.lineTo (245,300);
context.lineJoin = "round"
context.closePath ();
context.lineWidth = 5;
context.fillStyle = "rgba(23,21,223,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
//left side of neck
context.beginPath();
context.moveTo (120,260);
context.quadraticCurveTo (168,320,145,380);
//context.lineTo (160,320);
context.lineTo (200,270);
context.lineJoin = "round"
context.closePath ();
context.lineWidth = 5;
context.fillStyle = "rgba(53,163,79,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// triangle right of nose
context.beginPath ();
context.moveTo (200,270);
context.lineTo (285,215);
context.lineTo (170,155);
context.lineJoin = "round"
context.closePath ();
context.lineWidth = 5;
context.fillStyle = "rgba(24,172,196,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// right eye
context.beginPath ();
context.rect (218,155,55,25);
context.closePath ();
context.fillStyle = "rgba(249,239,239,1.00)"
context.fill();
context.lineWidth = 4;
context.strokeStyle = "black"
context.stroke();
// right eye iris
context.beginPath ();
context.rect (236,155,18,25);
context.closePath ();
context.fillStyle = "rgba(40,78,114,1.00)"
context.fill();
context.lineWidth = 4;
context.strokeStyle = "black"
context.stroke();
//right pupil
context.beginPath ();
context.rect (243,162,5,10);
context.closePath ();
context.fillStyle = "rgba(0,0,0,1.00)"
context.fill();
context.lineWidth = 4;
context.strokeStyle = "black"
context.stroke();
// ear outside
context.beginPath ();
context.moveTo (288,150);
context.bezierCurveTo (325,160,325,225,286,250);
context.fillStyle = "rgba(4,29,110,1.00)"
context.fill();
context.lineWidth = 6;
context.strokeStyle = "black"
context.stroke();
// inside of ear
context.beginPath ();
context.moveTo (285,170);
context.bezierCurveTo (305,160,305,225,285,230);
context.lineWidth = 6;
context.fillStyle = "rgba(143,212,227,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// right side of face outline
context.beginPath ();
context.moveTo (280,90);
context.bezierCurveTo (300,230,280,350,230,380);
context.lineWidth = 6;
context.strokeStyle = "black"
context.stroke();
//left side of face outline
context.beginPath ();
context.bezierCurveTo (148,270,10,250,60,90); // curve of cheek
context.lineTo (150,150);
context.lineWidth = 6;
context.fillStyle = "rgba(93,188,210,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// nose and forehead
context.beginPath ();
context.moveTo (282,115);
context.lineTo (190,115);
context.lineTo (200,270);
context.lineTo (145,270);
context.lineTo (150,150);
context.lineTo (60,90);
context.lineJoin = "round"
context.lineTo (278,90);
context.lineWidth = 5;
context.fillStyle = "rgba(0,47,132,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// left eye outline
context.beginPath ();
context.moveTo (110,115);
context.quadraticCurveTo (145,90,175,115);
context.quadraticCurveTo (150,140,110,115);
context.lineWidth = 4;
context.fillStyle = "rgba(249,239,239,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
//left eye iris
context.beginPath ();
context.arc (144,115,10,0,2*Math.PI,false);
context.lineWidth = 3;
context.fillStyle = "rgba(134,221,98,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
//left eye pupil
context.beginPath ();
context.arc (144,115,2,0,2*Math.PI,false);
context.lineWidth = 4;
context.strokeStyle = "black"
context.stroke();
//crown
context.beginPath ();
context.moveTo (60,90);
context.lineTo (327,90);
context.lineTo (327,25);
context.lineTo (300,50);
context.lineTo (250, 25);
context.lineTo (200, 50);
context.lineTo (150,25);
context.lineTo (100,50);
context.lineTo (60,25);
context.closePath ();
context.lineWidth = 6;
context.fillStyle = "rgba(22,51,93,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// crown line
context.beginPath ();
context.rect (60,65,267,12);
context.lineWidth = 4;
context.closePath();
context.fillStyle = "rgba(148,189,215,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// dark red shoulder
context.beginPath();
context.moveTo (260,378);
context.lineTo (339, 425);
context.lineJoin = "round"
context.lineTo (180,433);
context.closePath();
context.lineWidth = 6;
context.fillStyle = "rgba(166,2,3,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// trapazoid under red triangle
context.beginPath();
context.moveTo (339, 425);
context.lineTo (450,560);
context.lineTo (320,560);
context.lineTo (219,427);
context.closePath ();
context.lineWidth = 6;
context.fillStyle = "rgba(216,153,7,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// peach traingle next to red triangle
context.beginPath();
context.moveTo (219,429); // top of traingle
context.lineJoin = "round"
context.lineTo (219, 560); // left side of triangle
context.lineTo(320,560); // hypothanous of triangle
context.closePath();
context.lineWidth = 6;
context.fillStyle = "rgba(223,89,27,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// light yellow triangle
context.beginPath();
context.moveTo (180,433);
context.lineTo (260,378);
context.lineTo (115,378);
context.closePath();
context.lineWidth = 6;
context.fillStyle = "rgba(225,202,58,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// orangish shape next to semi cirlce
context.beginPath();
context.moveTo (180,433);
context.lineTo (115,378);
context.bezierCurveTo (20,430,10,550,110,600); // curve of circle
context.closePath();
context.lineWidth = 7;
context.fillStyle = "rgba(219,112,12,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// light brown small traingle
context.beginPath();
context.moveTo (126,600); //begining of triangle
context.lineTo (215,600);
context.lineTo (125,511);
context.closePath();
context.lineWidth = 4;
context.fillStyle = "rgba(170,121,42,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// yellowish semi circle
context.beginPath();
context.moveTo (218,427);
context.bezierCurveTo (150,425,50,525,218,600); // curve of circle
context.closePath();
context.lineWidth = 6;
context.fillStyle = "rgba(233,173,5,1.00)"
context.fill();
context.strokeStyle = "black"
context.stroke();
// <<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE
///////////////////////////////////////////////////////////////////
// CREDITS
context.save();
var credits = "Redieat Abebe, Cubic Queen, FMX 210-1, FA 2020";
context.font = 'bold 12px Helvetica';
context.fillStyle = "rgba(255,255,255,1.00)"; // change the color here
context.shadowColor = "rgba(0,0,0,1.00)"; // change shadow color here
context.shadowBlur = 12;
context.shadowOffsetX = 2;
context.shadowOffsetY = 2;
context.fillText(credits, 10, canvas.height - 10); // CHANGE THE LOCATION HERE
context.restore();
//////////////////////////////////////////////////////////////////
// HTML DISPLAY FIELD FOR TESTING PURPOSES
display.innerHTML = Math.round(mouseX) + " || " + Math.round(mouseY) + " || counter = " + Math.round(counter);
/////////////////////////////////////////////////////////////////
// LAST LINE CREATES THE ANIMATION
requestAnimFrame(draw); // CALLS draw() every nth of a second
}
</script>
</body>
</html>
This comment has been removed by the author.
ReplyDeleteI like how you took the class critique as a good thing and didn't give up. I loved your first version but this one is even better. The gradients make the design tie all together with the colors. I also think the gradients behind the opposite colors bring balance to the design. The use of warm and cool colors in different sections was a great idea! Amazing!!
ReplyDelete