Canvas Project

 For my final canvas project, I decided to create a dolphin jumping out of the water. Bottlenose dolphins are highly intelligent and are able to adapt to their changing environment surprisingly well. As a freshman in college, I was hoping that creating this dolphin would manifest that I too adapt to my changing environment with the same grace and diligence.

This project was difficult because of the amount of bezier and quadratic curves. Luckily, patience is one of my best qualities, but I do have to admit that I cried on three separate occasions while completing my project: once while creating the bottom water splashes, and twice while adding color and attempting to give my dolphin volume. 


Below I will include a picture of my final project, the reference image, and the code used to create it: 




<!doctype html>

<html>

<head>

<meta charset="UTF-8">




<title> dolphin </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>


<img src="dolphin.png" id="dolphin"/>



<!-- 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


var dolphin = new Image();

dolphin= document.getElementById("dolphin");


///////////////////////////////////////////////////////////////////////

// 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

//context.drawImage(dolphin,0,0);

//context.drawImage(dolphin,0,0);

//background 

var mygrad4 =

context.createRadialGradient(217,216,205,71,316,566);

context.beginPath();

mygrad4.addColorStop(0,"rgba(217,166,95,1.00)");

mygrad4.addColorStop(0.01,"rgba(170,116,50,1.00)")

mygrad4.addColorStop(0.25,"rgba(201,146,165,1.00)");

mygrad4.addColorStop(0.75,"rgba(203,110,124,1.00)");

mygrad4.addColorStop(0.75,"rgba(190,123,190,1.00)");

mygrad4.addColorStop(1,"rgba(224,191,110,1.00)");

context.beginPath();

context.rect(0,0,800,600);

context.fillStyle = mygrad4;

context.fill();

context.closePath();

// gradients 

var mygrad1 =

context.createRadialGradient(428,299,205,71,316,566);

context.beginPath();

mygrad1.addColorStop(0,"rgba(36,91,118,1.00)");

mygrad1.addColorStop(0.01,"rgba(16,87,118,1.00)")

mygrad1.addColorStop(0.25,"rgba(38,96,124,1.00)");

mygrad1.addColorStop(0.75,"rgba(66,126,153,1.00)");

mygrad1.addColorStop(0.75,"rgba(23,87,112,1.00)");

mygrad1.addColorStop(1,"rgba(38,99,127,1.00)");

var mygrad2 = 

context.createRadialGradient(410,320,5,365,200,200);

context.beginPath();

mygrad2.addColorStop(0.02,"rgba(213,213,209,1.00)");

mygrad2.addColorStop(0.5,"rgba(174,174,173,1.00)");

mygrad2.addColorStop(0.75,"rgba(209,213,211,1.00)");

var mygrad3 =

context.createLinearGradient(311,139,237,131);

context.beginPath();

mygrad3.addColorStop(0,"rgba(38,100,128,1.00)");

mygrad3.addColorStop(0.02,"rgba(39,97,125,1.00)");

mygrad3.addColorStop(1,"rgba(10,63,89,1.00)");

// tail 

context.beginPath();

context.moveTo(235,225);

context.bezierCurveTo(196,349,217,399,284,476);

context.bezierCurveTo(270,506,280,519,294,531);

context.bezierCurveTo(290,500,296,498,300,497);

context.bezierCurveTo(309,507,332,502,345,519);

context.bezierCurveTo(330,466,325,466,300,466);

context.bezierCurveTo(252,376,271,322,294,283);

context.closePath();


context.fillStyle= mygrad1;

context.fill();

// tail shadow

context.beginPath();

context.moveTo(238,220);

context.bezierCurveTo(197,330,217,399,284,476);


context.bezierCurveTo(190,310,234,199,273,195);

//

context.closePath();

context.fillStyle= "rgba(14,72,95,1.00)";

context.fill();

// shadow two 

context.beginPath();

context.moveTo(294,523);

context.lineTo(283,476);

context.lineTo(300,498);

