const {
start,
stop,
tick
} = (() => {
// Whether we should be actively listening for changes in the active item.
let highlightListen = false;
// The currently highlighted item.
let active;
// Do a check of which element should be highlighted.
const tick = () => {
// Get the x-coordinate of the middle of the screen.
const middle = window.innerWidth / 2;
const middleCard = document
// Get all elements at the point in the document of x: middle, y: 50px.
.elementsFromPoint(middle, 50)
// Filter this list to `.card` elements.
.filter((element) => element.matches('.card'))
// Get the first item from this array.
?.[0];
// If this middle card is different from the last-known active item.
if (active !== middleCard) {
// Remove the highlight opacity style that was on the previously
// active item.
if (active) {
active.style.opacity = '';
}
// Add the highlight opacity style to the new middle card. Check
// that it exists since we might have hit an instance where the
// the middle of the screen is not on a card.
if (middleCard) {
middleCard.style.opacity = '1';
}
// Store the new middle card.
active = middleCard;
}
// If we should be listening to positional changes, run this check
// again on the next drawing frame.
if (highlightListen) {
requestAnimationFrame(tick);
}
};
return {
// Start listening for active changes.
start() {
highlightListen = true;
tick();
},
// Stop listening for active changes.
stop() {
highlightListen = false;
},
// Do a single check.
tick,
};
})();
$(document).ready(function() {
//setup multiple rows of colours, can also add and remove while spinning but overall this is easier.
initWheel();
// Once all the elements are set up, do a single check to mark the initial state.
tick();
$('button').on('click', function() {
var outcome = parseInt($('input').val());
spinWheel(outcome);
});
});
function initWheel() {
var $wheel = $('.roulette-wrapper .wheel'),
row = "";
row += "<div class='row'>";
row += " <div class='card red'>1<\/div>";
row += " <div class='card black'>14<\/div>";
row += " <div class='card red'>2<\/div>";
row += " <div class='card black'>13<\/div>";
row += " <div class='card red'>3<\/div>";
row += " <div class='card black'>12<\/div>";
row += " <div class='card red'>4<\/div>";
row += " <div class='card green'>0<\/div>";
row += " <div class='card black'>11<\/div>";
row += " <div class='card red'>5<\/div>";
row += " <div class='card black'>10<\/div>";
row += " <div class='card red'>6<\/div>";
row += " <div class='card black'>9<\/div>";
row += " <div class='card red'>7<\/div>";
row += " <div class='card black'>8<\/div>";
row += "<\/div>";
for (var x = 0; x < 29; x++) {
$wheel.append(row);
}
}
function spinWheel(roll) {
var $wheel = $('.roulette-wrapper .wheel'),
order = [0, 11, 5, 10, 6, 9, 7, 8, 1, 14, 2, 13, 3, 12, 4],
position = order.indexOf(roll);
//determine position where to land
var rows = 12,
card = 75 + 3 * 2,
landingPosition = (rows * 15 * card) + (position * card);
var randomize = Math.floor(Math.random() * 75) - (75 / 2);
landingPosition = landingPosition + randomize;
var object = {
x: Math.floor(Math.random() * 50) / 100,
y: Math.floor(Math.random() * 20) / 100
};
$wheel.css({
'transition-timing-function': 'cubic-bezier(0,' + object.x + ',' + object.y + ',1)',
'transition-duration': '6s',
'transform': 'translate3d(-' + landingPosition + 'px, 0px, 0px)'
});
// Start active positional checking.
start();
setTimeout(function() {
$wheel.css({
'transition-timing-function': '',
'transition-duration': '',
});
var resetTo = -(position * card + randomize);
$wheel.css('transform', 'translate3d(' + resetTo + 'px, 0px, 0px)');
// Stop active positional checking.
stop();
}, 6 * 1000);
}
4条答案
按热度按时间jgovgodb1#
如何检查重叠,你可以在这里找到jQuery/JavaScript collision detection但我不确定你的解决方案是正确的...
2g32fytz2#
另一种不同的方法是用半透明的灰色覆盖卡片,中间部分是透明的,这样就不需要进行额外的计算。
这是一个简单的片段--用黑色的、透明的、黑色的线性渐变来覆盖。显然你可以改变它来得到你想要的效果。
注意:运行时,我笔记本电脑上的GPU使用率为15%。
7rfyedvj3#
让所有的
.card
元素都有opacity: 0.5
。我们将根据需要在活动的.card
上应用opacity: 1
。为了尽可能保持性能,我们只在微调器旋转时监听活动的位置变化。我们使用requestAnimationFrame()
来计时我们的检查到显示帧。wgx48brx4#
虽然不是你想要的,但也差不多了