Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

HTML5 Canvas CurvyTip

, 21 Mar 2013 MIT
CurvyTip HTML5 Canvas experiment.
CurvyTipSource.zip
function GetAngle(a,b,c){var d=100/a.segments*(b+c);return(a.endAngle-a.startAngle)*d/100+a.startAngle}function getX(a,b,c){return c+Math.cos(a*TO_RADIANS)*b}function getY(a,b,c){return c-Math.sin(a*TO_RADIANS)*b}function drawSegment(a,b){var c=a.radius,d=a.arcRadius,e=GetAngle(a,b,1),f=GetAngle(a,b,0),g=a.cX,h=a.cY/.5,i=parseInt(a.segments/2)==b,j=a.context,k=(e+f)/2,l=getX(e,c,g),m=getY(e,c,h),n=getX(e,c-d,g),o=getY(e,c-d,h),p=getX(f,c,g),q=getY(f,c,h),r=getX(f,c-d,g),s=getY(f,c-d,h),t=getX(k,c+a.ctxFactor,g),u=getY(k,c+a.ctxFactor,h),v=getX(k,c-d+a.ctxFactor,g),w=getX(k+4,c-d,g),x=getX(k-4,c-d,g),y=getY(k+4,c-d,h),z=getY(k-4,c-d,h),A=getX(k,c-d+a.ctxFactor,g),B=getY(k,c-d+a.ctxFactor,h+8),C=getY(k,c-d+a.ctxFactor,h);j.moveTo(l,m),j.quadraticCurveTo(l,m,n,o),j.moveTo(n,o),i?(j.quadraticCurveTo(n,o,x,z),j.lineTo(A,B),j.lineTo(w,y),j.quadraticCurveTo(r,s,r,s)):j.quadraticCurveTo(v,C,r,s),j.quadraticCurveTo(r,s,p,q),j.quadraticCurveTo(t,u,l,m)}function SetPosition(a){var b=a.anchor,c=10,d=getOffset(a.target),e=a.target.offsetWidth,f=a.target.offsetHeight,g=parseInt(a.segments/2),h=GetAngle(a,g,1),i=GetAngle(a,g,0),j=(h+i)/2,k=a.cY/.5;a.cX;var m=getY(j,a.radius-a.arcRadius+a.ctxFactor,k+8),n=0,o=0;switch(b){case"top":case null:default:n=d.left-a.canvas.width/2+a.target.offsetWidth/2,o=d.top-m-c;break;case"bottom":n=d.left-a.canvas.width/2+a.target.offsetWidth/2,o=d.top+f-(a.canvas.height-m)+c;break;case"left":n=d.left-c-m,o=d.top+f/2-m;break;case"right":n=d.left+e-(a.canvas.width-m)+c,o=d.top+f/2-m}setOpacity(a.canvas,1),a.canvas.setAttribute("style","display:block; left:"+n+"px; top:"+o+"px;z-index:9999")}function getOffset(a){for(var b=Object(),c=0,d=0;a;)c+=a.offsetTop,d+=a.offsetLeft,a=a.offsetParent;return b.left=d,b.top=c,b}function setOpacity(a,b){a.style.opacity=b,a.style.MozOpacity=b,a.style.KhtmlOpacity=b,a.style.filter="alpha(opacity="+100*b+")"}function fadeOut(a){var b=1,c=setInterval(function(){.1>=b&&(clearInterval(c),a.canvas.style.display="none",a.isbeingClosed=!1),setOpacity(a.canvas,b),b-=.1*b},15)}var TO_RADIANS=Math.PI/180,CurvyTip=function(a){new Image;var c=this,d=document.createElement("canvas");d.setAttribute("class","tooltip"),d.setAttribute("className","tooltip");var e=document.body;e.appendChild(d),this.canvas=d,this.canvas.width=200,this.canvas.height=200,this.context=this.canvas.getContext("2d"),this.stage=void 0,this.listening=!1,this.mousePos=null,this.mouseClick=!1,this.mouseOver=!1,this.mouseMove=!1,this.currentRegion=null,this.regionIndex=-1,this.lastRegionIndex=-1,this.mouseOverRegionIndex=-1,this.hasShadow=!0,this.target=document.getElementById(a),this.alwaysVisible=!1,this.hitSegment=-1,this.startAngle=130,this.endAngle=50,this.segments=3,this.radius=150,this.arcRadius=50,this.rotation=0,this.scale=1,this.tiles=[],this.images=[],this.currentRegionEvent={},this.anchor="top",this.isbeingClosed=!1,this.shadowColor="rgba(0,0,0,0.6)",this.backColor="rgba(0, 0, 0, 0.5)",this.mouseOverColor="rgba(128, 143, 255, 0.44)",this.width=this.canvas.width,this.height=this.canvas.height,this.cX=this.width/2,this.cY=this.height/2,this.ctxFactor=11.5*((this.startAngle-this.endAngle)/this.segments)/100,this.gradient=null,this.target.onmouseover=function(){c.isbeingClosed=!1,SetPosition(c),c.refresh()},document.addEventListener("click",function(){c.alwaysVisible||(c.isbeingClosed=!0,fadeOut(c))},!1),window.addEventListener("resize",function(){c.refresh()},!1),window.addEventListener?window.addEventListener("load",function(){c.refresh()},!1):window.attachEvent&&window.attachEvent("onload",function(){c.refresh()},!1),this.setStage(function(){(0==this.isbeingClosed&&"block"==this.canvas.style.display||this.alwaysVisible)&&(SetPosition(this),this.clearCvs(),this.context.save(),this.context.translate(this.cX,this.cY),this.context.rotate(this.rotation*TO_RADIANS),this.context.translate(-this.cX,-this.cY),this.context.scale(this.scale,this.scale),this.drawCanvas(),this.context.restore(),this.target.style.zIndex=this.canvas.style.zIndex+1)})};CurvyTip.prototype.reset=function(a){a||(a=window.event),null!=a&&this.setMousePosition(a),this.regionIndex=0,void 0!==this.stage&&this.stage(),this.mouseClick=!1,this.mouseOver=!1,this.mouseMove=!1},CurvyTip.prototype.listen=function(){var a=this;void 0!==this.stage&&this.stage(),this.canvas.addEventListener("click",function(b){a.mouseClick=!0,a.reset(b)},!1),this.canvas.addEventListener("mousemove",function(b){a.reset(b)},!1),this.canvas.addEventListener("mouseover",function(){a.mousePos=null},!1),this.canvas.addEventListener("mouseout",function(){a.mousePos=null},!1)},CurvyTip.prototype.getMousePos=function(){return this.mousePos},CurvyTip.prototype.setMousePosition=function(a){var b=a.clientX-this.getCanvasPos().left+window.pageXOffset,c=a.clientY-this.getCanvasPos().top+window.pageYOffset;this.mousePos={x:b,y:c}},CurvyTip.prototype.beginRegion=function(){this.currentRegion={},this.regionIndex++},CurvyTip.prototype.addRegionEventListener=function(a,b){var c="on"+a;this.currentRegion[c]=b},CurvyTip.prototype.closeRegion=function(){var a=this.mousePos;null!=a&&this.context.isPointInPath(a.x,a.y)?(this.lastRegionIndex!=this.regionIndex&&this.mouseOverRegionIndex!=this.lastRegionIndex&&(this.lastRegionIndex=this.regionIndex),this.mouseClick&&void 0!==this.currentRegion.onclick?(this.currentRegion.onclick(),this.mouseClick=!1):this.mouseOver||-1!=this.lastRegionIndex||this.regionIndex==this.mouseOverRegionIndex||void 0===this.currentRegion.onmouseover||(this.currentRegion.onmouseover(),this.mouseOver=!0,this.mouseOverRegionIndex=this.regionIndex)):this.regionIndex==this.lastRegionIndex&&(this.mouseOverRegionIndex=-1,this.lastRegionIndex=-1,void 0!==this.currentRegion.onmouseout&&this.currentRegion.onmouseout())},CurvyTip.prototype.getCanvasPos=function(){for(var a=this.canvas,b=0,c=0;null!=a&&"BODY"!=a.tagName;)b+=a.offsetTop,c+=a.offsetLeft,a=a.offsetParent;return{top:b,left:c}},CurvyTip.prototype.setStage=function(a){this.stage=a,this.listen()},CurvyTip.prototype.clear=function(){this.context.clearRect(0,0,this.canvas.width,this.canvas.height)},CurvyTip.prototype.refresh=function(){this.isbeingClosed||this.reset()},CurvyTip.prototype.setOptions=function(a){var b;for(b in a)this.hasOwnProperty(b)&&(this[b]=a[b],"images"==b&&this.setupImages());return this},CurvyTip.prototype.setupImages=function(){var a=this;for(this.tiles=[],x=0;this.segments>=x;x++){var b=new Image;b.src=this.images[x],this.tiles.push(b),b.onload=function(){setTimeout(function(){a.refresh()},0)}}return this},CurvyTip.prototype.addListener=function(a,b){var c="on"+a;return this.currentRegionEvent[c]=b,!1},CurvyTip.prototype.removeListener=function(a){var c="on"+a;return this.currentRegionEvent[c]=void 0,!1},CurvyTip.prototype.clearCvs=function(){this.isbeingClosed||this.context.clearRect(0,0,this.width,this.height)},CurvyTip.prototype.drawCanvas=function(){if(null==this.gradient){var a=this.context.createLinearGradient(0,0,0,this.cY/.75);a.addColorStop(0,"rgb(255, 255, 255)"),a.addColorStop(1,this.backColor),this.context.fillStyle=a}else this.context.fillStyle=this.gradient;if(this.context.lineWidth=.5,this.context.strokeStyle="black",this.hasShadow){this.context.save(),this.context.beginPath(),this.context.shadowColor=this.shadowColor,this.context.shadowBlur=5,this.context.shadowOffsetX=0,this.context.shadowOffsetY=5;for(var b=0;this.segments>b;b++)drawSegment(this,b);this.context.closePath(),this.context.fill(),this.context.restore()}for(var b=0;this.segments>b;b++){this.beginRegion(),this.context.beginPath(),drawSegment(this,b),this.context.fill(),this.context.stroke(),this.context.closePath();var c=this;this.addRegionEventListener("mouseover",function(){c.hitSegment=b,void 0!==c.currentRegionEvent.onmouseover&&c.currentRegionEvent.onmouseover(b)}),this.addRegionEventListener("click",function(){void 0!==c.currentRegionEvent.onclick&&c.currentRegionEvent.onclick(b)}),this.addRegionEventListener("mouseout",function(){c.hitSegment=-1,void 0!==c.currentRegionEvent.onmouseout&&c.currentRegionEvent.onmouseout(b)}),this.closeRegion()}for(var b=0;this.segments>b;b++){var d=GetAngle(this,b,1),e=GetAngle(this,b,0),f=this.cX,g=this.cY/.5,h=(d+e)/2,i=getX(h,this.radius-this.arcRadius/2,f),j=getY(h,this.radius-this.arcRadius/2,g);this.hitSegment==b&&(this.context.save(),this.context.beginPath(),drawSegment(this,b),this.context.fillStyle=this.mouseOverColor,this.context.fill(),this.context.closePath(),this.context.restore()),this.tiles[b]!==void 0&&(this.context.save(),this.context.shadowColor="rgb(0, 0, 0)",this.context.shadowOffsetX=0,this.context.shadowOffsetY=-1,this.context.shadowBlur=1,this.context.translate(i,j),this.context.rotate(-this.rotation*TO_RADIANS),this.context.drawImage(this.tiles[b],-(this.tiles[b].width/2),-(this.tiles[b].height/2)),this.context.restore())}};

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

sistec

United States United States
No Biography provided

| Advertise | Privacy | Terms of Use | Mobile
Web03 | 2.8.150129.1 | Last Updated 21 Mar 2013
Article Copyright 2013 by sistec
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid