Create Links in HTML Canvas

Create links in HTML canvas

There is no easy way. You will have to draw the link text onto the canvas and then check for mouseclicks. Here is a demo html page:

<html>
<head>
<script type="text/javascript">
var canvas = document.getElementById("myCanvas");
var ctx;
var linkText="https://stackoverflow.com";
var linkX=5;
var linkY=15;
var linkHeight=10;
var linkWidth;
var inLink = false;

// draw the balls on the canvas
function draw(){
canvas = document.getElementById("myCanvas");
// check if supported
if(canvas.getContext){

ctx=canvas.getContext("2d");

//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);

//draw the link
ctx.font='10px sans-serif';
ctx.fillStyle = "#0000ff";
ctx.fillText(linkText,linkX,linkY);
linkWidth=ctx.measureText(linkText).width;

//add mouse listeners
canvas.addEventListener("mousemove", on_mousemove, false);
canvas.addEventListener("click", on_click, false);

}
}

//check if the mouse is over the link and change cursor style
function on_mousemove (ev) {
var x, y;

// Get the mouse position relative to the canvas element.
if (ev.layerX || ev.layerX == 0) { //for firefox
x = ev.layerX;
y = ev.layerY;
}
x-=canvas.offsetLeft;
y-=canvas.offsetTop;

//is the mouse over the link?
if(x>=linkX && x <= (linkX + linkWidth) && y<=linkY && y>= (linkY-linkHeight)){
document.body.style.cursor = "pointer";
inLink=true;
}
else{
document.body.style.cursor = "";
inLink=false;
}
}

//if the link has been clicked, go to link
function on_click(e) {
if (inLink) {
window.location = linkText;
}
}
</script>
</head>
<body onload="draw()">
<center>
<canvas id="myCanvas" width="200" height="200" style="border-style:solid;border-width:1px">Canvas not supported.</canvas>
</center>
</body>
</html>

Add Href to canvas element

You can test which hexagon you mouse clicked using context.isPointInPath.

  • Listen for mousedown events
  • In mousedown, fetch the mouseX, mouseY
  • Recreate each of your hex paths (no need to actually stroke/fill them).
  • For each hex, use .isPointInPath(mouseX,mouseY) to see if the mouse clicked in this hex.
  • If you find a clicked hex, use window.open(theUrl, '_blank') to navigate to its associated url.

In Hexagon Tools, each hex has a points property which you can use to receate each of your hex paths.

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(); }
var isDown=false;var startX,startY;
var hexes=[];hexes.push({ points:[{x:57.5,y:63},{x:42.5,y:63},{x:35,y:50},{x:42.5,y:37},{x:57.5,y:37},{x:65,y:50}], url:'http://stackoverflow.com',});
draw();
$("#canvas").mousedown(function(e){handleMouseDown(e);});
function draw(){ for(var i=0;i<hexes.length;i++){ var h=hexes[i]; ctx.beginPath(); ctx.moveTo(h.points[0].x,h.points[0].y); for(var j=1;j<h.points.length;j++){ ctx.lineTo(h.points[j].x,h.points[j].y); } ctx.closePath(); ctx.stroke(); }}

