Canvas



    My canvas piece was a variation of the character Isaac from The Binding of Isaac. The game has a very simple art style while still having distinct character designs, which is why I chose it. To create a variation on it, I included the evil eye symbol as part of the game involves becoming increasingly morphed and deformed. I created Isaac through using Adobe Dreamweaver to create a series of shapes (primarily circles, quadratic curves, and Bezier curves). In total, it took me about 8 hours to create from start to finish.
    Given that it was my first exploration into working with Dreamweaver, I was really proud of how this turned out. It was pleasantly surprising how fun it was to manipulate code into something recognizable. It was daunting at first, but realizing that it was essentially just geometry reframed how I approached it into something a lot more manageable. I was particularly satisfied with how the eyes came out to create this mix of sad and eerie look (which is very tonally appropriate for the character). While there are some flaws, I think that overall the product came out well.

Sketch:

Isaac Inspiration:


Evil Eye Inspiration:

Code Used:

 <!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(73,31,31,1.00);
border: rgba(255,255,255,0) 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
context.beginPath();

for (var i=150; i<canvas.height; i+=50) {
context.moveTo(0,i);
//context.lineTo(canvas.width,i);
//context.lineTo(canvas.width-i,i);
context.lineTo(i,canvas.height);
context.lineTo(canvas.width, canvas.height-i);
context.lineTo(canvas.width - i, 0);
context.lineTo(0,i+50);
context.lineWidth = 20;
context.strokeStyle = "rgba(95,15,172,.20)";
context.stroke();
}

context.closePath();
//Left Arm

context.beginPath();
context.moveTo(390, 429);
context.bezierCurveTo(515, 600, 525, 780, 400, 655);
context.fillStyle = 'rgba(235,196,183,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgba(0,0,0,1.00)";
context.lineCap = 'round' 
context.stroke();

//Right Arm
context.beginPath();
context.moveTo(210, 429);
context.bezierCurveTo(85, 600, 75, 780, 200, 655);
context.fillStyle = 'rgba(235,196,183,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgba(0,0,0,1.00)";
context.lineCap = 'round' 
context.stroke();
//body


context.beginPath();
context.moveTo(125, 800);
context.quadraticCurveTo(300, -200, 475, 800);
context.fillStyle = 'rgba(235,196,183,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgb(0,0,0)";
context.stroke();
 

//head
        context.beginPath();
        context.arc(300, 250, 200, 0, 2*Math.PI, false);
    context.fillStyle = 'rgb(237,199,187)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,1.00)";
        context.stroke();


//frown
        context.beginPath();
        context.arc(300, 400, 50, 0, Math.PI, true);
context.fillStyle = 'rgba(47,33,34,1.00)';
context.fill();
      context.lineWidth = 2;
        context.strokeStyle = "black";
        context.stroke();
//frown - tongue
context.beginPath();
context.moveTo(250, 400);
context.quadraticCurveTo(300, 360, 350, 400);
context.fillStyle = 'rgba(227,157,175,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgba(0,0,0,1.00)";
context.stroke();


  //frown - lower lip
context.beginPath();
context.moveTo(250, 400);
context.quadraticCurveTo(300, 375, 350, 400);
context.fillStyle = 'rgba(237,199,187,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgba(0,0,0,1.00)";
context.stroke();
//evil eye 1
context.beginPath();
        context.arc(300, 145, 85, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(21,8,127,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();
//evil eye 2
context.beginPath();
        context.arc(300, 145, 50, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(255,255,255,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();
//evil eye 3
context.beginPath();
        context.arc(300, 145, 30, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(152,208,249,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();
//evil eye 4
context.beginPath();
        context.arc(300, 145, 10, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();

//left tears

context.beginPath();
context.moveTo(200,360);
context.bezierCurveTo(230, 440, 170, 520, 200, 600);
context.bezierCurveTo(230, 680, 170, 760, 200, 840);
context.lineWidth = 50;
context.strokeStyle = "rgba(78,214,252,0.75)";
context.lineCap = 'round' 
context.stroke();
//right tears
context.beginPath();
context.moveTo(400,360);
context.bezierCurveTo(370, 520, 430, 440, 400, 600);
context.bezierCurveTo(370, 760, 430, 680, 400, 840);
context.lineWidth = 50;
context.strokeStyle = "rgba(78,214,252,0.75)";
context.lineCap = 'round' 
context.stroke();

//left eye
context.beginPath();
        context.arc(200, 285, 75, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,1.00)";
        context.stroke();
//right eye
context.beginPath();
        context.arc(400, 285, 75, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(0,0,0,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,1.00)";
        context.stroke();
//left pupil
context.beginPath();
        context.arc(180, 260, 40, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(255,255,255,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();
//right pupil
context.beginPath();
        context.arc(380, 260, 40, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(255,255,255,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();

//right eye shine
context.beginPath();
        context.arc(440, 325, 15, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(255,255,255,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();

//left eye shine
context.beginPath();
        context.arc(235, 325, 15, 0, 2*Math.PI, false);
    context.fillStyle = 'rgba(255,255,255,1.00)' ;
context.fill();
        context.lineWidth = 2;
        context.strokeStyle = "rgba(0,0,0,00)";
        context.stroke();

//feet line
context.beginPath();
    context.moveTo(125,800)
    context.lineTo(475, 800);
context.lineWidth = 2; // STROKE WIDTH
    context.strokeStyle = 'rgba(0,0,0,1.00)';
context.stroke(); // STROKE
//leg arc
context.beginPath();
context.moveTo(250, 800);
context.quadraticCurveTo(300, 600, 350, 800);
context.fillStyle = 'rgba(73,31,31,1.00)';
context.fill();
context.lineWidth = 2;
context.strokeStyle = "rgba(0,0,0,1.00)";
context.stroke();
 

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

// CREDITS

context.save();
var credits = "Sage Boutelle, Canvas, FMX 210, SP 2022";
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>

Comments

  1. Hi Sage,
    This is so well done. Not sure if you have worked in Dreamweaver before but this project makes it look like you have. One of my favorites from the class!

    ReplyDelete

Post a Comment

Popular posts from this blog

Portfolio

A Brief History of the Internet, World Wide Web, Wi-Fi, and Bluetooth

Photoshop Tool Tutorial Overview