I have a canvas drawing implemented on my project. I would like to show speech-bubbles with information related to specific mouse clicks on the canvas. Say a click on a particular region of my canvas allows for a popup that gives text information about that region on the canvas.
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<ajaxToolkit:BalloonPopupExtender ID="BalloonPopupExtender1"
runat="server"
TargetControlID="myCanvas"
BalloonPopupControlID="Panel1"
Position="TopLeft"
BalloonStyle="Cloud"
BalloonSize="Small"
CustomCssUrl="CustomStyle/BalloonPopupOvalStyle.css"
CustomClassName="oval"
UseShadow="true"
ScrollBars="Auto"
DisplayOnMouseOver="true"
DisplayOnFocus="false"
DisplayOnClick="true" />
<canvas id="myCanvas" width="915" height="850" style="border: 2px double #000000;"></canvas>
<script type="text/javascript">
However this doesn't work, I believe this is because myCanvas is not a asp.net/server side element, hence runat ="server" isn't correct methodology.
I am currently following these blogs:-
http://www.c-sharpcorner.com/UploadFile/364074/balloonpopupextendercontrol-in-ajax/
http://www.asp.net/ajaxLibrary/AjaxControlToolkitSampleSite/BalloonPopup/BalloonPopupExtender.aspx
Any idea how to implement the popup on the canvas, upon a click?
Given that you want to respond to clicks on specific canvas coordinates, you might have to work on the client side. Here's code to do an info popup on the client side.
This is code that will draw an info balloon inside a separate canvas element. The canvas is moved off-screen until it's needed. You can of course, style this popup balloon in any way you want because it's a canvas element!
<canvas id="balloon" width=105 height=105></canvas>
function drawBalloon(X,Y,theInfo){
popCtx.save();
popCtx.fillStyle="#FD0";
popCtx.strokeStyle="#000";
// draw the balloon
popCtx.beginPath();
popCtx.moveTo(52,02);
popCtx.quadraticCurveTo(02,02,02,42);
popCtx.quadraticCurveTo(02,77,27,77);
popCtx.quadraticCurveTo(27,102,07,102);
popCtx.quadraticCurveTo(37,102,42,77);
popCtx.quadraticCurveTo(102,77,102,42);
popCtx.quadraticCurveTo(102,02,52,02);
popCtx.lineWidth=3;
popCtx.stroke();
popCtx.fill();
// draw theInfo
popCtx.font="10pt arial";
popCtx.fillStyle="black";
popCtx.fillText(theInfo,10,50);
popCtx.restore();
// move the balloon canvas to the target
$("#balloon").css({left:offsetX+X, top:offsetY+Y});
}
If you're not used to client-side javascript, here's how to get the position of the target-filled canvas relative to the window
<canvas id="canvas" width=300 height=300></canvas>
// get the position of canvas relative to window
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
And here's how to listen for clicks on the target-filled canvas.
// listen for clicks on the canvas
$("#canvas").click(function(e){
// get the mouseclick position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// see if we clicked on any targets, show the balloon
for(var i=0;i<circles.length;i++){
var circle=circles[i];
var dx=circle.x-mouseX;
var dy=circle.x-mouseY;
var radius=circle.radius;
// true if we clicked in the target circle
if(dx*dx+dy*dy<=radius*radius){
drawBalloon(circles[i].x+radius,circles[i].y-100,circles[i].info);
}
}
});
To test if any target location on the canvas was clicked, we can test a circular area around the target like this:
var dx=targetCircle.x-mouseX;
var dy=targetCircle.x-mouseY;
var radius=targetCircle.radius;
// true if we clicked in the target circle
if(dx*dx+dy*dy<=radius*radius){
// we hit a target, display the balloon
}
Here is working example code and a Fiddle: http://jsfiddle.net/m1erickson/AJvkN/
<!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:10px;padding-top:100px; }
#canvas{border:1px solid red;}
#balloon{ position:absolute; left:-200px; }
</style>
<script>
$(function(){
// get reference to our drawing canvas
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
// get reference to our balloon canvas
var balloon=document.getElementById("balloon");
var popCtx=balloon.getContext("2d");
// get the position of canvas relative to window
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
// define some targets and their basic info
var circles=[];
circles.push({x:40, y:30, radius:15,color:"red", info:"I'm red."});
circles.push({x:150, y:150,radius:25,color:"green",info:"I'm centered."});
circles.push({x:110, y:85, radius:40,color:"blue", info:"I'm big."});
// draw the target circles on the canvas
for(var i=0;i<circles.length;i++){
drawCircle(circles[i]);
}
// listen for clicks on the canvas and show the balloon
$("#canvas").click(function(e){
// get the mouseclick position
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// see if we clicked on any targets
for(var i=0;i<circles.length;i++){
var circle=circles[i];
var dx=circle.x-mouseX;
var dy=circle.x-mouseY;
var radius=circle.radius;
// true if we clicked in the target circle
if(dx*dx+dy*dy<=radius*radius){
drawBalloon(circles[i].x+radius,circles[i].y-100,circles[i].info);
}
}
});
// listen for clicks on the balloon and then hide the balloon
$("#balloon").click(function hideBalloon(e){ $("#balloon").css({left:-200}); });
function drawCircle(circle){
ctx.save();
ctx.beginPath();
ctx.fillStyle=circle.color;
ctx.strokeStyle="black";
ctx.lineWidth=3;
ctx.arc(circle.x,circle.y,circle.radius,0,Math.PI*2,false);
ctx.closePath();
ctx.fill();
ctx.stroke();
ctx.restore();
}
function drawBalloon(X,Y,theInfo){
popCtx.save();
popCtx.fillStyle="#FD0";
popCtx.strokeStyle="#000";
// draw the balloon
popCtx.beginPath();
popCtx.moveTo(52,02);
popCtx.quadraticCurveTo(02,02,02,42);
popCtx.quadraticCurveTo(02,77,27,77);
popCtx.quadraticCurveTo(27,102,07,102);
popCtx.quadraticCurveTo(37,102,42,77);
popCtx.quadraticCurveTo(102,77,102,42);
popCtx.quadraticCurveTo(102,02,52,02);
popCtx.lineWidth=3;
popCtx.stroke();
popCtx.fill();
// draw theInfo
popCtx.font="10pt arial";
popCtx.fillStyle="black";
popCtx.fillText(theInfo,10,50);
popCtx.restore();
// move the balloon canvas to the target
$("#balloon").css({left:offsetX+X, top:offsetY+Y});
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Click circles to popup an info balloon</p>
<p>When info balloon appears, click it do dismiss it</p>
<canvas id="canvas" width=300 height=300></canvas>
<canvas id="balloon" width=105 height=105></canvas>
</body>
</html>
Related
I have canvas area, where i can add some images.
And i want to cut whole canvas to parts and download just one part of image.
If i put divs with color overlay canvas, i can't move my elements inside.
But i want to show users which area has been selected and will be downloaded.
Is it possible to show some divs overlay canvas and also manage with canvas?
If don't how can i listening mouseover event for my div which is invisible, because have lower z-index, than my canvas image ?
Instead of trying to color your divs, you use a second (overlay) canvas on top of your image canvas to tint the desired parts of your image canvas underneath.
Define a javascript object representing each part (rectangle) of your canvas.
Place a second overlay canvas over your image canvas and tell it not emit events using CSS: pointer-events:none.
On mousemove, fill the part of the overlay canvas under the mouse with semi-transparent color.
Here is example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var overlay=document.getElementById("overlay");
var octx=overlay.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
function reOffset(){
var BB=canvas.getBoundingClientRect();
offsetX=BB.left;
offsetY=BB.top;
}
var offsetX,offsetY;
reOffset();
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }
var selectedPart=1;
var parts=[];
var img=new Image();
img.onload=start;
img.src='https://dl.dropboxusercontent.com/u/139992952/multple/sailboatSmall.png';
function start(){
cw=canvas.width=overlay.width=img.width;
ch=canvas.height=overlay.height=img.height;
octx.font='18px verdana';
octx.textAlign='center';
octx.textBaseline='middle';
octx.lineWidth=0.50;
octx.fillStyle='red';
octx.globalAlpha=0.10;
parts.push({x:0,y:0,w:cw/3,h:ch/2});
parts.push({x:cw/3,y:0,w:cw/3,h:ch/2});
parts.push({x:cw*2/3,y:0,w:cw/3,h:ch/2});
parts.push({x:0,y:ch/2,w:cw/2,h:ch/2});
parts.push({x:cw/2,y:ch/2,w:cw/2,h:ch/2});
ctx.drawImage(img,0,0);
$("#canvas").mousemove(function(e){handleMouseMove(e);});
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
var x=parseInt(e.clientX-offsetX);
var y=parseInt(e.clientY-offsetY);
for(var i=0;i<parts.length;i++){
var p=parts[i];
if(x>p.x && x<p.x+p.w && y>p.y && y<p.y+p.h){
if(i==selectedPart){return;}
selectedPart=i;
octx.clearRect(0,0,cw,ch);
octx.fillRect(p.x,p.y,p.w,p.h);
}
}
}
body{ background-color:white; }
#container{position:relative;}
#canvas,#overlay{position:absolute;}
#overlay{pointer-events:none;border:1px solid red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Move mouse over image parts</h4>
<div id=container>
<canvas id="canvas" width=300 height=300></canvas>
<canvas id="overlay" width=300 height=300></canvas>
</div>
I have a sprite sheet consisting of 12 frames.
I want to extract each individual frame from it and want to show it in different canvas like below.
what i have tried so far is posted below
//HTML code for define the canvas area .
<body onload="image_render();">
<div id="image_area"> <canvas id="image"></canvas></div>
<script src="sprite_demo.js"></script>
</body>
// javascript to slice the image and assign to the canvas
var canvasImage = new Image();
canvasImage.src = "image/sprite_xxdpi.jpg";
var can= document.getElementById("image");
can.width = 500;
can.height = 300;
function image_render()
{
coin.render();
}
var coin = sprite({
context: can.getContext("2d"),
width: 500,
height: 300,
image: coinImage
});
function sprite (options) {
var that = {};
that.context = options.context;
that.width = options.width;
that.height = options.height;
that.image = options.image;
that.render = function () {
// Draw the animation
that.context.drawImage(
that.image,
0, //X-axis starting position from where slicing begins
0, //y-axis starting position from where slicing begins
that.width, //width of slicing image
that.height,//height of slicing image
0, //X-axis starting position where image will be drawn
0, //y-axis starting position where image will be drawn
150, // width of the resulting image
150); //height of the resulting image
};
return that;
}
I am only able to get a single image ,But I want to get all the images to show in a grid.And also i want to get the image to show any where I want.
I also want to scale down big size images to show in a grid and while taping on it I want to show the original image.
Note: I don't want to animate my frames, I just want to show in grid. There are mostly examples of sprite animation available on internet.
You have the correct version of drawImage to clip individual sprites from the spritesheet, but you must alter the values in drawImage for each sprite.
The "faces" example spritesheet you show appear to have equal sized individual sprites (75px by 75px).
Assuming all your sprites are the same size, you would alter the 2nd & 3rd drawImage parameters which tell canvas the top-left x/y coordinate to begin clipping on the spritesheet.
Here's example code and a Demo: http://jsfiddle.net/m1erickson/tVD2K/
<!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 ctx=canvas.getContext("2d");
var spriteWidth=75;
var spriteHeight=75;
var spriteCols=4;
var spriteRows=3;
var y=20-sprightHeight;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/spritesheet1.jpg";
function start(){
var canvasY=0;
for(var col=0;col<spriteCols;col++){
for(var row=0;row<spriteRows;row++){
var sourceX=col*spriteWidth;
var sourceY=row*spriteHeight;
// testing: calc a random position to draw this sprite
// on the canvas
var canvasX=Math.random()*150+20;
canvasY+=spriteHeight+5;
// drawImage with changing source and canvas x/y positions
ctx.drawImage(img,
sourceX,sourceY,spriteWidth,spriteHeight,
canvasX,canvasY,spriteWidth,spriteHeight
);
}}
}
}); // end $(function(){});
</script>
</head>
<body>
<h4>Draw individual sprites from a spritesheet</h4>
<canvas id="canvas" width=300 height=1000></canvas>
</body>
</html>
I have a multipage site that the main home page simply has a single image logo on it. When this page is visited I need the image to move around like a screensaver. When any touch is registered the page will go to a second page. That second page has other data and info but nothing is touched for ten minutes it will default and go back to the entry page and the screensaver.
So, two things.
One, move an image around like a screensaver using jQuery.
Two, the other page has a timeout of ten minutes if no touch is registered that knocks the person back to the first page that has the screensaver.
This is an HTML5 page so if jQuery will not work, something using HTML5 and Canvas might.
This is for a site that will be used as a kiosk and a touch screen.
On the screensaver page:
You can use an html canvas that floats your logo image around the screen. Here's a link:
http://jsfiddle.net/m1erickson/E3Qda/
On the second page:
How about starting a 10 minute setTimeout when the page first loads.
If the user triggers a touch event before 10 minutes, (1) clearTimeout the original timeout (2) setTimeout for a new 10 minutes.
Here's example code for the screensaver page:
<!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;}
img{border:1px solid purple;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var ball;
var ballX=60;
var ballY=150;
var ballRadius=50;
var image=new Image();
image.onload=function(){
// resize the image to fit inside the ball's radius
var c=document.createElement("canvas");
var cctx=c.getContext("2d");
// calc the max side length of a square that fits the ball
var maxSide=Math.sqrt(2*ballRadius*ballRadius);
// calc the max rect size that fits in the ball
var iw=image.width;
var ih=image.height;
var maxW,maxH;
if(iw>=ih){
maxW=maxSide;
maxH=maxSide*iw/ih;
}else{
maxW=maxSide*ih/iw;
maxH=maxSide;
}
// size the temp canvas to the max rect size
c.width=maxW;
c.height=maxH;
// draw the image to the temp canvas
cctx.drawImage(image,0,0,iw,ih,0,0,maxW,maxH);
var ballimg=new Image();
ballimg.onload=function(){
ball={x:ballX,y:ballY,r:ballRadius,img:ballimg,imgSide:maxSide,directionX:1,directionY:1};
drawBall(ball);
}
ballimg.src=c.toDataURL();
requestAnimationFrame(animate);
}
image.src="ship.png";
function drawBall(ball){
// clip image inside ball
ctx.save();
ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2,false);
ctx.closePath();
ctx.clip();
ctx.fillStyle="white";
ctx.fillRect(ball.x-ball.r,ball.y-ball.r,ball.r*2,ball.r*2);
ctx.drawImage(ball.img, ball.x-ball.imgSide/2,ball.y-ball.imgSide/2);
ctx.restore();
ctx.beginPath();
ctx.arc(ball.x,ball.y,ball.r,0,Math.PI*2,false);
ctx.closePath();
ctx.strokeStyle="lightgray";
ctx.lineWidth=2;
ctx.stroke();
ctx.beginPath();
ctx.arc(ball.x,ball.y,ball.r+2,0,Math.PI*2,false);
ctx.closePath();
ctx.strokeStyle="gray";
ctx.lineWidth=2;
ctx.stroke();
}
function animate(time) {
requestAnimationFrame(animate);
// move with collision detection
ball.x+=ball.directionX;
if(ball.x-ball.r<0 || ball.x+ball.r>canvas.width){
ball.directionX*=-1;
ball.x+=ball.directionX;
}
ball.y+=ball.directionY;
if(ball.y-ball.r<0 || ball.y+ball.r>canvas.height){
ball.directionY*=-1;
ball.y+=ball.directionY;
}
// Draw
ctx.clearRect(0,0,canvas.width,canvas.height);
drawBall(ball);
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=350 height=350></canvas>
</body>
</html>
I'm trying to apply CamanJS filter to a canvas created with KineticJS. It works:
Caman("#creator canvas", function()
{
this.lomo().render();
});
After applying a CamanJS filter I'm trying to do sth with canvas (eg. drag and move layer or just click on it), but then the canvas reverts to its original state (before applying CamanJS filter). So the question is: how to "tell" KineticJS to update cache(?) or do sth like stage.draw() to keep new canvas data?
Here is jsfiddle (click on "apply filter", when processing will be done, try to drag the star).
BTW: why is the processing so slow?
Thanks in advance.
As you've discovered, Kinetic will redraw the original image when it internally redraws.
Your Caman modified content is not used or saved.
To keep your Caman effect, you can create an offscreen canvas and instruct your Kinetic.Image to get its image from that offscreen canvas.
Then you can use Caman to filter that canvas.
The result is that Kinetic will do its internal redraws with your Caman modified canvas image.
Demo: http://jsfiddle.net/m1erickson/L3ACd/
Code Example:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.7.2.min.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/camanjs/3.3.0/caman.full.min.js"></script>
<style>
body{padding:20px;}
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:350px;
height:350px;
}
</style>
<script>
$(function(){
var stage = new Kinetic.Stage({
container: 'container',
width: 350,
height: 350
});
var layer = new Kinetic.Layer();
stage.add(layer);
// create an offscreen canvas
var canvas=document.createElement("canvas");
var ctx=canvas.getContext("2d");
// load the star.png
var img=new Image();
img.onload=start;
img.crossOrigin="anonymous";
img.src="https://dl.dropboxusercontent.com/u/139992952/stack1/star.png";
// when star.png is loaded...
function start(){
// draw the star image to the offscreen canvas
canvas.width=img.width;
canvas.height=img.height;
ctx.drawImage(img,0,0);
// create a new Kinetic.Image
// The image source is the offscreen canvas
var image1 = new Kinetic.Image({
x:10,
y:10,
image:canvas,
draggable: true
});
layer.add(image1);
layer.draw();
}
// lomo the canvas
// then redraw the kinetic.layer to display the lomo'ed canvas
$("#myButton").click(function(){
Caman(canvas, function () {
this.lomo().render(function(){
layer.draw();
});
});
});
}); // end $(function(){});
</script>
</head>
<body>
<button id="myButton">Lomo the draggable Star</button>
<div id="container"></div>
</body>
</html>
After unsucessfull thread I'm asking for help again. How do I let the user add some text on the canvas by dragging text to their desired position? Let's say, they enter the text somewhere somehow, it appears on a canvas and then user can drag that text to desired position. Which technique I should use? Is there any way for someone to write a quick code?
Here's an outline of how to drag text on html canvas:
Create a text object that holds info about this word (text, x,y,width,height).
Create an array to hold all text objects
On mousedown, hit-test each text object in the array to see if the user mousedown'ed on a text
On mousemove, move the selected text by the distance that the user dragged the mouse
Demo: http://jsfiddle.net/m1erickson/tLvMK/
Here's commented 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 ctx=canvas.getContext("2d");
// variables used to get mouse position on the canvas
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();
// variables to save last mouse position
// used to see how far the user dragged the mouse
// and then move the text by that distance
var startX;
var startY;
// some text objects
var texts=[];
// some test texts
texts.push({text:"Hello",x:20,y:20});
texts.push({text:"World",x:20,y:70});
// calculate width of each text for hit-testing purposes
ctx.font="16px verdana";
for(var i=0;i<texts.length;i++){
var text=texts[i];
text.width=ctx.measureText(text.text).width;
text.height=16;
}
// this var will hold the index of the selected text
var selectedText=-1;
// START: draw all texts to the canvas
draw();
// clear the canvas draw all texts
function draw(){
ctx.clearRect(0,0,canvas.width,canvas.height);
for(var i=0;i<texts.length;i++){
var text=texts[i];
ctx.fillText(text.text,text.x,text.y);
}
}
// test if x,y is inside the bounding box of texts[textIndex]
function textHittest(x,y,textIndex){
var text=texts[textIndex];
return(x>=text.x &&
x<=text.x+text.width &&
y>=text.y-text.height &&
y<=text.y);
}
// handle mousedown events
// iterate through texts[] and see if the user
// mousedown'ed on one of them
// If yes, set the selectedText to the index of that text
function handleMouseDown(e){
e.preventDefault();
startX=parseInt(e.clientX-offsetX);
startY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
for(var i=0;i<texts.length;i++){
if(textHittest(startX,startY,i)){
selectedText=i;
}
}
}
// done dragging
function handleMouseUp(e){
e.preventDefault();
selectedText=-1;
}
// also done dragging
function handleMouseOut(e){
e.preventDefault();
selectedText=-1;
}
// handle mousemove events
// calc how far the mouse has been dragged since
// the last mousemove event and move the selected text
// by that distance
function handleMouseMove(e){
if(selectedText<0){return;}
e.preventDefault();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousemove stuff here
var dx=mouseX-startX;
var dy=mouseY-startY;
startX=mouseX;
startY=mouseY;
var text=texts[selectedText];
text.x+=dx;
text.y+=dy;
draw();
}
// listen for mouse events
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mousemove(function(e){handleMouseMove(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseOut(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>