Click here to Skip to main content
11,711,009 members (83,386 online)
Click here to Skip to main content
Add your own
alternative version

HTML5 Canvas CurvyTip

, 21 Mar 2013 MIT 53.4K 693 58
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

You may also be interested in...

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