根据距离计算div数字

4
我正在制作一个类似于赌场轮盘的旋转木马,但我不知道在动画播放时哪个div编号。我尝试通过距离计算来循环动画,但是没有成功。
以下是我的示例:

https://codepen.io/anon/pen/xXbpJr?page=1&

    var giftamount = 10;
var gw = $('.gift').outerWidth(true);
var giftcenter = gw/2;
var cycle = 7;

var containercenter = $('.boxwrapper').outerWidth(true)/2;
for(var i = 0; i <=5; i++)
{
  var giftduplicate = $('.giftwrapper').children().clone(true,true);
   $('.giftwrapper').append(giftduplicate);   
}    

$('.button').click(function(){
  var btn = $(this);
  btn.hide();
  var randomgift = Math.floor((Math.random() * 10) + 1);
  var distance = giftamount * gw * cycle + containercenter + (randomgift*gw) - giftcenter;

  console.log(distance);

  $( ".giftwrapper" ).css({left: "0"});

  $('.giftwrapper').animate({left: "-="+distance},10000,function(){
    alert('You Won Gift' + randomgift); 
    btn.show();                  
   });
});

我得到了错误的div数量,我尝试了很多组合但都不起作用。

你能否更具体地描述问题所在吗?我认为这只是措辞上的问题。你是想知道你落在哪个奖励方块上了吗? - mnewelski
我假设赢得的奖品是指针下面的那个(垂直红线)? - Terry
@Terry,那肯定是你赢得的奖品,但我正在尝试理解问题是否实际上在于确定它,考虑到警报包含不同的值。我正在请求澄清问题,同时质疑逻辑。 - mnewelski
没问题 :) 我正在写我的答案,已经有一个可行的解决方案了。 - Terry
@Terry 听起来不错 - 我也有正在运行的代码,因为这是许多 CS:GO 开箱网站的流行动态,但我的实现不依赖于 UI 元素上的任何计算,而是通过预定义的奖品创建/删除动态元素 - 就像 CS:GO 一样。基于客户端发生的事情来确定实际奖品太冒险了。 - mnewelski
2个回答

2
如果你想获得指针(垂直红色条)下面的奖品,实际上不需要计算距离。相反,你可以利用一个非常方便但不太知名的DOM API方法,称为elementFromPoint(x, y),在这里你可以获取页面x、y坐标下最顶部的DOM节点的引用。
为了使其正常工作,xy将必须对应于指针的视觉中心,我们可以通过以下方式简单地计算:
var $pointer = $('.rafflebox .pointer');
var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
var pointerY = $pointer.offset().top + $pointer.height() * 0.5;

在jQuery的动画回调函数中,您可以轻松地检索位于此坐标下方的元素(也称为奖品)。
// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();

// Get element from pointer's visual center
var prize = document.elementFromPoint(pointerX, pointerY);

// Show it again
$pointer.show();

现在你已经正确引用了DOM节点,接下来就是由您决定要在“prize” DOM节点中存储什么类型的元数据。例如,您可以在HAML中嵌入HTML5 data-属性:

%img{:src => "http://placehold.it/125x125?text=Prize+#{i}", :data => {:prize => "Prize #{i}"}}

这段代码简单地将文本Prize (n)(其中n是奖项编号)存储在属性data-prize中,我们可以稍后使用以下方式访问它:

var prize = document.elementFromPoint(pointerX, pointerY);
console.log($(prize).data('prize'));

当我们用我建议的代码替换部分代码时,你会得到这个:
  // Get visual center of pointer
  var $pointer = $('.rafflebox .pointer');
  var pointerX = $pointer.offset().left + $pointer.width() * 0.5;
  var pointerY = $pointer.offset().top + $pointer.height() * 0.5;

  $( ".giftwrapper" ).css({left: "0"});

  $('.giftwrapper').animate({left: "-="+distance},10000,function(){
    // Hide pointer first, otherwise it will be returned as the topmost element
    $pointer.hide();

    // Get element from pointer's visual center
    var prize = document.elementFromPoint(pointerX, pointerY);

    // Show it again
    $pointer.show();
    alert('You Won Gift ' + $(prize).data('prize')); 
    btn.show();                  
   });

这是您更新后的笔,附带一个可工作的示例:https://codepen.io/terrymun/pen/dVPdMg


更新示例

指针有很小的机会落在奖品之间。为了防止这种情况,您需要在.gift元素上使用padding而不是margin

.gift {
    // Change margin to padding
    padding: 0px 4px;
}

...并对返回的prize节点执行额外的检查:

// Hide pointer first, otherwise it will be returned as the topmost element
$pointer.hide();

// Get element from pointer's visual center
var $prize = $(document.elementFromPoint(pointerX, pointerY));

// If prize lands on the .gift element instead
if(!$prize.is('img'))
    $prize = $prize.find('img')

// Show it again
$pointer.show();
alert('You Won Gift' + $prize.data('prize')); 
btn.show();                  

这里的笔只是原始解决方案的一个变体,但是水平填充被夸大了,以增加指针落在图像之间的机会:https://codepen.io/terrymun/pen/rGaJmY

值得注意的是,这个值不应该被信任,因为任何人都可以在客户端简单地修改任何元素的 data-prize 属性。 - mnewelski

2
你可以尝试用这个替换 distance
var distance = giftamount *  cycle * gw   + (randomgift*gw) - containercenter -24;

以下是内容的翻译:

思路如下:使用distance=- containercenter;,您可以将其移动到与容器中心左对齐。然后添加一定数量的周期giftamount * cycle * gw,最后再添加一些随机礼物元素((randomgift*gw))。

无法弄清楚常量-24来自哪里。我已经硬编码了,但需要更好地定义,但我想这可能取决于一些边距/近似值/jQuery/CSS/??

现在您应该看到动画总是停在礼物元素内的同一点(中间)。要添加随机偏差,您可以像这样添加一个小偏差dev(让您保持在礼物元素内):

var dev = Math.random()*(giftcenter+1);
var distance = giftamount *  cycle * gw   + (randomgift*gw) - containercenter -24 +dev;

更新的演示:https://codepen.io/anon/pen/RLNeBX


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接