带有Raphael的单手可拖动时钟-无法获得鼠标单击位置 [英] One handed draggable clock with Raphael - cannot get mouse click position

查看:119
本文介绍了带有Raphael的单手可拖动时钟-无法获得鼠标单击位置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了教程来构建单手时钟

 <!-语言:lang-js-> 
window.onload = function(){

var canvas = Raphael( pane,0,0,500,500);

canvas.circle(200,150,100).attr( stroke-width,2);
canvas.circle(200,150,3).attr( fill,#000);

var angleplus = 360,rad = Math.PI / 180,
cx = 200,cy = 150,r = 85,
startangle = -90,angle = 15, x,y,内角;

for(i = 1; i <= 24; i ++)
{

endangle =起始角+角度;

x = cx + r * Math.cos(endangle * rad);
y = cy + r * Math.sin(endangle * rad);
canvas.text(x,y, +(i%24));

startangle = endangle;
}

move = function(dx,dy){
if(dx> = 0&& dy&=; 85)
this.rotate (dx * 0.25,200,150);
},
start = function(){

},
up = function(){};
var hand = canvas.path( M200 70L200 150)。attr( stroke-width,3);



hand.drag(移动,开始,向上);

};

现在,我希望时钟指针可拖动(可通过智能手机触摸)以设置特定时间。我不希望时钟运行,我只需要它作为输入设备。
我知道如何计算角度,但是不幸的是,我无法获得单击的鼠标位置,而只知道相对值。
有人有想法吗?



编辑:
现在,它应该可以工作了。我也让它运行...或多或少。仍然有点跳动,还有一些要改进的地方:




  • 防止圆被拖拽

  • 微调器会对时钟产生影响

  • 使用/尝试实际的开始,结束,移动功能(我仍然无法成功)

  • ...


解决方案

这将允许您拖动任何双手,如果这是您所追求的。也许有一种更简单的方法,但暂时无法想到。



我们需要从屏幕转换为元素(以便它们在相同的坐标空间中),getScreenCTM()会为我们提供这一点,我们需要找到要应用的逆函数。 (如果所有内容都是静态的且不进行任何转换,则可能有一种更简单的方法,但是元素通常会通过各种转换进行更改并在以后被我们发现)。



我们可以获得该转换

  this.node.getScreenCTM()。inverse()


我们需要从Raph事件中获取x,y并将其作为svg点,以便我们进行转换,例如。

  var pt = this.node.ownerSVGElement.createSVGPoint(); 
pt.x = x; pt.y = y;
var newpt = pt.matrixTransform(this.node.getScreenCTM()。inverse());

所以整体看起来像...

  hour_hand.drag(move,start,end); 
minutes_hand.drag(move,start,end);
hand.drag(move,start,end);

函数移动(dx,dy,x,y){
var pt = this.node.ownerSVGElement.createSVGPoint();
pt.x = x; pt.y = y;
var newpt = pt.matrixTransform(this.node.getScreenCTM()。inverse());
var angle =(90 + Math.atan2(pt.y-clock.attr('cy')-5,pt.x-clock.attr('cx')-5)* 180 / Math.PI + 360)%360;
this.rotate(angle,200,150);
this.angle = angle;
}

函数start(){}

函数end(){
alert(parseInt(this.angle / 30))
}

jsfiddle -拖动手臂以移动



编辑:例如,如果您只想单击以移动第二只手,则略微修改,相同的原理,除了我在其中放置背景白色矩形以放置点击处理程序。



jsfiddle -单击以移动第二只手



编辑:改进了小提琴此处,其中考虑了相对于屏幕上其他html等时钟的各种位置。我在其中添加了以下内容...

  var cpt = clock.node.ownerSVGElement.createSVGPoint(); 
cpt.x = clock.attr(’cx’);
cpt.y = clock.attr(‘cy’);
cpt = cpt.matrixTransform(clock.node.getScreenCTM());

考虑到时钟屏幕上的任何位置,并删除了一些其他冗余代码


i followed this tutorial to build a one handed clock

<!-- language: lang-js -->
    window.onload = function(){

var canvas = Raphael("pane",0,0,500,500);

canvas.circle(200,150,100).attr("stroke-width",2);
canvas.circle(200,150,3).attr("fill","#000");

var angleplus = 360,rad = Math.PI / 180,
    cx = 200,cy =150 ,r = 85,
    startangle = -90,angle=15,x,y, endangle;

     for(i=1;i<=24;i++)
     {

         endangle = startangle + angle ;

         x = cx + r  * Math.cos(endangle * rad);
         y = cy + r * Math.sin(endangle * rad);
         canvas.text(x,y,""+(i%24));

          startangle = endangle;
     }

move = function(dx,dy){
    if(dx >=0 && dy <= 85)
        this.rotate(dx*0.25,200,150);
},
start = function(){

},
up = function(){};
var hand = canvas.path("M200 70L200 150").attr("stroke-width",3);



hand.drag(move,start,up);

};

Now i want the clock hand to be draggable (touchable via smartphones) to set a certain time. I don't want the clock to run, I just need it as an input device. I know how to calculate the angle but unfortunately I am not able to get the clicked mouse position only relative values to I don't know what. Does anybody have an idea?

EDIT: Now it should hopefully work. I also got it to run ... more or less. It is still a bit jumpy and there are a few points I still want to improve:

  • Prevent the circle from getting dragged
  • Having influence on the clock by the spinner
  • Using / Trying the actual start,end,move functions (I still couldn't succeed)
  • ...

解决方案

This will allow you to drag any of the hands, if this is the sort of thing you are after. There may be an easier way, but can't think of it for the moment.

We need to get the transform from the screen to the element (so that they are in the same coordinate space), getScreenCTM() will give us this, and we'll need to find the inverse to apply. (there may be a simpler way if everything is static and no transforms, but often elements are changed by various transforms and catches us out later).

We can get that transform matrix from

this.node.getScreenCTM().inverse()

We'll need to get the x,y from the Raph event and put it as an svg point so we can transfom, eg..

var pt = this.node.ownerSVGElement.createSVGPoint();
pt.x = x; pt.y = y;
var newpt = pt.matrixTransform( this.node.getScreenCTM().inverse() );

So the whole lot would look like...

hour_hand.drag( move, start, end );
minute_hand.drag( move, start, end );
hand.drag( move, start, end );

function move (dx,dy,x,y) {
    var pt = this.node.ownerSVGElement.createSVGPoint();
    pt.x = x; pt.y = y;
    var newpt = pt.matrixTransform( this.node.getScreenCTM().inverse()     );
    var angle = ( 90 + Math.atan2(pt.y - clock.attr('cy') - 5, pt.x - clock.attr('cx') - 5 ) * 180 / Math.PI + 360) % 360;
    this.rotate(angle, 200,150);
    this.angle = angle;
}

function start() {}

function end() {
     alert( parseInt( this.angle / 30  ) )
}

jsfiddle - drag arms to move

Edit: If you just want a click to move the 2nd hand for example, here is a slight modification, same principle, apart from I've put a background white rect in there to put the click handler on.

jsfiddle - click to move 2nd hand

Edit: There's an improved fiddle here which takes into account various postions of the clock with respect to other html on the screen etc. Where I've added the following...

var cpt = clock.node.ownerSVGElement.createSVGPoint();
cpt.x = clock.attr('cx');
cpt.y = clock.attr('cy');
cpt = cpt.matrixTransform(clock.node.getScreenCTM());

to take into account any position on the screen of the clock, and removed a bit of other redundant code.

这篇关于带有Raphael的单手可拖动时钟-无法获得鼠标单击位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