context.quadraticCurveTo(291,496,294,523);

context.fillStyle= "rgba(13,76,103,1.00)";

context.fill();

//belly 

context.beginPath();

context.moveTo(590,204);

context.bezierCurveTo(495,96,359,199,344,214);

context.bezierCurveTo(179,372,308,449,297,466);

context.lineTo(307,466);

context.bezierCurveTo(250,308,336,242,425,213);

context.bezierCurveTo(530,187,482,195,590,204);

context.fillStyle = mygrad2;

context.fill();

// top fin

context.beginPath();

context.moveTo(349,107);

context.quadraticCurveTo(274,140,241,232);

context.quadraticCurveTo(235,236,234,227);

context.quadraticCurveTo(244,198,255,187);

context.bezierCurveTo(257,122,255,155,219,120);

context.bezierCurveTo(208,100,288,108,349,107);

context.closePath();

context.fillStyle = "rgba(36,92,119,1.00)";

context.fill();

context.lineWidth= 1;


// details/ shadows 

// top fin 

context.beginPath();

context.moveTo(227,112);

context.quadraticCurveTo(228,123,253,127);

context.quadraticCurveTo(256,129,279,149);

context.quadraticCurveTo(295,129,313,129);

context.quadraticCurveTo(260,183,238,233);

context.quadraticCurveTo(231,246,233,232);

context.quadraticCurveTo(240,201,255,187);

context.bezierCurveTo(257,122,255,155,219,120);

context.quadraticCurveTo(218,108,227,112);

context.closePath();

context.fillStyle= "rgba(14,72,95,1.00)";

context.fill();


// bottom fin 2

context.beginPath();

context.moveTo(441,256);

context.quadraticCurveTo(494,238,488,192);

context.quadraticCurveTo(450,189,441,256);

 context.closePath();

context.fillStyle = "rgba(14,72,95,1.00)";

context.fill();

context.lineWidth= 3;

 // bottom fin 1

context.beginPath();

context.moveTo(392,256);

context.bezierCurveTo(381,246,408,241,445,191);

context.quadraticCurveTo(477,180,478,198);

context.quadraticCurveTo(428,254,392,256);

context.closePath();


context.fillStyle = "rgba(38,98,126,1.00)";

context.fill();

context.lineWidth= 3;

 // fin 1 shadow 

context.beginPath();

context.moveTo(397,243);

context.quadraticCurveTo(428,225,449,189);

context.quadraticCurveTo(420,215,397,243);

context.fillStyle= "rgba(14,72,95,1.00)";

context.fill();


 

//head and body 

context.beginPath();

context.moveTo(614,183);

context.bezierCurveTo(608,48,416,70,347,108);

context.quadraticCurveTo(282,134,240,230);

context.quadraticCurveTo(253,261,289,279);

context.bezierCurveTo(387,157,476,140,554,175);

context.bezierCurveTo(544,131,580,154,614,183);

context.closePath();

context.fillStyle = "rgba(37,92,119,1.00)";

context.fill();

// head 

context.beginPath();

context.moveTo(520,83)

context.quadraticCurveTo(606,100,613,174);

context.quadraticCurveTo(539,129,552,173);

context.quadraticCurveTo(345,108,520,83);

context.closePath();

context.fillStyle= "rgba(37,92,119,1.00)";

context.fill();

// head

// head highlight

context.beginPath();

context.moveTo(563,116);

context.quadraticCurveTo(552,62,367,98);

context.quadraticCurveTo(513,75,563,116);

context.closePath();

context.fillStyle= "rgba(60,114,137,1.00)";

context.fill();

//eye 

context.beginPath();

context.arc(539,145,7,0*Math.PI,1*Math.PI,true);

context.arc(539,145,7,1*Math.PI,0*Math.PI,true);

context.fillStyle = "rgba(89,93,95,1.00)";

context.fill();

context.lineWidth= 1;

//bottom beak

context.beginPath();

