closePath() Moving Polygon - javascript

The following code below is what is needed to make a simple triangle. I want to keep the triangle in that exact position and add this to my canvas.
can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
If you run the code below, the triangle is there for a split second and then disappears. I need it to stay there along with the three equations. I created the function path(); in effort to keep the triangle positioned in the upper left corner. I am not sure how to keep the triangle there and do all of this.
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script type="text/javascript" src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
#gameCanvas {
background-color: lightyellow;
}
</style>
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" />
</div>
<div id="eqn2"> 3+2=<input type="text" id="q2" />
</div>
<div id="eqn3"> 5+2=<input type="text" id="q3" />
</div>
<canvas id="gameCanvas" width="600" height="600">Not supported</canvas>
<script type="text/javascript">
var m=1;
var stage = new createjs.Stage("gameCanvas");
var obj=[];
can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
function startGame() {
obj[1] = new createjs.DOMElement(document.getElementById(`eqn${1}`));
obj[2] = new createjs.DOMElement(document.getElementById(`eqn${2}`));
stage.addChild(obj[1]);
stage.addChild(obj[2]);
createjs.Ticker.addEventListener("tick", handleTick);
createjs.Ticker.setFPS(60);
function handleTick(event){
drop(1);
drop(2);
path();
stage.update();
}
}
function drop(i){
obj[1].x =40;
obj[1].y =50;
obj[2].x =300;
obj[2].y =50;
}
function path(){
ctx.x=1;
ctx.y=1;
}
</script>
<body onload="startGame();">
<div >
<canvas>This browser or document mode doesn't support canvas object.</canvas>
</div>
</body>
</html>

