Canvas Final Project
The assignment was to create a piece of art using html, through Adobe Dreamweaver. When beginning this project, I was not sure where to start, however I decided to make a piece that reminded me of being a kid. The piece I created was from the show Avatar. I created Avatar Aang, with Momo on his head. When figuring out how I wanted it to look, I took inspiration from a Pop-Toy, which I had come across online.
While I love making digital art, I found using html to be very frustrating. In past projects I have worked on using illustrator or photoshop, it is easier to make shapes and manipulate them the way that I want them to look, by clicking and dragging or drawing. With html, I found myself doing, undoing, and guessing for a lot of my design. The project consisted of a lot of trial and error, until I was able to find something I was happy with.
When designing the piece, I wanted to follow the shape of the toy, as best I could. I ran into trouble when trying to create a rounded square face for Aang and Momo. What I ended up doing was adding an outline to Aang’s face, and rounding the line join. The toughest part was getting the ears where I wanted them. I used the code from a heart that I made for H3, and manipulated the positions until I got the visible part to where I wanted it. If you look behind the face, it is kind of a mess. I also tried to make the eyebrows curved using Bezier curves and connecting them. I ended up having a lot of trouble getting them to line up right, so I ended up settling on using 2 lines.
For the background, I wanted to keep it simple, while still relating to the show. In the show Aang is the Avatar, which means he can bend all four elements (earth, air, fire, water). Each of those elements has their own colors, which I used as the background, adding a gradient to each to make it a little more complicated. I also added the repeating Bezier curves over the top, to add more effects, to make it look less bland.
Overall, the experience of using Dreamweaver was an interesting one. It was cool to learn a new way to make art, and though it was frustrating, I enjoyed seeing my idea come to life as I pushed through the tough parts. What made my piece successful was using creativity to solve problems. Like using the line join to create a more curved square face, or using a triangle to create the dip in Momo’s face. I also think that it was successful because I used the color picker tool in photoshop to get the exact skin color of the Pop-Toy, which allowed me to more accurately recreate the toy.
Time Spent: 7 hours
My 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="800" height="600"></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 grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(36,114,219,1.00)");
grd.addColorStop(1, "white");
context.fillStyle = grd;
context.fillRect(0, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(255,255,255,0.40)");
grd.addColorStop(1, "rgba(36,114,219,1.00)");
context.fillStyle = grd;
context.fillRect(0, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(232,237,27,1.00)");
grd.addColorStop(1, 'white');
context.fillStyle = grd;
context.fillRect(600, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, 'rgba(255,255,255,0.40)');
grd.addColorStop(1, 'rgba(232,237,27,1.00');
context.fillStyle = grd;
context.fillRect(600, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(211,12,12,1.00)");
grd.addColorStop(1, 'white');
context.fillStyle = grd;
context.fillRect(200, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, 'rgba(246,246,246,.40)');
grd.addColorStop(1, 'rgba(211,12,12,1.00)');
context.fillStyle = grd;
context.fillRect(200, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(11,211,94,1.00)");
grd.addColorStop(1, 'white');
context.fillStyle = grd;
context.fillRect(400, 0, 200, 600);
var grd = context.createLinearGradient(0, 0, 0, 350);
grd.addColorStop(0, "rgba(255,255,255,0.40)");
grd.addColorStop(1, 'rgba(11,211,94,1.00)');
context.fillStyle = grd;
context.fillRect(400, 0, 200, 600);
////// BEZIER CURVE 1 on right side
for (var i=0; i<canvas.height; i+=10) {
var startX = 3;
var startY = 800;
// starting point coordinates
var endX = 1000;
var endY = i;
var cpoint1X = canvas.width;
var cpoint1Y = canvas.height;
var cpoint2X = i;
var cpoint2Y = 275;
context.beginPath();
context.moveTo(startX, startY); ///cpoint1Y
context.bezierCurveTo(cpoint1X, cpoint1Y , cpoint2X, cpoint2Y, endX, endY);
context.lineWidth = 1;
context.strokeStyle = "rgba(112,112,112,.5)";
context.stroke();
}
/////// BEZIER CURVE 2 middle
for (var i=0; i<canvas.height; i+=10) {
var startX = 50;
var startY = +800;
// starting point coordinates
var endX = i;
var endY = -1000;
var cpoint1X = canvas.width;
var cpoint1Y = canvas.height;
var cpoint2X = i;
var cpoint2Y = 175;
context.beginPath();
context.moveTo(startX, startY); ///cpoint1Y
context.bezierCurveTo(cpoint1X, cpoint1Y , cpoint2X, cpoint2Y, endX, endY);
context.lineWidth = 2;
context.strokeStyle = "rgba(255,255,255,.5)";
context.stroke();
}
/////// BEZIER CURVE 3 left side
for (var i=0; i<canvas.height; i+=10) {
var startX = -3;
var startY = 800;
// starting point coordinates
var endX = -1000;
var endY = -i;
var cpoint1X = canvas.width;
var cpoint1Y = canvas.height;
var cpoint2X = i;
var cpoint2Y = 275;
context.beginPath();
context.moveTo(startX, startY); ///cpoint1Y
context.bezierCurveTo(cpoint1X, cpoint1Y , cpoint2X, cpoint2Y, endX, endY);
context.lineWidth = 1;
context.strokeStyle = "rgba(0,0,0,.5)";
context.stroke();
}
//MOMO
//Tail
//Bezier Curve
var x1 = 275;
var y1 = 75;
context.beginPath();
context.moveTo(375, 150);
context.bezierCurveTo(200, 150, 450, 70, x1, y1);
context.lineWidth = 6;
context.strokeStyle = "rgba(251,245,215,1.00)";
context.lineCap = 'round'
context.stroke();
//Ears
//Triangle
context.beginPath();
context.moveTo(300,5);
context.lineTo(370, 80);
context.lineTo(350,110);
context.closePath();
context.lineWidth = 10;
context.lineJoin = "round";
context.strokeStyle = "rgba(251,245,215,1.00)";
context.stroke();
context.fillStyle = "rgba(97,66,5,1.00)";
context.fill();
//Triangle
context.beginPath();
context.moveTo(500,5);
context.lineTo(430, 80);
context.lineTo(450,110);
context.closePath();
context.lineWidth = 10;
context.lineJoin = "round";
context.strokeStyle = "rgba(251,245,215,1.00)";
context.stroke();
context.fillStyle = "rgba(97,66,5,1.00)";
context.fill();
//Body
//Rectangle
var x=360;
var y=75;
var width = 80
var height= 120;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
context.fillStyle = 'rgba(251,245,215,1.00)';
context.strokeStyle = 'rgba(115,197,232,0.00)';
context.fill();
context.stroke();
//Neck
//Triangle
context.beginPath();
context.moveTo(420,130);
context.lineTo(400, 130);
context.lineTo(410,140);
context.closePath();
context.lineWidth = 5;
context.lineJoin = "round";
context.strokeStyle = "rgba(97,66,5,1.00)";
context.stroke();
context.fillStyle = "rgba(97,66,5,1.00)";
context.fill();
//Triangle
context.beginPath();
context.moveTo(380,130);
context.lineTo(400, 130);
context.lineTo(390,140);
context.closePath();
context.lineWidth = 5;
context.lineJoin = "round";
context.strokeStyle = "rgba(97,66,5,1.00)";
context.stroke();
context.fillStyle = "rgba(97,66,5,1.00)";
context.fill();
//Head
//Square
var x=350;
var y=30;
var width = 100
var height= 100;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
context.fillStyle = 'rgba(251,245,215,1.00)';
context.strokeStyle = 'rgba(115,197,232,0.00)';
context.fill();
context.stroke();
//Square
var x=360;
var y=50;
var width = 80
var height= 75;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
context.fillStyle = 'rgba(87,44,12,1.00)';
context.strokeStyle = 'rgba(115,197,232,0.00)';
context.fill();
context.stroke();
//Triangle
context.beginPath();
context.moveTo(390,50);
context.lineTo(410, 50);
context.lineTo(400,65);
context.closePath();
context.lineWidth = 5;
context.lineJoin = "round";
context.strokeStyle = "rgba(251,245,215,1.00)";
context.stroke();
context.fillStyle = "rgba(251,245,215,1.00)";
context.fill();
//Eyes
//Circle
context.beginPath();
context.arc(380, 85, 10, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =10;
context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke();
//Circle
context.beginPath();
context.arc(420, 85, 10, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =10;
context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke();
//Nose
//Triangle
context.beginPath();
context.moveTo(395,105);
context.lineTo(405, 105);
context.lineTo(400,110);
context.closePath();
context.lineWidth = 5;
context.lineJoin = "round";
context.strokeStyle = "rgba(0,0,0,1.00)";
context.stroke();
context.fillStyle = "rgba(0,0,0,1.00)";
context.fill();
//AANG
//Ear L
//Heart/bezier curve
var Ax = 300;
var Ay = 500;
var Bx = 250;
var By = 525;
var control1x = 300;
var control1y = 125;
var control2x = -75;
var control2y = 350;
var control3x = 500;
var control3y = 300;
var control4x = 300;
var control4y = 125;
context.beginPath();
context.moveTo(Ax, Ay);
context.bezierCurveTo(control1x, control1y, control2x, control2y, Bx, By);
context.bezierCurveTo(control3x, control3y, control4x, control4y, Ax, Ay);
context.lineWidth = 15;
// line color
context.strokeStyle = 'rgba(220,190,118,1.00)';
context.lineCap = 'square';
context.stroke();
context.fillStyle = 'rgba(220,190,118,1.00)';
context.fill();
//Ear R
//Heart/Bez curve
var Ax = 550;
var Ay = 500;
var Bx = 500;
var By = 550;
var control1x = 400;
var control1y = 125;
var control2x = -125;
var control2y = 275;
var control3x = 900;
var control3y = 400;
var control4x = 500;
var control4y = 125;
context.beginPath();
context.moveTo(Ax, Ay);
context.bezierCurveTo(control1x, control1y, control2x, control2y, Bx, By);
context.bezierCurveTo(control3x, control3y, control4x, control4y, Ax, Ay);
context.lineWidth = 15;
// line color
context.strokeStyle = 'rgba(220,190,118,1.00)';
context.lineCap = 'square';
context.stroke();
context.fillStyle = 'rgba(220,190,118,1.00)';
context.fill();
//Face (square)
var x=200;
var y=175;
var width = 400
var height= 400;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
context.lineJoin = "round";
context.fillStyle = 'rgba(225,201,142,1.00)';
context.strokeStyle = 'rgba(225,201,142,1.00)';
context.fill();
context.stroke();
//Arrow
//Rectangle
var x=350;
var y=175;
var width = 100
var height= 150;
context.beginPath();
context.rect(x, y, width, height);
context.lineWidth = 0;
context.fillStyle = 'rgba(115,197,232,1.00)';
context.strokeStyle = 'rgba(115,197,232,1.00)';
context.fill();
context.stroke();
//Triangle
context.beginPath();
context.moveTo(300,275);
context.lineTo(500, 275);
context.lineTo(400,375);
context.closePath();
context.lineWidth = 25;
context.lineJoin = "round";
context.strokeStyle = "rgba(115,197,232,1.00)";
context.stroke();
context.fillStyle = "rgba(115,197,232,1.00)";
context.fill();
//Eye L
//Circle
context.beginPath();
context.arc(275, 450, 40, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =10;
context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke();
//Eye R
//circle
context.beginPath();
context.arc(525, 450, 40, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =10;
context.strokeStyle = 'rgba(2,2,2,1.00)';
context.stroke();
//Eye Brow L
//Line
context.moveTo(225,380);
context.lineTo(325,410);
context.lineWidth = 10;
context.stroke();
//Eye Brow R
//Line
context.moveTo(575,380);
context.lineTo(475,410);
context.lineWidth = 10;
context.stroke();
//Nose
//Quad Curve
var x = 385;
var y = 500;
// control point coordinates ( magnet )
var cpointX = canvas.width / 2 ;
var cpointY = canvas.height / 2 + 150;
// ending point coordinates
var x1 = 415;
var y1 = 500;
context.beginPath();
context.moveTo(x, y);
context.quadraticCurveTo(cpointX, cpointY, x1, y1);
context.lineWidth = 5;
context.strokeStyle = "rgba(248,253,193,0.51)";
context.stroke();
//Mouth
//quad curve
var x = 390;
var y = 565;
// control point coordinates ( magnet )
var cpointX = canvas.width / 2 + 20;
var cpointY = canvas.height / 2 + 200;
// ending point coordinates
var x1 = 460;
var y1 = 535;
context.beginPath();
context.moveTo(x, y);
context.quadraticCurveTo(cpointX, cpointY, x1, y1);
context.lineWidth = 5;
context.strokeStyle = "rgba(215,157,72,1.00)";
context.stroke();
var centerX = 445;
var centerY = 560
var radius = 10;
var startangle = 0* Math.PI;;
var endangle = .5* Math.PI;
context.beginPath();
context.arc(centerX, centerY, radius, startangle, endangle, false);
context.fillStyle = "rgba(0,0,255,0.00)";
context.fill();
context.lineWidth = 5;
context.strokeStyle = "rgba(255,234,156,1.00)";
context.stroke();
//Nostril
//Circle
context.beginPath();
context.arc(395, 500, .5, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =5;
context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke();
//Circle
context.beginPath();
context.arc(405, 500, .5, 0 , 2* Math.PI, true);
context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
context.lineWidth =5;
context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke();
//Square, rectangle, triangle, gradient, circle, line, quad curve, bezier curve, heart, Repear curves, Arc
// <<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE
///////////////////////////////////////////////////////////////////
// CREDITS
context.save();
var credits = "Ben Bickerstaff, Canvas, FMX 210, SP 2022";
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 = 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>
The way you did Momo worked really well. It is very geometric in a very stylized way and maintains the details. Very well done
ReplyDeleteAppreciate it. That was one of my favorite parts of the project.
Delete