Click on object to do certain function - javascript

I'm programming on JavaScript and basically what I'm supposed to do is to draw a face on a canvas and those faces have certain effects.
One of the effects I'm supposed to do is to click on the nose and it will change the face to an angry face. I have created objects for all the face parts (nose, eyes, etc.) and what I'm trying to do is that I want the function "angryFace" to be called when the nose is clicked. The nose is already an object.
Been stuck for a long time on this. Would appreciate it if someone could help! Uploaded the whole code down here. Thanks guys!
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>COM1008 Assignment 2</title>
<link rel="stylesheet" href="main1.css">
</head>
<main>
<h1>COM 1008 Assignment 2</h1>
<p>By Samuel Fung Chi Lun</p>
</main>
<body>
<canvas id="canvasFrame" width="600" height="600"></canvas>
<p>
<button name="sadbutton" id="sadFace">Sad</button>
<button name="angrybutton" id="angryFace">Angry</button>
<button name="surprisedbutton" id="surprisedFace">Surprised</button>
<button name="neutralbutton" id="neutralFace">Neutral</button>
</p>
<script>
var canvas = document.getElementById('canvasFrame');
var context = canvas.getContext('2d');
//Function to obtain x and y coordinates of mouse positions - Obtained from 20/11/2017 lecture slides
function getMouseXY(e) {
var boundingRect = canvas.getBoundingClientRect();
var offsetX = boundingRect.left;
var offsetY = boundingRect.top;
var w = (boundingRect.width - canvas.width);
var h = (boundingRect.height - canvas.height);
offsetX += w;
offsetY += h;
var mx = Math.round(e.clientX - offsetX);
var my = Math.round(e.clientY - offsetY);
return { x: mx, y: my };
}
const BROWS_UP = 190;
const BROWS_DOWN = 170;
//Creating an object for left eye brow
var leftEyeB = {
draw: function (x1,brows_direction1,x2,brows_direction2) {
context.beginPath();
context.lineWidth = 18;
context.moveTo(x1, brows_direction1);
context.lineTo(x2, brows_direction2)
context.stroke();
}
};
//Creating an object for right eye brow
var rightEyeB = {
draw: function (x1,brows_direction1,x2,brows_direction2) {
context.beginPath();
context.lineWidth = 18;
context.moveTo(x1, brows_direction1);
context.lineTo(x2, brows_direction2)
context.stroke();
}
};
//Creating an object for the head
var faceShape = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(255,255,0)"
context.lineWidth = 3;
context.arc(300, 300, 200, 0, Math.PI * 2, true);
context.fill();
context.stroke();
}
}
//Creating an object for the eyes
var eyes = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(255, 250); //LeftEye
context.arc(220, 250, 40, 0, Math.PI * 2, true);
context.moveTo(415, 250);//Right Eye
context.arc(380, 250, 40, 0, Math.PI * 2, true);
context.fill();
context.fill();
context.stroke();
context.beginPath();
context.fillStyle = "rgb(255,255,255)";
context.moveTo(240, 250); //LeftPupil
context.arc(220, 250, 15, 0, Math.PI * 2, true);
context.moveTo(400, 250); //Right Pupil
context.arc(380, 250, 15, 0, Math.PI * 2, true);
context.fill();
context.stroke();
}
}
//Creating an object for the nose
var nose = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(300, 275);
context.lineTo(275, 325);
context.lineTo(325, 325);
context.fill();
context.closePath();
context.stroke();
}
}
//Creating an object for the mouth
var mouth = {
frown: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(305, 427);//Mouth
context.arc(305, 427, 80, 0, Math.PI, true);
context.fill();
context.closePath();
context.stroke();
},
circle: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.arc(300, 400, 50, 0, Math.PI * 2, true);
context.fill();
context.stroke();
},
straight: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.rect(225, 390, 150, 20);//Mouth
context.fill();
context.stroke();
}
}
//Drawing the sad face
function sadFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.frown();
leftEyeB.draw(175,BROWS_DOWN,265,BROWS_DOWN);
rightEyeB.draw(335,BROWS_DOWN,425,BROWS_DOWN);
}
//Drawing the angry face
function angryFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.frown();
leftEyeB.draw(175,BROWS_DOWN,265,BROWS_UP);
rightEyeB.draw(335,BROWS_UP,425,BROWS_DOWN);
}
//Drawing the surprised face
function surprisedFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.circle();
leftEyeB.draw(175,BROWS_UP,265,BROWS_DOWN);
rightEyeB.draw(335,BROWS_DOWN,425,BROWS_UP);
}
//Drawing the neutral face
function neutralFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.circle();
leftEyeB.draw(175,BROWS_DOWN,265,BROWS_DOWN);
rightEyeB.draw(335,BROWS_DOWN,425,BROWS_DOWN);
}
//Not sure how to properly do the bottom part. It does not work at all for the eyebrows one so please help!
function effects() {
//Click on the eyebrows to raise them
if (mousePosition.x > x1 && mousePosition.x < x2 && mousePosition.y < BROWS_UP && mousePosition.y > BROWS_DOWN) {
BROWS_UP += 20;
}
//Click on eye to show angry face
if (mousePosition = on coordinates of the eye) {
angryFace();
}
//Click on nose to show happy face
if (mousePosition = on coordinates of the nose) {
smileFace();
}
}
canvas.addEventListener('click', function(evt) {
effects(evt);
});
neutralFace();
//Linking the face functions to the buttons
var angryButton = document.getElementById("angryFace");
var sadButton = document.getElementById("sadFace");
var surprisedButton = document.getElementById("surprisedFace");
var neutralButton = document.getElementById("neutralFace");
sadButton.addEventListener("click", sadFace);
angryButton.addEventListener("click", angryFace);
surprisedButton.addEventListener("click", surprisedFace);
neutralButton.addEventListener("click", neutralFace);
</script>
</body>
</html>

When you make face, for you, there are different objects(say nose, eyes etc). For DOM, there is only 1 object i.e. Canvas. So when you click, you are clicking on canvas and not nose.
So to achieve this, you will have to play with coordinates. You have to assume the position of every container and on click of canvas, check the coordinates. If the coordinates are within range of some object, fire necessary function.
canvas.addEventListener('click', function(event){
var x = event.clientX, y = event.clientY;
if(x> 280 && x <335 && y > 280 && y <335) {
// nose is clicked.
angryFace();
}
else {
neutralFace();
}
})
Following is a partial sample:
var canvas = document.getElementById('canvasFrame');
var context = canvas.getContext('2d');
//Function to obtain x and y coordinates of mouse positions - Obtained from 20/11/2017 lecture slides
function getMouseXY(e) {
var boundingRect = canvas.getBoundingClientRect();
var offsetX = boundingRect.left;
var offsetY = boundingRect.top;
var w = (boundingRect.width - canvas.width);
var h = (boundingRect.height - canvas.height);
offsetX += w;
offsetY += h;
var mx = Math.round(e.clientX - offsetX);
var my = Math.round(e.clientY - offsetY);
return {
x: mx,
y: my
};
}
const BROWS_UP = 190;
const BROWS_DOWN = 170;
//Creating an object for left eye brow
var leftEyeB = {
draw: function(x1, brows_direction1, x2, brows_direction2) {
context.beginPath();
context.lineWidth = 18;
context.moveTo(x1, brows_direction1);
context.lineTo(x2, brows_direction2)
context.stroke();
}
};
//Creating an object for right eye brow
var rightEyeB = {
draw: function(x1, brows_direction1, x2, brows_direction2) {
context.beginPath();
context.lineWidth = 18;
context.moveTo(x1, brows_direction1);
context.lineTo(x2, brows_direction2)
context.stroke();
}
};
//Creating an object for the head
var faceShape = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(255,255,0)"
context.lineWidth = 3;
context.arc(300, 300, 200, 0, Math.PI * 2, true);
context.fill();
context.stroke();
}
}
//Creating an object for the eyes
var eyes = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(255, 250); //LeftEye
context.arc(220, 250, 40, 0, Math.PI * 2, true);
context.moveTo(415, 250); //Right Eye
context.arc(380, 250, 40, 0, Math.PI * 2, true);
context.fill();
context.fill();
context.stroke();
context.beginPath();
context.fillStyle = "rgb(255,255,255)";
context.moveTo(240, 250); //LeftPupil
context.arc(220, 250, 15, 0, Math.PI * 2, true);
context.moveTo(400, 250); //Right Pupil
context.arc(380, 250, 15, 0, Math.PI * 2, true);
context.fill();
context.stroke();
}
}
//Creating an object for the nose
var nose = {
draw: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(300, 275);
context.lineTo(275, 325);
context.lineTo(325, 325);
context.fill();
context.closePath();
context.stroke();
}
}
//Creating an object for the mouth
var mouth = {
frown: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.moveTo(305, 427); //Mouth
context.arc(305, 427, 80, 0, Math.PI, true);
context.fill();
context.closePath();
context.stroke();
},
circle: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.arc(300, 400, 50, 0, Math.PI * 2, true);
context.fill();
context.stroke();
},
straight: function() {
context.beginPath();
context.fillStyle = "rgb(0,0,0)";
context.rect(225, 390, 150, 20); //Mouth
context.fill();
context.stroke();
}
}
//Drawing the sad face
function sadFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.frown();
leftEyeB.draw(175, BROWS_DOWN, 265, BROWS_DOWN);
rightEyeB.draw(335, BROWS_DOWN, 425, BROWS_DOWN);
}
//Drawing the angry face
function angryFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.frown();
leftEyeB.draw(175, BROWS_DOWN, 265, BROWS_UP);
rightEyeB.draw(335, BROWS_UP, 425, BROWS_DOWN);
}
//Drawing the surprised face
function surprisedFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.circle();
leftEyeB.draw(175, BROWS_UP, 265, BROWS_DOWN);
rightEyeB.draw(335, BROWS_DOWN, 425, BROWS_UP);
}
//Drawing the neutral face
function neutralFace() {
faceShape.draw();
eyes.draw();
nose.draw();
mouth.circle();
leftEyeB.draw(175, BROWS_DOWN, 265, BROWS_DOWN);
rightEyeB.draw(335, BROWS_DOWN, 425, BROWS_DOWN);
}
function effects() {
mousePosition = getMouseXY(e);
console.log(mousePosition);
}
neutralFace();
canvas.addEventListener('click', function(event){
var x = event.clientX, y = event.clientY;
if(x> 280 && x <335 && y > 280 && y <335) {
// nose is clicked.
angryFace();
}
else {
neutralFace();
}
})
//Linking the face functions to the buttons
var angryButton = document.getElementById("angryFace");
var sadButton = document.getElementById("sadFace");
var surprisedButton = document.getElementById("surprisedFace");
var neutralButton = document.getElementById("neutralFace");
sadButton.addEventListener("click", sadFace);
angryButton.addEventListener("click", angryFace);
surprisedButton.addEventListener("click", surprisedFace);
neutralButton.addEventListener("click", neutralFace);
<!-- This is not the original markup. This is a part of an edit to make the code executable. -->
<canvas id='canvasFrame' width=600 height=600></canvas>
<div>
<button id="angryFace">Angry Face</button>
<button id="sadFace">Sad Face</button>
<button id="surprisedFace">Surprised Face</button>
<button id="neutralFace">Neutral Face</button>
</div>