context.moveTo(626,201);

context.quadraticCurveTo(632,215,592,205);

context.quadraticCurveTo(553,175,551,173);

context.quadraticCurveTo(548,155,555,158);

context.quadraticCurveTo(585,179,620,198);

context.closePath();

context.fillStyle = "rgba(37,92,119,1.00)";

context.fill();


// face shadow 

context.beginPath();

context.moveTo(552,151);

context.lineTo(618,189);

context.quadraticCurveTo(610,150,598,131);

context.quadraticCurveTo(600,154,598,165);

context.quadraticCurveTo(572,145,550,150);

context.closePath();

context.fillStyle= "rgba(14,72,95,1.00)";

context.fill();

// top beak

context.beginPath();

context.moveTo(628,204);

context.bezierCurveTo(612,152,507,142,552,161);

context.quadraticCurveTo(591,188,628,204);


context.closePath();

context.fillStyle = "rgba(37,92,119,1.00)";

context.fill();

// line for mouth 

context.beginPath();

context.moveTo(627,207);

context.quadraticCurveTo(600,193,582,179);

context.strokeStyle= "rgba(58,58,58,1.00)";

context.stroke();

// pupil 

context.beginPath();

context.arc(540,145,5,0.5*Math.PI,1.75*Math.PI,false);

context.arc(540,145,5,1.75*Math.PI,0.75*Math.PI,false);

context.closePath();

context.fillStyle = "rgba(1,1,3,0.83)";

context.fill();

context.lineWidth= 1;

// water splash main 

context.beginPath();

context.moveTo(362,305);

context.bezierCurveTo(312,330,341,360,344,364);

context.bezierCurveTo(361,302,431,322,459,377);

context.bezierCurveTo(460,394,446,405,441,402);

context.bezierCurveTo(455,358,387,310,358,357);

context.quadraticCurveTo(342,404,375,439);

context.quadraticCurveTo(388,402,417,411);

context.bezierCurveTo(424,423,380,424,382,443);

context.quadraticCurveTo(380,455,393,484);

context.quadraticCurveTo(413,456,429,489);

context.quadraticCurveTo(428,498,422,498);

context.quadraticCurveTo(410,468,398,498);

context.quadraticCurveTo(434,584,401,601);

context.lineTo(246,600);

context.quadraticCurveTo(224,571,197,589);

context.quadraticCurveTo(183,578,194,568);

context.quadraticCurveTo(208,546,214,562);

context.bezierCurveTo(245,524,199,442,164,503);

context.quadraticCurveTo(162,510,164,515);

context.quadraticCurveTo(168,519,177,525);

context.quadraticCurveTo(164,542,147,527);

context.bezierCurveTo(128,488,209,412,230,525);

context.quadraticCurveTo(244,526,239,500);

context.quadraticCurveTo(263,518,243,555);

context.quadraticCurveTo(256,600,293,592);

context.bezierCurveTo(261,544,329,514,328,557);

context.quadraticCurveTo(318,541,310,544);

context.bezierCurveTo(280,546,318,635,358,551);

context.bezierCurveTo(361,513,356,528,348,534);

context.bezierCurveTo(360,476,343,482,331,449);

context.lineTo(329,439);

context.quadraticCurveTo(344,459,356,465);

context.quadraticCurveTo(353,412,316,414);

context.quadraticCurveTo(305,402,321,401);

context.quadraticCurveTo(335,401,351,419);

context.bezierCurveTo(305,333,320,312,362,305);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

// white water main 

context.beginPath();

context.moveTo(348,587);

context.bezierCurveTo(392,527,350,548,361,451);

context.bezierCurveTo(366,508,393,572,348,587);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(340,375);

context.quadraticCurveTo(344,357,330,353);

context.lineTo(340,375);

context.fillStyle= "rgba(29,166,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(404,591);

context.bezierCurveTo(402,570,414,578,392,501);

context.quadraticCurveTo(424,571,404,591);

