Working with hyperlinks in canvas

I wanted to provide a way to hyperlink to the most popular page in the topic and the most popular topic on the site from within the gadget. However you can't use <a></a> tags. Instead you need to detect whether the mouse is positioned over the link text by watching its position. 

First make an array of the text of links that need watching, along with their co-ordinates and length. We can use .measureText() to get the width of text rendered in a canvas.

links = [data.page,data.topic].map ( function (l,j) {

return {

url:selectLink(l,siteUrl),

title:l.analytics[l.analytics.length-1].favoriteTitle,

x:left + options.textSpace + j*(options.barLength + options.horizontalBetween ),

y:top,

width:0,

height:0

};

});


links.forEach(function(l) {

l.width = fillText (l.y, l.x, l.title, options.linkColor).width;

l.height = options.textHeight *1.2;

});

  

             function canvasText (cx,top,left,text,color,align,textPx) {

   cx.font = textPx;

        cx.fillStyle = color;

        cx.textAlign = align || 'left';

        cx.fillText(text, left, top);

        return cx.measureText (text);

   }


Next we need to watch out for movement or clicks

        

             canvas.addEventListener("mousemove",linkHover,false);

canvas.addEventListener("click",linkClick,false);


And if they are triggered, see if we are over any links, and react if they are

               // happens when a link is hovered over

      function linkHover(e) {

      var target = overLink(e);

     if (target) {

          document.body.style.cursor = "pointer";

     }

     else {

     document.body.style.cursor = "";

     }

      }


        // happens when a  link is clicked

      function linkClick (e) {

     var target = overLink(e);

     if (target) {

window.top.location = target.url;

     }

      }


        // check if we are over a link

      function overLink (e) {

     if (links) {


     x = (e.layerX || 0) - canvas.offsetLeft;

     y = (e.layerY || 0) - canvas.offsetTop;


     var target = links.filter ( function (l) {

     return l.x < x &&  l.x  + l.width > x  && l.y > y && l.y - l.height < y;

     });

     return target.length ? target[0] : null;

     }

     else {

     return null;

     }

      }



For help and more information join our forum,follow the blog or follow me on twitter .




Comments