Take a look at this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Math Game</title>
<script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>
<body onload="startGame();">
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
<div id="eqn2"> 3+2=<input type="text" id="q2" /></div>
<div id="eqn3"> 5+2=<input type="text" id="q3" /></div>
<canvas id="gameCanvas" width="600" height="200">Not supported</canvas>
</div>
<script>
var stage = new createjs.Stage("gameCanvas");
var can = document.getElementById("gameCanvas");
var ctx = can.getContext("2d");
var obj = [];
function drawTriangle() {
ctx.beginPath();
ctx.moveTo(1, 20);
ctx.lineTo(20, 100);
ctx.lineTo(70, 100);
ctx.closePath();
ctx.stroke();
}
function startGame() {
obj[1] = new createjs.DOMElement(document.getElementById("eqn1"));
obj[1].x = 40;
obj[1].y = 50;
stage.addChild(obj[1]);
obj[2] = new createjs.DOMElement(document.getElementById("eqn2"));
obj[2].x = 300;
obj[2].y = 50;
stage.addChild(obj[2]);
stage.update();
drawTriangle();
}
</script>
</body>
</html>
You can see I created a new function drawTriangle it will be called at the end of your startGame that way the triangle is the last item drawn in the canvas.
I'm not sure why you needed the Ticker so I remove it, same with the other functions, they did not make much sense to me, no need for what you are trying to accomplish at the moment.
Now to your problem... in my implementation I have the drawTriangle as the last action in the startGame, but if we change the order, to something like this:
drawTriangle();
stage.update();
The triangle disappears!
My educated guess is that stage.update() clears the entire canvas and draws what it "knows" the triangle drawing is happening outside the stage so we need to always draw it after.
Looking at the code documentation for update:
https://www.createjs.com/docs/easeljs/files/easeljs_display_Stage.js.html#l349
there is an if statement if (this.autoClear) { that does exactly what we are seeing in your sample, and the default value of autoClear is true:
https://www.createjs.com/docs/easeljs/classes/Stage.html#property_autoClear
Also worth pointing out... there is a native createjs way to draw lines:
https://createjs.com/docs/easeljs/classes/Graphics.html#method_moveTo
https://createjs.com/docs/easeljs/classes/Graphics.html#method_lineTo
There is nothing wrong with your approach, you are using both createjs and directly drawing in the canvas via getContext("2d") you just have to plan accordingly, but my recommendation, if there is a native approach I would stick with that, here is a sample code:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Math Game</title>
<script src="//code.createjs.com/createjs-2013.09.25.combined.js"></script>
</head>
<body onload="startGame();">
<div class="canvasHolder1">
<div id="eqn1"> 3+3=<input type="text" id="q1" /></div>
<canvas id="gameCanvas" width="600" height="160">Not supported</canvas>
</div>
<script>
function startGame() {
var stage = new createjs.Stage("gameCanvas");
var eqn1 = new createjs.DOMElement(document.getElementById("eqn1"));
eqn1.x = eqn1.y = 50;
stage.addChild(eqn1);
var triangle = new createjs.Shape();
triangle.graphics.beginStroke("black")
triangle.graphics.moveTo(1, 20);
triangle.graphics.lineTo(20, 100);
triangle.graphics.lineTo(70, 100);
triangle.graphics.lineTo(1, 20);
stage.addChild(triangle);
stage.update();
}
</script>
</body>
</html>

Related

Using destination-over to save background and actual sketch

I've read this and a few other questions, and it is clear I need to use destination-over to save the background and the sketch by display the new image over the old one.
I'm using Sketch.JS with my code as such:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
$('#myCanvas').sketch({
defaultColor: "red"
});
$('#download').click(function() {
ctx.globalCompositeOperation = "destination-over";
img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = 'http://lorempixel.com/400/200/';
ctx.drawImage(img, 0, 0);
$('#url').text(c.toDataURL('/image/png'));
window.open(c.toDataURL('/image/png'));
});
#myCanvas {
background: url(http://lorempixel.com/400/200/);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/intridea/sketch.js/gh-pages/lib/sketch.js"></script>
<canvas id="myCanvas"></canvas>
<input type='button' id='download' value='download'>
<span id='url'></span>
Fiddle
But that doesn't help. Clicking 'download' still only produces the sketch. Now, it seems I don't understand how I need to use destination-over properly. W3Schools doesn't seem to help.
Could anyone point me in the right direction please?
Assume you have a SketchJS canvas on top of an image containing a background:
#wrapper{positon:relative;}
#bk,#myCanvas{position:absolute;}
<div id='wrapper'>
<img crossOrigin='anonymous' id=bk src='yourImage.png'>
<canvas id="myCanvas" width=500 height=300></canvas>
</div>
Then when you want to combine the Sketch with the background and save it as an image you can use destination-over compositing to draw the background "under" the existing Sketch.
ctx.globalCompositeOperation='destination-over';
ctx.drawImage(bk, 0, 0);
Here's example code:
<!doctype html>
<html>
<head>
<script src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script src="https://rawgit.com/intridea/sketch.js/gh-pages/lib/sketch.js"></script>
<style>
body{ background-color: ivory; }
#wrapper{positon:relative;}
#bk,#myCanvas{position:absolute;}
</style>
<script>
$(function(){
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
$('#myCanvas').sketch({ defaultColor: "red" });
$('#download').click(function() {
var img=document.getElementById('bk');
ctx.globalCompositeOperation='destination-over';
ctx.drawImage(bk, 0, 0);
ctx.globalCompositeOperation='source-over';
var html="<p>Right-click on image below and Save-Picture-As</p>";
html+="<img src='"+c.toDataURL()+"' alt='from canvas'/>";
var tab=window.open();
tab.document.write(html);
});
}); // end $(function(){});
</script>
</head>
<body>
<h4>Drag to sketch on the map.</h4>
<button id=download>Download</button>
<div id='wrapper'>
<img crossOrigin='anonymous' id=bk src='https://dl.dropboxusercontent.com/u/139992952/multple/googlemap1.png'>
<canvas id="myCanvas" width=459 height=459></canvas>
</div>
</body>
</html>

Zoom and pan HTML5 canvas - library

I'm trying to implement zooming and panning a canvas which contains a picture.
I found this example http://phrogz.net/tmp/canvas_zoom_to_cursor.html, but the transformations are applied on the picture withing the canvas, not on the canvas itself.
I don't understand the code completely, so I didn't manage to customize it for my needs.
Can someone help me with that?
Or, if you could recommend me some good library suitable for my needs, that would be great.
Thanks.
Check out the transformation methods available on the context object.
Context.scale will allow you to scale your content.
Context.translate will allow you to offset the drawing of your content to create your panning effect.
If you want 2 overlaying canvases to maintain their aspect ratio then you would scale & translate both canvases by the same amount.
Here's example code and a Demo: http://jsfiddle.net/m1erickson/H6UMN/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#wrapper{position:relative;}
canvas{position:absolute; border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
var cw=canvas.width;
var ch=canvas.height;
var scaleFactor=1.00;
var panX=0;
var panY=0;
var circleX=150;
var circleY=150;
var radius=15;
drawTranslated();
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#scaledown").click(function(){ scaleFactor/=1.1; drawTranslated(); });
$("#scaleup").click(function(){ scaleFactor*=1.1; drawTranslated(); });
$("#panleft").click(function(){ panX-=10; drawTranslated(); });
$("#panright").click(function(){ panX+=10; drawTranslated(); });
function drawTranslated(){
ctx.clearRect(0,0,cw,ch);
ctx.save();
ctx.translate(panX,panY);
ctx.scale(scaleFactor,scaleFactor);
ctx.beginPath();
ctx.rect(circleX-radius,circleY-radius,radius*2,radius*2);
ctx.closePath();
ctx.fillStyle="blue";
ctx.fill();
ctx.restore();
ctx1.clearRect(0,0,cw,ch);
ctx1.save();
ctx1.translate(panX,panY);
ctx1.scale(scaleFactor,scaleFactor);
ctx1.beginPath();
ctx1.arc(circleX,circleY,radius,0,Math.PI*2);
ctx1.closePath();
ctx1.fillStyle="red";
ctx1.fill();
ctx1.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<button id=scaledown>Scale Down</button>
<button id=scaleup>Scale Up</button>
<button id=panleft>Pan Left</button>
<button id=panright>Pan Right</button><br>
<div id=wrapper>
<canvas id="canvas" width=350 height=300></canvas>
<canvas id="canvas1" width=350 height=300></canvas>
</div>
</body>
</html>

Canvas: Insert fading rectangle between drawn image and clip

I am trying to create a rectangle which will fade on top of an image that is being clipped dynamically.
However any instance of creating a rectangle goes behind the drawn image, and I can't seem to figure out how to place it on top so both the shape and image become clipped.
Here is a Fiddle of where I am currently: JSFiddle
Here is my html:
<div id='demo'>
<canvas id="canvas" width="200px" height="200px"></canvas>
<img id="img" src="http://www.filterforge.com/more/help/images/size200.jpg" />
</div>
Here is my javascript:
function init(){
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
var r = 1;
function draw(){
c.beginPath();
c.arc(100,100,r,0,2*Math.PI,false);
r = r + 1;
// Start Image
c.save();
c.clip();
var img = document.getElementById('img');
c.drawImage(img,0,0);
c.restore();
// The Rectangle I am also trying to mask
c.fillStyle = "rgba(0,0,0,0.025)"
c.fillRect(0, 0, 200, 200);
c.save();
c.clip();
c.restore();
if(r < 100){
requestAnimationFrame(draw);
}
r++;
}
requestAnimationFrame(draw);
}
init();
I would appreciate any help you guys can offer.
Thanks,
Here's the order you want for your clipping:
context.save
define the clipping region (eg your arc)
drawImage
context.restore
Demo: http://jsfiddle.net/m1erickson/YS45U/
Code:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
#canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas = document.getElementById('canvas');
var c = canvas.getContext('2d');
var r = 0;
var img=new Image();
img.onload=function(){
draw();
};
img.src="http://www.filterforge.com/more/help/images/size200.jpg";
function draw(){
// request another animation if not 100%
if(++r<100){
requestAnimationFrame(draw);
}
// save the unclipped context
c.save();
// set the clipping region
c.beginPath();
c.arc(100,100,r,0,2*Math.PI,false);
c.closePath();
c.clip();
// draw the image into the clipped region
c.drawImage(img,0,0);
// restore the canvas context
c.restore();
}
$("#stop").click(function(){});
}); // end $(function(){});
</script>
</head>
<body>
<button id="stop">Stop</button><br>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

Click image to add to HTML5 Canvas path

I am drawing a circle onto my html5 canvas like below:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
</style>
</head>
<body>
<canvas id="myCanvas" width="578" height="200"></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.lineWidth = 1;
context.strokeStyle = '#000000';
context.stroke();
</script>
</body>
</html>
On my website I have a series of images on the left of the canvas that the user clicks and it adds the image to the canvas and is draggable. I am using KineticJS to achieve this portion. I need help understanding how to be able to click the image and it adds the image to the bounds of the circle and only moves along the circle. On the KineticJS website they have a feature that allows the user to drag in a circular motion. I do not want to use this as it simply constrains it to the whole circle and i would like it to go around the border of the circle.
below is the image of what i'm asking:
circular drag http://www.papiobeads.com/images/theimage.png
You can use canvas transformations to rotate your image around the circumference of your circle.
Move to your desired rotation point (the center of your circle)
Set your desired rotation angle (in radians)
Draw the image
Here's example code and a Demo: http://jsfiddle.net/m1erickson/t5N9T/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" />
<script src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var radianAngle=0;
var cx=150;
var cy=150;
var radius=50;
var img=new Image();img.onload=start;img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/cars.png";
function start(){
animate();
}
function animate() {
requestAnimationFrame(animate);
// Drawing code goes here
radianAngle+=Math.PI/120;
ctx.clearRect(0,0,canvas.width,canvas.height);
// draw the circle
ctx.beginPath();
ctx.arc(cx,cy,radius,0,Math.PI*2);
ctx.closePath();
ctx.stroke();
// draw the image rotated around the circumference
ctx.save();
ctx.translate(cx,cy);
ctx.rotate(radianAngle);
ctx.drawImage(img,radius-img.width/2,-img.height/2);
ctx.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>

How to fill a circle with color when clicked on a correspong link using html5

I have tried this much of a code. I have two circles with a link beside, I need to color the circle onclick of the corresponding link. Suggest some solutions
<body>
<div class="row-fluid">
<div class="span1 offset3">
<canvas id="myCanvas" width="100" height="100"></canvas>
</div>
<div class="span1">
<br/>Hello
</div>
<div class="span1">
<canvas id="myCanvas1" width="100" height="100"></canvas>
</div>
<div class="span1">
<br/>Hi
</div>
</div>
<script>
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(55, 30, 20, 0, 2 * Math.PI);
ctx.stroke();
var c = document.getElementById("myCanvas1");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.arc(55, 30, 20, 0, 2 * Math.PI);
ctx.stroke();
function () {
//onclick function which will change the color of the correspondind circle
}
</script>
</body>
How to fill a canvas circle when an html link is clicked
Here is a flexible function that draws a circle and optionally fills that circle:
function drawCircle(context,fill){
context.beginPath();
context.arc(55, 30, 20, 0, 2 * Math.PI);
context.closePath();
context.stroke();
if(fill){
context.fill()
}
}
jquery can listen for clicks on your anchors.
Then jquery calls the drawCircle function with fill=true (the circle is filled)
// fill the circle on click
$("#c1").click(function(){ drawCircle(ctx,true); });
$("#c2").click(function(){ drawCircle(ctx1,true); });
Here is code and a Fiddle: http://jsfiddle.net/m1erickson/8LGPB/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:20px; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("myCanvas");
var ctx=canvas.getContext("2d");
var canvas1=document.getElementById("myCanvas1");
var ctx1=canvas1.getContext("2d");
// draw stroked but not filled circles
drawCircle(ctx,false);
drawCircle(ctx1,false);
function drawCircle(context,fill){
context.beginPath();
context.arc(55, 30, 20, 0, 2 * Math.PI);
context.closePath();
context.stroke();
if(fill){
context.fill()
}
}
// fill the circle on click
$("#c1").click(function(){ drawCircle(ctx,true); });
$("#c2").click(function(){ drawCircle(ctx1,true); });
}); // end $(function(){});
</script>
</head>
<body>
<div class="row-fluid">
<div class="span1 offset3">
<canvas id="myCanvas" width="100" height="100"></canvas>
</div>
<div class="span1">
<br/><a id="c1" href="#">Hello</a>
</div>
<div class="span1">
<canvas id="myCanvas1" width="100" height="100"></canvas>
</div>
<div class="span1">
<br/><a id="c2" href="#">Hi</a>
</div>
</div>
</body>
</html>
use this code script tag for each function
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var centerX = canvas.width / 2;
var centerY = canvas.height / 2;
var radius = 70;
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fillStyle = 'blue';
context.fill();
context.lineWidth = 5;
context.strokeStyle = '#003300';
context.stroke();
</script>

Categories

Resources