context.fillStyle = "rgba(28,165,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(279,602);

context.quadraticCurveTo(246,578,239,567);

context.quadraticCurveTo(244,594,279,602);

context.fillStyle= "rgba(28,165,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(204,562);

context.quadraticCurveTo(195,565,198,592);

context.quadraticCurveTo(186,565,204,562);

context.fillStyle= "rgba(27,164,187,1.00)";

context.fill();

context.beginPath();

context.moveTo(183,472);

context.quadraticCurveTo(150,496,153,516);

context.quadraticCurveTo(141,490,183,472);


context.fillStyle= "rgba(10,148,171,1.00)";

context.fill();

context.beginPath();

context.moveTo(433,344);

context.bezierCurveTo(458,386,454,389,444,402);

context.quadraticCurveTo(475,386,433,344);

context.filleStyle= "rgba(27,165,187,1.00)";

context.fill();

// small water splashes top right 

context.beginPath();

context.moveTo(504,280);

context.quadraticCurveTo(549,300,558,324);

context.quadraticCurveTo(532,298,504,280);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(455,286);

context.bezierCurveTo(527,291,543,350,542,363);

context.bezierCurveTo(525,355,513,307,455,286);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(385,299);

context.bezierCurveTo(446,273,499,317,492,371);

context.quadraticCurveTo(469,289,385,299);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

// white water top right 

context.beginPath();

context.moveTo(493,367);

context.quadraticCurveTo(498,338,472,314);

context.quadraticCurveTo(489,338,493,367);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(540,361);

context.quadraticCurveTo(540,323,497,302);

context.quadraticCurveTo(526,329,540,361);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

// water splashes bottom left 

context.beginPath();

context.moveTo(229,456);

context.bezierCurveTo(182,410,153,411,117,464);

context.bezierCurveTo(97,406,185,383,229,456);

context.closePath();

context.fillStyle= "rgba(7,140,161,1.00)";

context.fill();

context.beginPath();

context.moveTo(231,476);

context.quadraticCurveTo(185,423,171,442);

context.bezierCurveTo(170,450,196,443,231,476);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(144,470);

context.quadraticCurveTo(108,514,136,540);

context.bezierCurveTo(99,523,114,478,144,470);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(116,549);

context.quadraticCurveTo(133,564,125,584);

context.quadraticCurveTo(98,565,116,549);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

// white water bottom left 

context.beginPath();

context.moveTo(120,446);

context.quadraticCurveTo(115,420,145,416);

context.quadraticCurveTo(141,420,120,446);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

// bottom right splashes 

context.beginPath();

context.moveTo(435,430);

context.bezierCurveTo(536,406,546,500,520,506);

context.bezierCurveTo(471,420,450,427,435,430);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(430,469);

context.bezierCurveTo(466,452,492,502,480,510);

context.bezierCurveTo(457,501,454,480,430,469);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

context.beginPath();

context.moveTo(364,601);

context.quadraticCurveTo(702,501,799,601);

context.closePath();

context.fillStyle= "rgba(6,141,162,1.00)";

context.fill();

// white water bottom right 

context.beginPath();

context.moveTo(525,499);

context.quadraticCurveTo(530,470,505,440);

context.quadraticCurveTo(512,503,525,499);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(477,510);

context.quadraticCurveTo(470,483,468,480);

context.quadraticCurveTo(490,491,477,510);

context.fillStyle= "rgba(27,166,188,1.00)";

context.fill();

context.beginPath();

context.moveTo(448,591);

context.bezierCurveTo(515,590,621,535,735,580);

context.bezierCurveTo(621,557,603,581,448,591);

context.fillStyle= "rgba(40,174,194,1.00)";

context.fill();

// <<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE<<<END HERE

///////////////////////////////////////////////////////////////////


// CREDITS


context.save();

var credits = "Sydney Poniewaz, Dolphin, FMX 210, FA 2021";

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>


Comments

Popular posts from this blog

Autoscopy Project