Html graphics rendering control like the BitBucket one - html
I'm trying to find out what graphics library is BitBucket using to create the visualization of the commit graph (the lines on the left), if it's public.
If the library used by BitBucket is not available open source or commercially, what would be some alternative HTML 5 based libraries can be used to achieve similar effects ?
This is not for a VCS system but for other kind of project
Here's code to draw the primitives in the commit graph:
lines: that curve into columnar tracks
branches: that split a single line into 2
dots: representing events
A Demo: http://jsfiddle.net/m1erickson/cz37L/
Example code:
<!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; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
ctx.lineWidth=2;
var offsetX=20;
var offsetY=10;
var spacingX=12;
var spacingY=25;
var y=0;
// lines
var lines=[];
lines.push([0,0,0,0,1,1,2,2,2,2,2,2,2,2,2,2,3]);
lines.push([1,1,1,1,2,2,3,3,3,3,3,3,3,3,3,3,4]);
lines.push([2,2,2,2,3,3,4,4,4,4,4,4,4,4,4,4,5]);
lines.push([3,3,3,3,4,4]);
lines.push([4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5]);
lines.push([5,5,5,5]);
var branches=[];
branches.push({line:2,x1:4,y1:5,x2:4,y2:4});
branches.push({line:3,x1:5,y1:2,x2:4,y2:3});
branches.push({line:4,x1:5,y1:6,x2:4,y2:5});
branches.push({line:4,x1:5,y1:14,x2:4,y2:13});
// dots
var events1=[5,5,5,4,4,4,5,4,4,4,4,4,4,4,5,5];
var events2=[5,5,5,3,3,2,4,2,2,2,2,2,2,2,4,2];
var colors=["purple","olive","cyan","magenta","khaki","green"];
drawAll();
function drawAll(){
for(var i=0;i<lines.length;i++){
drawLine(lines[i],colors[i]);
}
for(var i=0;i<branches.length;i++){
drawBranch(branches[i],colors[branches[i].line]);
}
for(var i=0;i<events1.length;i++){
ctx.beginPath();
ctx.arc(offsetX+events1[i]*spacingX,offsetY+i*spacingY,3,0,Math.PI*2);
ctx.closePath();
ctx.fillStyle=colors[events2[i]];
ctx.fill();
}
}
function drawBranch(branch,linecolor){
var x1=offsetX+branch.x1*spacingX;
var x2=offsetX+branch.x2*spacingX;
var y1=offsetY+branch.y1*spacingY;
var y2=offsetY+branch.y2*spacingY;
var cy=cy2=y1+(y2-y1)/2;
ctx.beginPath();
ctx.moveTo(offsetX+branch.x1*spacingX,offsetY+branch.y1*spacingY);
ctx.bezierCurveTo(x1,cy,x2,cy,x2,y2);
ctx.strokeStyle=linecolor;
ctx.stroke();
}
function drawLine(line,linecolor){
var y=0;
ctx.beginPath();
ctx.moveTo(offsetX+line[0]*spacingX,offsetY+y*spacingY);
for(var i=1;i<line.length;i++){
if(line[i]==line[i-1]){
ctx.lineTo(offsetX+line[i]*spacingX,offsetY+y*spacingY);
}else{
var x1=offsetX+line[i-1]*spacingX;
var x2=offsetX+line[i]*spacingX;
var y1=offsetY+(y-1)*spacingY;
var y2=offsetY+y*spacingY;
var cy=cy2=y1+(y2-y1)/2;
ctx.bezierCurveTo(x1,cy,x2,cy,x2,y2);
}
y++;
}
ctx.strokeStyle=linecolor;
ctx.stroke();
}
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=400></canvas>
</body>
</html>
Related
move multiple images from one canvas to other canvas
There is an example given at http://www.rgraph.net/blog/2013/january/an-example-of-html5-canvas-drag-n-drop.html I am not able to add multiple images into canvas 1 and move those added images to canvas 2. Also I should be able to drag(move the added image within canvas 2) those added images in second canvas.
function dragDrop(e, ui) { // get the drop point (be sure to adjust for border) var x = parseInt(ui.offset.left - offsetX) - 1; var y = parseInt(ui.offset.top - offsetY); // get the drop payload (here the payload is the $tools index) var theIndex = ui.draggable.data("toolsIndex"); // drawImage at the drop point using the dropped image ctx.drawImage($tools[theIndex], x, y, 32, 32); } http://jsfiddle.net/cyur7/ This jsfiddle link is working fine.
This solution uses the KineticJS library to accomplish your need. Here is code and a Fiddle: http://jsfiddle.net/m1erickson/bSpBF/ <!DOCTYPE html> <html> <head> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script> <style> body{ background-color: ivory; padding:10px;} #container1,#container2{ border:solid 1px #ccc; margin-top: 10px; width:300px; height:100px; } #container2{ height:300px; } </style> <script> $(function(){ var highlightWidth=8; var stage = new Kinetic.Stage({ container: 'container1', width: 300, height: 100 }); var layer = new Kinetic.Layer(); stage.add(layer); var dropzone = new Kinetic.Stage({ container: 'container2', width: 300, height: 300 }); var dropLayer = new Kinetic.Layer(); dropzone.add(dropLayer); // these must go after the creation of stages & layers addBackground(stage,layer,dropLayer); layer.draw(); addBackground(dropzone,dropLayer,layer); dropLayer.draw(); // get images & then trigger start() var images={}; var URLs = { house1: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-3.jpg', house2: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-4.jpg', house3: 'https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house204-1.jpg' }; loadImages(URLs,start); function start(){ var house1=kImage(images.house1,10,10,50,50,layer); var house2=kImage(images.house2,75,10,50,50,layer); var house3=kImage(images.house3,140,10,50,50,layer); layer.draw(); } function swapStagesIfSelected(sourceLayer,destinationLayer,startX,startY){ // get all elements on the source layer var elements=sourceLayer.get("Image"); // don't let dropped elements fall off the stage var totalWidth=0; var maxHeight=-999; var layerWidth=destinationLayer.getStage().getWidth(); var layerHeight=destinationLayer.getStage().getHeight(); for(var i=0;i<elements.length;i++){ if(elements[i].isSelected){ totalWidth+=elements[i].getWidth(); maxHeight=Math.max(elements[i].getHeight(),maxHeight); } } if(startX+totalWidth>layerWidth){ startX=layerWidth-totalWidth-15; } if(startY+maxHeight>layerHeight){ startY=layerHeight-maxHeight-15; } // move all selected images // to the clicked x/y of the destination layer for(var i=0;i<elements.length;i++){ var element=elements[i]; if(element.isSelected){ var img=element.getImage(); kImage(img,startX,startY,element.getWidth(),element.getHeight(),destinationLayer); startX+=element.getWidth()+10; element.remove(); } } sourceLayer.draw(); destinationLayer.draw(); } // build the specified KineticJS Image and add it to the specified layer function kImage(image,x,y,width,height,theLayer){ var image=new Kinetic.Image({ image:image, x:x, y:y, width:width, height:height, strokeWidth:0.1, stroke:"green", draggable:true }); image.myLayer=theLayer; image.isSelected=false; image.on("click",function(){ highlight(this); this.myLayer.draw(); }); image.myLayer.add(image); return(image); } // build a background image and add it to the specified stage function addBackground(theStage,theLayer,otherLayer){ var background = new Kinetic.Rect({ x: 0, y: 0, width: theStage.getWidth(), height: theStage.getHeight(), fill: "white", stroke: "green", strokeWidth: 1 }); background.on("click",function(){ var pos=theStage.getMousePosition(); var mouseX=parseInt(pos.x); var mouseY=parseInt(pos.y); swapStagesIfSelected(otherLayer,theLayer,mouseX,mouseY); }); theLayer.add(background); } ///////////// Image loader function loadImages(URLs, callback) { var loaded = 0; var needed = 0; for(var url in URLs) { needed++; console.log(url); } for(var url in URLs) { images[url] = new Image(); images[url].onload = function() { if(++loaded >= needed) { callback(images); } }; images[url].src = URLs[url]; } } ///////////// Toggle Highlighting function highlight(element,setStrokeWidth){ if(setStrokeWidth){ element.setStrokeWidth(setStrokeWidth); }else{ if(element.getStrokeWidth()>5){ element.setStrokeWidth(0.1); element.isSelected=false; }else{ element.setStrokeWidth(highlightWidth); element.isSelected=true; } } } }); // end $(function(){}); </script> </head> <body> <p>Click on image(s) to toggle selection</p> <p>Then click in the other canvas to drop</p> <div id="container1"></div> <div id="container2"></div> <button id="clear">Clear Hightlights</button> <button id="swap">Swap Selected</button> </body> </html>
HTML5 Canvas - Context Sensitive Menu
I'm drawing a number of rectangles on an HTML5 canvas and want to be able to right click on the boxes and get a context sensitive menu displayed. The menu should be specific to the type of box being clicked on and be totally user specified, i.e. it should not include Reload, Save As, Print etc... Can any one give me any pointers? Thanks, Paul
You can addEventListener for context menu to handle right-mouse requests: // listen for contextmenu requests canvas.addEventListener('contextmenu', handleContextmenu, false); Then in the handler, you check each of your rects for hits: function handleContextmenu(e){ // get mouse position relative to the canvas var x=parseInt(e.clientX-offsetX); var y=parseInt(e.clientY-offsetY); // check each rect for hits for(var i=0;i<rects.length;i++){ var rect=rects[i]; var rectRight=rect.x+rect.width; var rectBottom=rect.y+rect.height; // if this rect is hit, display an alert if(x>=rect.x && x<=rectRight && y>=rect.y && y<=rectBottom ){ alert("Context menu request on the "+rect.color+" rectangle."); } } // prevents the usual context from popping up e.preventDefault() return(false); } Here is working code (no jsFiddle because no right-clicking in X-Domain iframes): <!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; } canvas{border:1px solid red;} </style> <script> $(function(){ var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var canvasOffset=$("#canvas").offset(); var offsetX=canvasOffset.left; var offsetY=canvasOffset.top; var rects=[]; rects.push({x:50,y:50,width:50,height:50,color:"red"}); rects.push({x:150,y:100,width:75,height:75,color:"blue"}); ctx.clearRect(0,0,canvas.width,canvas.height); for(var i=0;i<rects.length;i++){ var rect=rects[i]; ctx.beginPath(); ctx.fillStyle=rect.color; ctx.rect(rect.x,rect.y,rect.width,rect.height); ctx.fill(); } // listen for contextmenu requests canvas.addEventListener('contextmenu', handleMouseDown, false); function handleMouseDown(e){ // get mouse position relative to the canvas var x=parseInt(e.clientX-offsetX); var y=parseInt(e.clientY-offsetY); // check each rect for hits for(var i=0;i<rects.length;i++){ var rect=rects[i]; var rectRight=rect.x+rect.width; var rectBottom=rect.y+rect.height; // check each rect for hits if(x>=rect.x && x<=rectRight && y>=rect.y && y<=rectBottom ){ alert("Context menu request on the "+rect.color+" rectangle."); } } // prevents the usual context from popping up e.preventDefault() return(false); } }); // end $(function(){}); </script> </head> <body> <canvas id="canvas" width=300 height=300></canvas> </body> </html>
HTML 5 and images map
Anyone knows how to accomplish such a thing http://www.jarzebinowe.pl/mieszkania.html (you need to choose floor ...) in html5? It's about choosing the apartment, lights, etc. .. Top how would one image was processed by HTML5 so that was the result I'm sorry for being so strange and laconic question
Try the html map element You probably can achieve your "drill-down" into a building more simply by using html map which will let your users click on a portion of an image and link to a new more specific image. Here's a reference: http://www.w3schools.com/tags/tag_map.asp [Edit with a fancier display with canvas.] Here's code and a Fiddle: http://jsfiddle.net/m1erickson/BbCJx/ <!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:15px; } canvas{border:1px solid red;} </style> <script> $(function(){ var canvas=document.getElementById("canvas"); var ctx=canvas.getContext("2d"); var floorplan=document.getElementById("floorplan"); var planCtx=floorplan.getContext("2d"); planCtx.font="24px Arial"; planCtx.fillStyle="red"; var canvasOffset=$("#canvas").offset(); var offsetX=canvasOffset.left; var offsetY=canvasOffset.top; var lastWindow=-1; var plan=new Image(); var outside=new Image(); outside.onload=function(){ plan.onload=function(){ ctx.drawImage(outside,0,0); } plan.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/inside.jpg"; } outside.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/outside.png"; var windows=[] windows.push({top:66, left: 70, bottom:111, right:111, floorplan:0, apartment:"3a"}); windows.push({top:66, left:139, bottom:111, right:183, floorplan:0, apartment:"3b"}); windows.push({top:66, left:211, bottom:111, right:255, floorplan:0, apartment:"3c"}); windows.push({top:153, left: 70, bottom:196, right:111, floorplan:1, apartment:"2a"}); windows.push({top:153, left:139, bottom:196, right:183, floorplan:1, apartment:"2b"}); windows.push({top:153, left:211, bottom:196, right:255, floorplan:1, apartment:"2c"}); windows.push({top:239, left:139, bottom:283, right:182, floorplan:2, apartment:"1a"}); function selectWindow(x,y){ var w; var isInWindow=false; for(var i=0;i<windows.length;i++){ w=windows[i]; if(x>w.left && x<w.right && y>w.top && y<w.bottom){ isInWindow=true; if(i!=lastWindow){ planCtx.clearRect(0,0,floorplan.width,floorplan.height); planCtx.drawImage(plan,0,0); planCtx.fillText("Apt: "+w.apartment+", Plan: "+w.floorplan,70,25); lastWindow=i; } break; } } if(!isInWindow){ planCtx.clearRect(0,0,floorplan.width,floorplan.height); }; } function handleMouseMove(e){ canMouseX=parseInt(e.clientX-offsetX); canMouseY=parseInt(e.clientY-offsetY); $("#movelog").html("Move: "+ canMouseX + " / " + canMouseY); // Put your mousemove stuff here selectWindow(canMouseX,canMouseY); } $("#canvas").mousemove(function(e){handleMouseMove(e);}); }); // end $(function(){}); </script> </head> <body> <p>Mouse over a window to see it's floorplan</p> <canvas id="canvas" width=300 height=300></canvas> <canvas id="floorplan" width=300 height=300></canvas> </body> </html>
Easel.js > What is wrong with this code?
What is wrong with this code? :S.. My canvas stays empty. Image URL is correct and image loads. This is my engine.js file: var canvas; var stage; function init() { canvas = document.getElementById("canvas"); stage = new Stage(canvas); playerImg = new Image(); playerImg.src = 'img/player/walkingbl.png'; playerImg.onload = onPlayerLoaded; Ticker.setFPS(30); Ticker.addListener(window); } function tick() { stage.update(); } function onPlayerLoaded() { console.log(playerImg); player = new Bitmap(playerImg); player.x = 300; player.y = 450; stage.addChild(player); console.log('Player added to stage'); } $(document).ready(function(){ init(); }); And this is my index.html file: <!DOCTYPE html> <html> <head> <title>Game Engine</title> <link rel="stylesheet" href="css/main.css" /> </head> <body> <div id='container'> <canvas id='#canvas' width='1000' height='350'></canvas> </div> <script src="js/jquery.js"></script> <script src="js/easel.js"></script> <script src='js/engine.js'></script> </body> I'm new to the whole easel.js and never did anything with Flash or actionscript. I'm an PHP developer by heart, so this is a pretty big transition for me. The lack of documentation / tutorials / examples, make it very hard for me to learn how to use easel.js. So if you have any pointers or resources for me to check out. Please share!
This line is wrong: <canvas id='#canvas' width='1000' height='350'></canvas> The ID doesnt need a #. the right line is: <canvas id='canvas' width='1000' height='350'></canvas> but I wouldnt use the word "canvas" as an identifier, as it could be confused with the tag. Better use: <canvas id='mycanvas' width='1000' height='350'></canvas> and change the JS code: canvas = document.getElementById("mycanvas");
CSS/Javascript How do I make this background-position movie in Firefox like it does in IE7+?
<script language="javascript" > var speed=25; //speed var num=0; var photos = document.getElementById('head_image'); function scrollBG() { num++; photos.style.backgroundPosition="0"+num; } setInterval('scrollBG()',speed); </script> This is the site in question: www.theorymarine.com
photos.style.backgroundPosition="0"+num; You need a unit for CSS lengths. photos.style.backgroundPosition= num+'px 0'; You might also prefer to base your animation on the time, so that the rate it moves is not dependent on ‘speed’ or browser performance. eg.: <script type="text/javascript"> var photos= document.getElementById('head_image'); var begin= new Date().getTime(); setInterval(function() { var x= Math.floor((new Date().getTime()-begin)/25); photos.style.backgroundPosition= x+'px 0'; }, 25); </script>