Blake Gottlieb
Html5 Canvas
For this html5 canvas experiment I drew inspiration from a favorite album cover design from my childhood, the Kanye West Graduation album cover. This is an album cover that I think is very well put together aesthetically and has a lot to interpret. I like to think that the bear is being sent to a new platform and everyone else in the picture is celebrating his success. In addition to being interested in the visual aspects, I also have been a big fan of the artist Kanye West, listening to his music for years.
For my project, I wanted to interpret the album cover in a more simplistic approach. I wanted to show the bear post graduation in the working world, but still holding on to what got him there. Whether this be a symbolic representation, or a physical representation through the graduation cap. I am fairly pleased with my work for my first ever coding project. I like the symmetry and perfectly straight lines, especially in the neck down portion. I also really like the ears on the bear. I created these by making circles and adjusting the angles on the starting and ending points to make semi circles that fit the head shape. A couple of things I would have liked to experiment with more are colors and curves. However, my lack of coding knowledge and experience limited my artistic capabilities. Overall, I am pleased with my persistence with all the issues that came up while working on this project. I am proud of my work with curves and symmetry. As well as creating a meaningful interpretative image.
Inspiration:
Canvas:
Hours worked on: 15-20 hours
657 lines of code
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="600" height="800"></canvas>
<div id="display"></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 x = 0;
var y = 0;
var width = canvas.width;
var height = canvas.height;
var centerX = 300;
var centerY = 400;
var radius = 200;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
var gradient1 = context.createLinearGradient(0, 0, 100, 0);
gradient1.addColorStop(0, 'rgba(0, 0, 0, 1)');
gradient1.addColorStop(1, 'rgba(128, 0, 0, 0.9)');
context.fillStyle = gradient1;
context.fill();
context.strokeStyle = 'rgba(0, 0, 0, 1)'; //outline
context.stroke();
context.closePath();
//grad cap top
context.moveTo(200,100); // COORDINATES OF STARTING POINT (left)
context.lineTo(300,170); // COORDS OF ENDING POINT 1 (down)
//context.moveTo(300,160); // COORDINATES OF STARTING POINT (bottom right)
context.lineTo(400,100); // COORDS OF POINT 2 (right)
context.lineTo(300,30); // COORDS OF POINT 3 (up)
context.lineTo(200,100); // COORDS OF POINT 4 (connect left)
context.lineWidth = 4; // STROKE WIDTH
context.lineCap = 'round'
context.strokeStyle = 'rgba(0, 0, 0, 0)'; //outline
context.stroke(); // STROKE
context.fillStyle = 'rgba(0,191,255,.5)'; //blue
context.fill ();
context.closePath();
//grad cap bottom
var centerX = 300;
var centerY = 180
var radius = 56;
var startangle = .9* Math.PI;; // left
var endangle = .1* Math.PI; // right
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 5;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(210,180,140,1)';
context.fill ();
context.closePath();
// left ear (outter)
var centerX = 216;
var centerY = 218
var radius = 20;
var startangle = 1.75* Math.PI;; // right
var endangle = .7* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, true);
context.lineWidth = 2;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(210,105,30,1)'; //chocolate
context.fill ();
context.closePath();
// left ear (inner)
var centerX = 216;
var centerY = 218
var radius = 15;
var startangle = 1.75* Math.PI;; // right
var endangle = .7* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, true);
context.lineWidth = 2;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,0.3)';
context.fill ();
context.closePath();
// right ear (outter)
var centerX = 382;
var centerY = 222
var radius = 20;
var startangle = 1.3* Math.PI;; // right
var endangle = .25* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 2;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(210,105,30,1)'; //chocolate
context.fill ();
context.closePath();
// right ear (inner)
var centerX = 382;
var centerY = 222
var radius = 15;
var startangle = 1.3* Math.PI;; // right
var endangle = .25* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 2;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,0.3)';
context.fill ();
context.closePath();
//head top
var centerX = 300;
var centerY = 290
var radius = 110;
var startangle = 1* Math.PI;; // left
var endangle = 0* Math.PI; // right
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.moveTo(411,293);
context.lineWidth = 0;
// context.strokeStyle = 'rgba(255,255,255,0)';
// context.stroke();
context.fillStyle = 'rgba(244,164,96, 1)'; //sandy brown (actually copied body color)
context.fill ();
context.closePath();
//body
context.moveTo(150,440); // COORDINATES OF STARTING POINT (left)
context.lineTo(150,510); // COORDS OF ENDING POINT 1 (down)
context.lineTo(300,640); // COORDS OF POINT 2
context.lineTo(450,510); // COORDS OF POINT 3
context.lineTo(450,440); // COORDS OF POINT 4
context.lineTo(300,375); // COORDS OF POINT 5
context.lineTo(150,440); // COORDS OF POINT 6
context.lineWidth = 3; // STROKE WIDTH
context.strokeStyle = 'rgba(255,255,255,0)';
context.stroke(); // STROKE
context.fillStyle = 'rgba(210,105,30,1)'; //chocolate
context.fill ();
context.closePath();
// name tag
var x=230;
var y=420;
var width = 30
var height= 15;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 5;
context.fillStyle = 'rgba(255,255,255,1)';
//context.strokeStyle = 'rgba(0,0,0,1)';
context.fill();
//context.stroke();
/// cheeks (figure out why collar is causing stroke/outline)
context.beginPath();
context.moveTo(190,290);
context.quadraticCurveTo(40,375,290,360);
context.quadraticCurveTo(560,365,410,290);
context.lineWidth = 0;
//context.strokeStyle = 'rgba(0,0,0,0)';
//context.stroke();
context.fillStyle = 'rgba(210,105,30,1)'; //sandy brown
context.fill ();
context.closePath();
//tie (figure out why collar is causing stroke/outline)
context.beginPath();
context.moveTo(285,393); // COORDINATES OF STARTING POINT (left)
context.lineTo(285,480); // COORDS OF ENDING POINT 1 (down)
context.lineTo(300,520); // COORDS OF POINT 2
context.lineTo(315,480); // COORDS OF POINT 3
context.lineTo(315,393); // COORDS OF POINT 4
context.lineWidth = 1; // STROKE WIDTH
context.strokeStyle = 'rgba(255,255,255,1.00)';
context.stroke(); // STROKE
context.closePath();
//collar** stroke style effects tie and cheeks
context.beginPath();
context.moveTo(270,365); // COORDINATES OF STARTING POINT (left)
context.lineTo(270,410); // COORDS OF ENDING POINT 1 (down)
context.lineTo(300,375); // COORDS OF POINT 2
context.lineTo(330,410); // COORDS OF POINT 3
context.lineTo(330,365); // COORDS OF POINT 4
//context.lineTo(270,365); // COORDS OF POINT 5
context.lineWidth = 1; // STROKE WIDTH
context.strokeStyle = 'rgba(255,255,255,1)';
context.stroke(); // STROKE
context.closePath();
// mouth
context.beginPath();
context.moveTo(300,340);
context.quadraticCurveTo(240,346,266,310);
context.quadraticCurveTo(295,277,320,305);
context.quadraticCurveTo(355,346,300,340);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.fillStyle = 'rgba(210,180,140,1)'; //tan
context.fill ();
context.stroke();
//nose
var centerX = 295;
var centerY = 305
var radius = 13;
var startangle = 1* Math.PI;; // left
var endangle = 0* Math.PI; // right
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, true);
context.moveTo(283,305); // COORDINATES OF STARTING POINT (left)
context.lineTo(308,305); // COORDS OF ENDING POINT 1 (right)
context.lineWidth = 1.5;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(139,69,19,1)'; //saddle brown
context.fill ();
context.closePath();
// nose (nostrail right)
var centerX = 300;
var centerY = 309
var radius = 2.5;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 4;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,.6)';
context.fill ();
context.closePath();
// nose (nostrail left)
var centerX = 292;
var centerY = 309
var radius = 2.5;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 4;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,.6)';
context.fill ();
context.closePath();
// left eye (outter)
var centerX = 265;
var centerY = 240
var radius = 19;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(152,251,152,1)';
context.fill ();
context.closePath();
// left eye (inner)
var centerX = 265;
var centerY = 240
var radius = 10;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(255,255,255,1)';
context.fill ();
context.closePath();
// left eye (most inward)
var centerX = 265;
var centerY = 240
var radius = 5;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,1)';
context.fill ();
context.closePath();
// right eye (outter)
var centerX = 335;
var centerY = 240
var radius = 19;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(152,251,152, 1)';
context.fill ();
context.closePath();
// right eye (inner)
var centerX = 335;
var centerY = 240
var radius = 10;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(255,255,255, 1)';
context.fill ();
context.closePath();
// right eye (most inward)
var centerX = 335;
var centerY = 240
var radius = 5;
var startangle = 0* Math.PI;; // right
var endangle = 2* Math.PI; // left
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.lineWidth = 3;
context.strokeStyle = 'rgba(0, 0, 0, 0)';
context.stroke();
context.fillStyle = 'rgba(0,0,0,.8)';
context.fill ();
context.closePath();
// <<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE
///////////////////////////////////////////////////////////////////
// CREDITS
context.save();
var credits = "Blake Gottlieb, Canvas, FMX 210, SP 2020";
context.font = 'bold 12px Helvetica';
context.fillStyle = "rgba(0,0,0,1)"; // change the color here
context.shadowColor = "rgba(255,255,255,1)"; // 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 = mouseX + " || " + mouseY + " || counter = " + Math.round(counter);
/////////////////////////////////////////////////////////////////
// LAST LINE CREATES THE ANIMATION
requestAnimFrame(draw); // CALLS draw() every nth of a second
}
</script>
</body>
</html>