Related

Cube gets a little bigger when i draw it again. (Canvas, Javascript)

//Selectors
canvas = document.querySelector('.canvas');
canvas.setAttribute("tabindex", 0);
canvas.focus();
pointerImg = document.querySelector('.pointer');
//Variables
const pi = Math.PI;
const c = canvas.getContext('2d');
var grid = {
'x':60,
'y':20,
'size':20,
}
var pointerValues = {
37: {'x':-1, 'y':0},
38: {'x':0, 'y':-1},
39: {'x':1, 'y':0},
40: {'x':0, 'y':1},
}
//Event Listeners
window.addEventListener('resize', function() {
//init();
})
var cells = [];
for(let i=0;i<grid.x;i++) {
cells[i] = new Array(grid.y);
}
//Functions
function init() {
resizeGrid();
initCells();
}
init();
function update(){
requestAnimationFrame(update)
}
update();
function Cell(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.color = 'white';
this.update = function() {
this.draw();
}
this.draw = function() {
c.beginPath();
c.rect(this.x*this.size, this.y*this.size, this.size, this.size);
c.strokeStyle = 'black';
c.stroke();
c.fillStyle=this.color; c.fill();
c.closePath();
}
this.resetCell = function() {
c.clearRect(this.x, this.y, this.size, this.size);
this.update();
}
}
function resizeGrid() {
let windowX = window.innerWidth;
windowX -= windowX*0.1;
grid.size = windowX/grid.x;
let canvasX = windowX, canvasY = grid.y * grid.size;
canvas.width = canvasX;
canvas.height = canvasY;
}
function initCells() {
cells = [];
for(let i=0;i<grid.x;i++) {
cells[i] = new Array(grid.y);
}
for(let i=0;i<grid.x;i++) {
for(let j=0;j<grid.y;j++) {
cells[i][j] = new Cell(i, j, grid.size);
cells[i][j].update();
}
}
}
<html>
<head>
<link rel="stylesheet" href="assets/css/main.css">
<div style="display:none;">
<img class='pointer' src="assets/img/pointer.svg">
</div>
<div class='nav'>
</div>
</head>
<body>
<div class="content">
<canvas class='canvas'></canvas>
</div>
<script src='assets/js/canvas.js'></script>
</body>
</html>
function Cell(x, y, size) {
this.x = x;
this.y = y;
this.size = size;
this.color = 'white';
this.update = function () {
this.draw();
}
this.draw = function () {
c.beginPath();
c.rect(this.x * this.size, this.y * this.size, this.size, this.size);
c.strokeStyle = 'black';
c.stroke();
c.fillStyle = this.color;
c.fill();
c.closePath();
}
this.resetCell = function () {
c.clearRect(this.x, this.y, this.size, this.size);
this.update();
}
This is my code for a single cell in a grid. After I draw it a single time, when I call resetCell(), it draws the cell just a little bit bigger.
In this picture, I call Update for the very first cell and it becomes a tiny bit bigger than the rest.
I've tried pretty much everything but nothing seems to work.
Also can someone recommend better way to draw and control grid.
I need it to demonstrate BFS algorithm.
You were tricked by the thickness of the border
The border has a thickness, which is easy to forget. If you draw a box which is X wide, its left and right border are in addition to the width of X.
So if you do NOT fill the interior, you get this nice appearance (left), but if you FILL, you get this ugly appearance (right).
When you draw a grid of these squares, each one covers over the right-hand and bottom sides of previous squares, so that it is not obvious what is happening.
Unless you redraw one that is not the last of the list, as I have done here (bottom-middle). Then it becomes obvious that something is wrong.
Here is the code to reproduce the above figures, and below I recommend a solution.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
// With NO fill, it looks fine
ctx.beginPath();
ctx.rect(40, 40, 40, 40);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.rect(80, 80, 40, 40);
ctx.stroke();
ctx.closePath();
// With white fill, the inner half of each box gets covered up by the white fill.
ctx.beginPath();
ctx.rect(140, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(180, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
// Make Grid. This part looks OK initially.
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.rect(240, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(240, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(280, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(280, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(320, 40, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
ctx.beginPath();
ctx.rect(320, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
// Redraw one: this will look messed up.
ctx.beginPath();
ctx.rect(280, 80, 40, 40);
ctx.stroke();
ctx.fillStyle="white";
ctx.fill();
ctx.closePath();
<!DOCTYPE html>
<html>
<body>
<canvas id="myCanvas" width="400" height="150" ></canvas>
</body>
</html>
Solution 1. Don't fill the interiors
This is the neatest solution, if you can get away with it, and it works regardless of any (non-zero) border thickness.
Solution 2. Shrink the width to allow for border thickness
This is complicated because you need to manually set the border thickness, and realise that it is in addition to the numerical values you specify for the rectangle's size.
Look at this messy business at CSS-tricks, even when they are trying to make borders interesting! https://css-tricks.com/almanac/properties/b/border/

Animate Canvas from Vue

I am trying to implement this post, which draws and animates a stick figure, into Vue.
draw(timestamp, wave) {
if(Date.now() < (timestamp+900)) return requestAnimationFrame(this.draw);
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
context.beginPath();
context.fillStyle = "black"; // #000000
context.arc(200, 50, 30, 0, Math.PI * 2, true);
context.fill(); //fill the circle
context.beginPath();
context.lineWidth = 6;
context.stroke();
//body
context.beginPath();
context.moveTo(200, 80);
context.lineTo(200, 180);
context.strokeStyle = "black";
context.stroke();
//arms
context.beginPath();
context.strokeStyle = "black";
context.moveTo(200, 100);
context.lineTo(150, 130);
if(wave) {
context.moveTo(200, 100);
context.lineTo(250, 130);
wave = false;
}
else {
context.moveTo(200, 100);
context.lineTo(250, 70);
wave = true;
}
context.stroke();
//legs
context.beginPath();
context.strokeStyle = "black";
context.moveTo(200, 180);
context.lineTo(150, 280);
context.moveTo(200, 180);
context.lineTo(250, 280);
context.stroke();
timestamp = Date.now();
requestAnimationFrame(this.draw);
}
},
mounted: function () {
var canvas = document.getElementById("canvas");
context = canvas.getContext("2d"); // get Canvas Context object
let timestamp = Date.now();
let wave = false;
this.draw(timestamp, wave);
}
If I do the entire draw method inside of my mounted method, it works. But when I move draw to it's own method, as shown above, it fails.
I know it's failing because the line if(Date.now() < (timestamp+900)) is always returning false when running the code above. But I'm not sure why that's happening, or what the difference is.
How can I get this canvas to animate?
Here's an example of how this might look in a component.
Vue.component('canvas-demo', {
data: function () {
return {
timestamp: Date.now(),
wave: false
}
},
mounted: function(){
this.startDrawing(this.$el.getContext("2d"));
},
template: '<canvas></canvas>',
methods: {
startDrawing: function(context) {
var draw = () => {
if (Date.now() < (this.timestamp + 900)) return requestAnimationFrame(draw);
context.clearRect(0, 0, window.innerWidth, window.innerHeight);
context.beginPath();
context.fillStyle = "black"; // #000000
context.arc(200, 50, 30, 0, Math.PI * 2, true);
context.fill(); //fill the circle
context.beginPath();
context.lineWidth = 6;
context.stroke();
//body
context.beginPath();
context.moveTo(200, 80);
context.lineTo(200, 180);
context.strokeStyle = "black";
context.stroke();
//arms
context.beginPath();
context.strokeStyle = "black";
context.moveTo(200, 100);
context.lineTo(150, 130);
if (this.wave) {
context.moveTo(200, 100);
context.lineTo(250, 130);
this.wave = false;
}
else {
context.moveTo(200, 100);
context.lineTo(250, 70);
this.wave = true;
}
context.stroke();
//legs
context.beginPath();
context.strokeStyle = "black";
context.moveTo(200, 180);
context.lineTo(150, 280);
context.moveTo(200, 180);
context.lineTo(250, 280);
context.stroke();
this.timestamp = Date.now();
requestAnimationFrame(draw);
}
draw();
}
}
});
new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<canvas-demo></canvas-demo>
</div>

HTML5 Canvas is very slow in google chrome and chromium but others are fast

I am making a canvas scatter chart with 15,000 points. Each points contains 2 circles. It works perfectly in Firefox and Safari (takes 200ms) but in chrome it takes (1500ms). Here is my code i tried.
// dataUpdate has 15000 points
dataUpdate.forEach(function(d, i) {
var x = getXYvalue(d, "x"),
y = getXYvalue(d, "y"),
size = getSymbolSize(d);
context.save();
context.translate(x, y);
if (outerFillColor || outerStrokeColor) {
context.beginPath();
context.fillStyle = fillColor;
context.strokeStyle = strokeColor;
context.lineWidth = outerStrokeWidth;
context.arc(0, 0, size, 0, Math.PI * 2);
if (outerFillColor) {
context.fill();
}
if (outerStrokeColor && outerStrokeWidth) {
context.stroke();
}
context.closePath();
}
if (innerFillColor || innerStrokeColor) {
context.beginPath();
context.fillStyle = fillColor;
context.strokeStyle = strokeColor;
context.lineWidth = innerStrokeWidth;
context.arc(0, 0, size / 2, 0, Math.PI * 2);
if (innerFillColor) {
context.fill();
}
if (innerStrokeColor && innerStrokeWidth) {
context.stroke();
}
context.closePath();
}
context.restore();
}

Drawing triangle in Canvas issue

I have photo with triangle/rectangle drawn moveable here:http://jsfiddle.net/b29hxxma/ Now i want replace photo with video but with moveable shape see here:http://jsfiddle.net/alwaysgreat/ez1orho1/ but somehow its not working.I tried lot and even able to draw shape but not making it moveable.Pls help.Code(got from somewhere) i used to draw shape but not making it moveable on video:
function draw() {
var v = document.getElementById("video1");
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.drawImage(v, 5, 5, 260, 125);
ctx.clearRect(135, 92, 126, 34);
ctx.beginPath();
ctx.rect(135, 92, 126, 34);
ctx.fillStyle = 'pink';
ctx.fill();
setTimeout(function(){ draw(v,5, 5, 260, 125); }, 20);
}
draw();
For a moveable rectangle over the video, you can use this code (adapted from your second JSFiddle link):
var v = document.getElementById("video1");
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
var mouseX = 135;
var mouseY = 92;
function draw() {
ctx.clearRect(0, 0, c.width, c.height);
ctx.drawImage(v, 5, 5, 260, 125);
ctx.beginPath();
ctx.rect(mouseX, mouseY, 126, 34);
ctx.fillStyle = 'pink';
ctx.fill();
setTimeout(function(){ draw(v,5, 5, 260, 125); }, 20);
}
function findOffset(obj) {
var curX = 0,
curY = 0;
if (obj.offsetParent) {
do {
curX += obj.offsetLeft;
curY += obj.offsetTop;
} while (obj = obj.offsetParent);
return {
x: curX,
y: curY
};
}
}
window.addEventListener('mousemove', function(event) {
var offset = findOffset(c);
mouseX = event.pageX - offset.x;
mouseY = event.pageY - offset.y;
}
draw();
The code will draw a rectangle over the top of the video at the mouse position. It works by saving the mouse position from the onmousemove function, and then when the draw function is called, it draws the rectangle at that location.

Rotation of canvas not happening as per my expectation

I want my rectangle to rotate in place. But currently it is rotating as though there is one object at center and my object is revolving around it i.e much like what we see in solar system. I want my object to rotate in place not revolve around something. How can I do that?
This is my code so far:
<script type="text/javascript">
var context;
var radian = 0.01;
var w, h;
$(document).ready(function () {
w = document.width;
h = document.height;
var canvas = $('#canvas');
context = canvas[0].getContext('2d');
canvas[0].width = w;
canvas[0].height = h;
setInterval(startAnim, 10);
});
function startAnim() {
context.save();
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(0,0,0)';
context.fillRect(0, 0, w, h);
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(255,255,0)';
context.strokeRect(0, 0, 200, 200);
context.fillRect(0, 0, 200, 200);
context.restore();
context.fillStyle = 'rgb(0,255,255)';
context.fillRect(500, 400, 200, 200);
radian += 0.01;
}
</script>
UPDATE: Sorry I was experimenting before I posted and I forgot to add rotate function while posting here. This is the actual code:
function startAnim() {
context.save();
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(0,0,0)';
context.fillRect(0, 0, w, h);
context.translate(350, 300);
context.rotate(radian);
context.translate(-350, -300);
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(255,255,0)';
context.strokeRect(0, 0, 200, 200);
context.fillRect(0, 0, 200, 200);
context.restore();
context.fillStyle = 'rgb(0,255,255)';
context.fillRect(500, 400, 200, 200);
radian += 0.01;
}
Use translate(x, y), rotate(r), and then draw your rectangle.
function startAnim() {
context.save();
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(0,0,0)';
context.fillRect(0, 0, w, h);
//^Shouldn't clearRect() be better here?
//Draw translated, rotated rectangle at (250, 250)
var x = 250;
var y = 250;
context.save();
context.translate(x, y);
context.rotate(radian);
context.fillStyle = 'rgb(255,255,0)';
context.fillRect(0, 0, 200, 200);
context.restore();
//Restore context (to reverse translation and rotation)
context.strokeStyle = 'rgb(0,0,0)';
context.fillStyle = 'rgb(255,255,0)';
context.strokeRect(0, 0, 200, 200);
context.fillRect(0, 0, 200, 200);
context.restore();
context.fillStyle = 'rgb(0,255,255)';
context.fillRect(500, 400, 200, 200);
radian += 0.01;
}
jsFiddle demo and Simple jsFiddle demo with one rotating rectangle
You have to translate your context to the center of the rectangle before you rotate it:
context.translate(RECT_CENTER_X, RECT_CENTER_Y);
context.rotate(radian);
context.fillRect(-RECT_CENTER_X, -RECT_CENTER_Y, w, h);

Categories