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>
Related
I have an image of 4000px by 3000px. I want to display this image on an html page and allow users to select coordinates over this image.
Actually I have to replicate from this:
https://www.botb.com/CompetitionPlay.aspx?SiteID=1®ion=GB&cid=2ca08b9b-4717-474c-b5ec-1e6a40df6d54&play=1
(Please register and see this element. Its free to sign up)
Actually I want to display this 4000x3000px picture in 700x500px div size but the user should be able to select coordinates in the picture relative to its actual size i.e 4000x3000px.
The problem with simple approach of scaling the pixels is that the user is only able to select coordinates from downscaled pixels. I want the user to able to select a coordinate from 4000*3000 possibilities
How can I fix a large dimensions image into that size and make magnify tool just like the one in the above? Is it possible in using html5 canvas?
If you can share any jquery plugin for this then I will be very grateful.
Image at 25% size:
Image with magnified section (magnified section is 100% size)
Here's code to magnify the image when the user holds the mouse down over their desired magnification point.
The code uses a second overlaying canvas to present a portion of the magnified (full-sized) image.
Example code and a Demo:
This starting example uses a fixed size magnification viewport, but you can adjust to let the user use mousedown+mouseup to define a variable sized viewport.
var canvas=document.getElementById("canvas");
var ctx=canvas.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 magifier=document.getElementById("magnifier");
var mctx=magnifier.getContext("2d");
var $magnifier=$('#magnifier');
var mw=100;
var mh=100;
var downscale=0.25;
var upscale=1/downscale;
var iw,ih;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/soccer.jpg";
function start(){
magnify();
iw=img.width;
ih=img.height;
cw=canvas.width=iw*downscale;
ch=canvas.height=ih*downscale;
ctx.drawImage(img,0,0,cw,ch);
$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas,#magnifier").mouseup(function(e){handleMouseUp(e);});
}
function magnify(x,y){
if(!x){$magnifier.css({left:-999}); return;};
$magnifier.css({left:x-mw/2,top:y-mh/2});
mctx.clearRect(0,0,mw,mh);
mctx.drawImage(img,-(x)*upscale+mw/2,-(y)*upscale+mh/2);
}
function handleMouseDown(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);
magnify(x,y);
}
function handleMouseUp(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
magnify();
}
body{ background-color: ivory; }
#container{position:relative;}
#canvas{position:absolute;border:1px solid red;}
#magnifier{position:absolute;border:3px solid blue;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hold mouse down for magnified view.</h4>
<div id=container>
<canvas id="canvas" width=300 height=300></canvas>
<canvas id="magnifier" width=100 height=100></canvas>
</div>
maybe something like this, you can use this to calculate the ratio to the original size too, just do the multiplication.
var element = document.getElementById("box");
element.onmousemove = function(e) {
var x = e.pageX - this.offsetLeft;
var y = e.pageY - this.offsetTop;
show(x, y);
}
function show(x, y) {
coords.innerHTML = "(" + x + "," + y + ")";
}
#box {
border: 2px solid black;
background: lightblue;
width: 200px;
height: 150px;
cursor: crosshair;
background-image: url('http://lorempixel.com/200/150/');
}
body {
margin: 10px;
}
Coords <span id="coords">(X,Y)</span>
<div id="box"></div>
I have an HTML canvas with all different shapes of all different sizes and it is built by parsing information from an external file. I am wondering how I can make it so that hovering the mouse over each shape will display its unique name. I have found resources on how to display text on a mouse hover for the whole canvas, but I need each individual shape to display a unique text. Thanks!
You can use context.isPointInPath to test if your mouse is hovering over one of your shapes.
Create a javascript object representing each shape from the external file.
var triangle={
name:'triangle',
color:'skyblue',
points:[{x:100,y:100},{x:150,y:150},{x:50,y:150}]
};
Create a function that takes a shape-object and makes a Path from that shape-object:
function defineShape(s){
ctx.beginPath();
ctx.moveTo(s[0].x,s[0].y);
for(var i=1;i<s.length;i++){
ctx.lineTo(s[i].x,s[i].y);
}
ctx.closePath();
}
Use context.isPointInPath to test if the mouse is inside the most recently defined path (from step#2).
// define the path to be tested
defineShape(triangle);
// test if the mouse is inside that shape
if(context.isPointInPath(mouseX,mouseY){
// the mouse is inside the shape
}
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.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(); }
ctx.font='14px verdana';
var shapes=[];
var triangle1={
name:'triangle1',
color:'skyblue',
drawcolor:'skyblue',
points:[{x:100,y:100},{x:150,y:150},{x:50,y:150}]
};
var triangle2={
name:'triangle2',
color:'palegreen',
drawcolor:'palegreen',
points:[{x:220,y:100},{x:270,y:150},{x:170,y:150}]
};
shapes.push(triangle1,triangle2);
$("#canvas").mousemove(function(e){handleMouseMove(e);});
drawAll();
function drawAll(){
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
defineShape(s.points);
ctx.fillStyle=s.drawcolor;
ctx.fill();
ctx.stroke();
if(s.color!==s.drawcolor){
ctx.fillStyle='black';
ctx.fillText(s.name,s.points[0].x,s.points[0].y);
}
}
}
function defineShape(s){
ctx.beginPath();
ctx.moveTo(s[0].x,s[0].y);
for(var i=1;i<s.length;i++){
ctx.lineTo(s[i].x,s[i].y);
}
ctx.closePath();
}
function handleMouseMove(e){
// tell the browser we're handling this event
e.preventDefault();
e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// clear the canvas
ctx.clearRect(0,0,cw,ch);
for(var i=0;i<shapes.length;i++){
var s=shapes[i];
// define the shape path we want to test against the mouse position
defineShape(s.points);
// is the mouse insied the defined shape?
if(ctx.isPointInPath(mouseX,mouseY)){
// if yes, fill the shape in red
s.drawcolor='red';
}else{
// if no, fill the shape with blue
s.drawcolor=s.color;
}
}
drawAll();
}
body{ background-color: ivory; }
#canvas{border:1px solid red; margin:0 auto; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Hover the mouse over the shape.</h4>
<canvas id="canvas" width=300 height=300></canvas>
Are you willing to use a library, or are you attached to a purely native canvas implementation? With purely native canvas, this could get quite annoying, because you would have to not only get the mouse coordinates of the pointer, but also keep track of the position of every object and check whether or not the mouse is at that position every time the mouse moves. I coded that functionality once, and it was annoying enough with just a few rectangles to keep track of.
On the other hand, if you use KineticJS to do your canvas drawing (or presumably others; KineticJS is just the one I've used), all that annoyance is handled for you. The objects you create and add to the canvas can have event handlers attached to them using the KineticJS library, and it will be only minimally harder than reacting to mouseover events on any other HTML element. This link shows how to do it.
http://www.html5canvastutorials.com/kineticjs/html5-canvas-listen-or-dont-listen-to-events-with-kineticjs/
Hello I have this script that checks for transparent pixels and non transparent pixels. Now i made it so the result is coming from 100px by 100px rectangle on mouse over:
var data = ctx.getImageData(100,100, canvas.width, canvas.height).data;
And right now it shows on mouse of over the result of Opague area and Transparent area.
I would like somehow to visualise this rectangle on load with a grid overlaying the image and the oppaque boxes and transparent one to have different colours like oppaque is green transparent is red. I need probably on load function? But how should it look?
I am stuck here and need someone to direct me in the right position
and here is my current progress:
https://jsfiddle.net/kdichev/Lnp3k5re/
Since you probably want the game console to still show, you can draw your 100x100 boxes with a reduced alpha (globalAlpha).
Here's example code and a Demo:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var boxWidth=100;
var boxHeight=100;
var boxRows=Math.ceil(865/boxHeight);
var boxCols=Math.ceil(1152/boxWidth);
var boxes=new Array(boxRows*boxCols);
for(var i=0;i<boxes.length;i++){boxes[i]=false;}
var img=new Image();
img.onload=start;
img.crossOrigin='anonymous';
img.src="http://i.imgur.com/RrHayx8.png?1";
function start(){
ctx.drawImage(img,0,0);
var d=ctx.getImageData(0,0,cw,ch).data;
for(var i=0;i<d.length;i+=4){
if(d[i+3]>200){
var px=parseInt(i/4);
var pixelY=parseInt(px/cw);
var pixelX=px-pixelY*cw;
var boxX=parseInt(pixelX/boxWidth);
var boxY=parseInt(pixelY/boxHeight);
boxes[boxY*boxCols+boxX]=true;
}
}
ctx.globalAlpha=0.25;
ctx.fillStyle='red';
for(var i=0;i<boxes.length;i++){
var y=parseInt(i/boxCols);
var x=i-y*boxCols;
if(boxes[i]==true){
ctx.fillRect(x*boxWidth,y*boxHeight,boxWidth,boxHeight);
}
}
ctx.globalAlpha=1.00;
ctx.fillStyle='black';
}
body{ background-color: ivory; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=1152 height=865></canvas>
I want to do something like this in the canvas with Javascript.
I want to blur a square. I looked for it on the internet but I didn't find anything. If I don't have to use an external JS library, it'll be better.
[EDIT]I'm not refering to the Finder Icon but the square that is behind it.[/EDIT]
Stackoverflow's Ken Fyrstenberg has authored a very nice blur script here:
https://github.com/epistemex/realtime-blur-js
Here's an example using Ken's blur plus a tinted 25% opaque rectangle:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/wingedLion.jpg";
function start(){
var tempcanvas=document.createElement("canvas");
var tctx=tempcanvas.getContext("2d");
cw=canvas.width=tempcanvas.width=img.width;
ch=canvas.height=tempcanvas.height=img.height;
var x=50;
var y=250;
var w=325;
var h=75;
tctx.drawImage(img,0,0);
var rtblur;
rtblur=new RTBlur({source:tempcanvas});
rtblur.blur(0.50,tctx);
ctx.drawImage(img,0,0);
ctx.drawImage(tempcanvas, x,y,w,h, x,y,w,h);
ctx.fillStyle='tan';
ctx.globalAlpha=0.250;
ctx.fillRect(x,y,w,h);
ctx.globalAlpha=1.00;
ctx.strokeStyle='darkgray';
ctx.lineWidth=2;
ctx.strokeRect(x,y,w,h);
ctx.font='18px verdana';
ctx.fillStyle='white';
ctx.fillText('A rect with blurred background',x+20,y+30);
ctx.fillText('and a tan 25% opacity tint',x+20,y+55);
}
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
<script src="https://cdn.rawgit.com/epistemex/realtime-blur-js/master/rtblur.js"></script>
<canvas id="canvas" width=300 height=300></canvas>
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>