2013-02-18 117 views
3

我有一个大的画布包裹在一个较小的div容器内,并且隐藏了溢出。溢出虚假滚动条:隐藏

我想创建一个(假div/css或甚至canvas?)滚动条来移动包装内的画布位置,就好像它是一个真实的(overflow:auto)滚动条。

首先,我正在努力实现的是可行的吗?

我可以在javascript中将'canvas'位置移动到包装中吗?

为什么假滚动条?

  • 画布是用户可以绘制和移动形状的“活动”区域。

  • 原生滚动条不适用于ipad。

  • 的CSS定制

我看到很多jQuery的库做类似的事情,但他们所做的内容可拖动,而我只是想滚动条“栏”可拖动。

这是我尝试的演示:

http://jsbin.com/otinuy/1/edit

回答

5

是的,你只需要做画布的左侧位置,涉及到的水平滚动条“栏”的左侧位置,如下

令W是画布宽度,设D是包含div和滚动条的宽度,B是滚动条“bar”的宽度。 W> D

Initiall相对于包含div,canvas的左侧为0,滚动条的“bar”左侧为0。

画布可见的分数d/W等B = d * d/W

“扎”的左手边缘的范围是0到DB和为“栏中的”向右移动画布按比例向左移动。

令L为从所述滚动条的左手边缘的“BAR”的当前位置,移动的分数为L/d等画布移动L * W/d向左

即,当(bar).style.left = L(canvas).style。左= -L * W/D

这是一个使用JQuery的小提琴,希望能够满足您的需求。

http://jsfiddle.net/GdsEa/

Javascript代码如下所示

var W=2000; 
var D=500; 
var B=D*D/W; 
document.getElementById("wrap1").style.width=D+"px"; 
document.getElementById("hbar").style.width=B+"px"; 
var canv=document.getElementById("mycanvas"); 
canv.width=W; 
var ctx=canv.getContext("2d"); 
ctx.beginPath(); 
ctx.moveTo(100,100); 
ctx.lineTo(200,100); 
ctx.lineTo(200,200); 
ctx.lineTo(100,200); 
ctx.closePath(); 
ctx.fillStyle="rgb(255,0,0)"; 
ctx.fill(); 

ctx.beginPath(); 
ctx.moveTo(W-100,100); 
ctx.lineTo(W,100); 
ctx.lineTo(W,200); 
ctx.lineTo(W-100,200); 
ctx.closePath(); 
ctx.fillStyle="rgb(0,0,255)"; 
ctx.fill(); 

$(".bar").draggable({ containment:"parent" }); 
$(".bar").on("drag", function(event, ui) {var L=ui.position.left; 
               canv.style.left=(-L*W/D)+"px"}); 

注意内含div,帆布,滚动条和条的宽度在代码通过设置W和d被覆盖,所以,它很容易改变这些值。

+0

太好了,那就是我正在寻找的东西,现在我只需要插入一些事件并查看是否可以在平板电脑上拖动元素。 – coulix 2013-02-18 22:22:33

2

在过去一个大于屏幕的画布的导航,你可以有你的大帆布离屏幕再有第二个更小的屏幕上的画布。

通过显示较大画布的部分,第二个画布的作用类似于放大画布的视口。

您可以创建导航系统,以允许用户通过视口滚动较大的画布。

这里的代码和一个小提琴:http://jsfiddle.net/m1erickson/BBwW8/

<!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 ctxCanvas=canvas.getContext("2d"); 
     var view=document.getElementById("view"); 
     var ctxView=view.getContext("2d"); 

     var col=0; 
     var row=0; 

     var img=new Image(); 
     img.onload=function(){ 
      ctxCanvas.drawImage(this,0,0,canvas.width,canvas.height); 
      drawToViewport(); 
     } 
     img.src="http://www.gospelgifs.com/art_pages_15/imgs/house2.gif"; 

     $("#left").click(left); 
     $("#right").click(right); 
     $("#up").click(up); 
     $("#down").click(down); 

     function drawToViewport(){ 
      ctxView.clearRect(0,0,view.width,view.height); 
      ctxView.drawImage(canvas, 
       col*canvas.width/4,row*canvas.height/4,view.width,view.height, 
       0,0,view.width,view.height); 
     } 
     function right(){ 
      if(col+1<=3){ col++; drawToViewport(); } 
     } 
     function left(){ 
      if(col-1>=0){ col--; drawToViewport(); } 
     } 
     function down(){ 
      if(row+1<=3){ row++; drawToViewport(); } 
     } 
     function up(){ 
      if(row-1>=0){ row--; drawToViewport(); } 
} 

    }); // end $(function(){}); 
</script> 

</head> 

<body> 

<canvas id="canvas" width=300 height=300></canvas><br/> 
<canvas id="view" width=97 height=67></canvas> 
<button id="left">Left</button> 
<button id="right">Right</button> 
<button id="up">Up</button> 
<button id="down">Down</button> 


</body> 
</html> 
+0

是的,这是正常的非交互式画布的良好解决方案,但在我使用fabricjs的casa中,我仍需要能够操作视口上的对象。复制ImageData只会照顾显示部分。 – coulix 2013-02-18 21:58:48