function handleMouseDown(e){ // tell the browser we're handling this event e.preventDefault(); e.stopPropagation();
mouseX=parseInt(e.clientX-offsetX); mouseY=parseInt(e.clientY-offsetY);
for(var i=0;i<hexes.length;i++){ var h=hexes[i]; ctx.beginPath(); ctx.moveTo(h.points[0].x,h.points[0].y); for(var j=1;j<h.points.length;j++){ ctx.lineTo(h.points[j].x,h.points[j].y); } ctx.closePath(); //if(ctx.isPointInPath(mouseX,mouseY)){ window.open(h.url, '_blank'); } if(ctx.isPointInPath(mouseX,mouseY)){ alert('Navigate to: '+h.url); } }}
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>Click in the hexagon to navigate to Stackoverflow.com</h4><canvas id="canvas" width=300 height=300></canvas>

How to add hyperlink to image in canvas element?

I got it working. Here is the [DEMO]

var canvas = document.getElementById("myCanvas");
var ctx;
var linkText="http://google.com";
var linkX=5;
var linkY=15;
var linkHeight=10;
var linkWidth;
var inLink = false;

// draw the balls on the canvas
function draw(){
canvas = document.getElementById("myCanvas");
// check if supported
if(canvas.getContext){

ctx=canvas.getContext("2d");

//clear canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);

//draw the link
ctx.font='10px sans-serif';
ctx.fillStyle = "#0000ff";
ctx.fillText(linkText,linkX,linkY);
linkWidth=ctx.measureText(linkText).width;

//add mouse listeners
canvas.addEventListener("mousemove", on_mousemove, false);
canvas.addEventListener("click", on_click, false);

}
}

//check if the mouse is over the link and change cursor style
function on_mousemove (ev) {
var x, y;

// Get the mouse position relative to the canvas element.
if (ev.layerX || ev.layerX == 0) { //for firefox
x = ev.layerX;
y = ev.layerY;
}
x-=canvas.offsetLeft;
y-=canvas.offsetTop;

//is the mouse over the link?
if(x>=linkX && x <= (linkX + linkWidth) && y<=linkY && y>= (linkY-linkHeight)){
document.body.style.cursor = "pointer";
inLink=true;
}
else{
document.body.style.cursor = "";
inLink=false;
}
}

//if the link has been clicked, go to link
function on_click(e) {
if (inLink) {
window.location = linkText;
}
}

draw();

creating multiple links on html5 canvas

I can see a couple of problems here.

(1) you reset inLink to "" inside the loop. This means that if you hover over a link, remaining links in the loop will not be hovered over, and will reset inLink to "" - fix = set inLink to "" once, before the loop (you can't hover over more than one link at a time, so it can only be set once inside the loop)

(2) You've inconsistently 'spelt' inLink. - fix = ensure capitalization is the same for all instances of the variable (inLink is different to inlink)

(3) The placement of brackets in the check if you're over a link has the potential to be ambiguous.

(4) By using links.length in the for loop, it needs to be recalculated each time through the loop. A better approach is to read this value once and store it in a temporary variable.

Here's a rough example of the code working just fine, as tested in Chrome (no FF here, unfortunately)

Note: I've also added the break to discontinue the loop if a hovered link is found - there's no need to check the remaining ones in the loop if you find one successfully. (This speeds up execution, while also achieving the same effect as point #1)

Note2: It is faster to iterate through the loop from n-1 to 0, as you had initially done - I just prefer to go forwards.

<!DOCTYPE html>
<html>
<head>
<script>
function byId(e){return document.getElementById(e);}

window.addEventListener('load', onDocLoaded, false);

function onDocLoaded()
{
outlineLinks();
byId('can').addEventListener("mousemove", on_mousemove, false);
// byId('can').addEventListener("click", on_click2, false);
byId('can').addEventListener("click", on_click, false);
}

// var link = ["websitelink1", "websitelink2"];
var link = ["http://stackoverflow.com/questions/24650947/creating-multiple-links-on-html5-canvas/24652217", "http://stackoverflow.com/"];
var links = [[0,0,100,20],[0,25,100,20]];

var inLink = "";

function outlineLinks()
{
var canvas = byId('can');
var ctx = canvas.getContext('2d');

var i, n = links.length;
for (i=0; i<n; i++)
ctx.strokeRect( links[i][0], links[i][1], links[i][2], links[i][3] );
}

function on_mousemove(evt)
{
var mouse_x, mouse_y;

// Get the mouse position relative to the canvas element.
if (evt.layerX || evt.layerX)
{ //for firefox
mouse_x = evt.layerX;
mouse_y = evt.layerY;
}
mouse_x -= this.offsetLeft;
mouse_y -= this.offsetTop;

byId('coords').innerHTML = "Mouse Pos: " + mouse_x + "," + mouse_y;

var n = links.length;
inLink = "";
for(i=0; i<n; i++)
{
var linkX = parseInt(links[i][0]),
linkY = parseInt(links[i][1]),
linkwidth = parseInt(links[i][2]),
linkheight = parseInt(links[i][3]);

//is the mouse over the link?
if( (mouse_x >= linkX) && (mouse_x <= (linkX + linkwidth)) && (mouse_y >= linkY) && (mouse_y <= (linkY + linkheight)))
{
document.body.style.cursor = "pointer";
inLink = link[i];
break;
}
else{
document.body.style.cursor = "";
}
}
}
function on_click(evt)
{
if (inLink != "")
window.open(inLink);
}

function on_click2(evt)
{
if (inLink != "")
byId('tgt').innerHTML = "Navigating to: " + inLink;
else
byId('tgt').innerHTML = "No link is hovered";
}

</script>
<style>
</style>
</head>
<body>
<div id='tgt'> </div>
<div id='coords'> </div>
<canvas id='can'></canvas>
</body>
</html>

Adding a link to a dynamic canvas

I have managed to click on a certain element in a canvas.

I have tried to explain with comments what it does.
I have made 3 limits as shown in the image below.
image with limits

And I'm comparing only with x value, if it's in between these limits. It can be more complex so getCursorPosition() method returns an object with x and y components, just in case if you need to make more comparisons.

https://jsfiddle.net/_jserodio/asa10pye/

    var canvas;    var ctx;
// first get your canvas canvas = document.getElementById('canvas'); canvas.width = 253; canvas.heigth = 68;
// assign the context ctx = canvas.getContext("2d");
// asign click event to the canvas addEventListener("click", listener, false);
function listener(e) { // if you have 3 buttons var position = getCursorPosition(e);
var limit1 = canvas.width / 3; //console.log("limit1: " + limit1); var limit2 = canvas.width * 2 / 3; //console.log("limit2: " + limit2); var limit3 = canvas.width; //console.log("limit3: " + limit3);
if (position.x < limit1) { console.log("go to facebook"); //window.open("http://www.facebook.com"); } else if (position.x < limit2) { console.log("go to twitter"); //window.open("http://www.twitter.com"); } else if (position.x < limit3) { console.log("go to whatsapp"); //window.open("http://www.whatsapp.com"); }
//console.log("\nx" + position.x); //console.log("y" + position.y); }
function getCursorPosition(event) { var rect = canvas.getBoundingClientRect(); var x = event.clientX - rect.left; var y = event.clientY - rect.top; var data = { x: x, y: y }; return data; }
// load image from data url var imageObj = new Image(); imageObj.onload = function() { ctx.drawImage(this, 0, 0); };
imageObj.src = 'https://justpaste.it/files/justpaste/d307/a11791570/file1.png';
<canvas id='canvas' width="253" height="68">
</canvas>


Related Topics



Leave a reply



Submit