Gust van de Wal Gust van de Wal - 2 months ago 6
Javascript Question

My script changes some values with what seems to be no reason

So I've been working on a script that spawns bubbles at the mouse coordinates. It is a very basic script that calculates some things like a random opacity, random size, etc.



var transform = (function () { // This piece is to test whether transform should be prefixed or not
var testEl = document.createElement('div')
if (testEl.style.transform == null) {
var vendors = ['Webkit', 'Moz', 'ms']
for (var vendor in vendors) {
if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) {
return vendors[vendor] + 'Transform'
}
}
}
return 'transform'
})()

var bubbles = {}
bubbles.chance = 0.08 // Chance for a bubble to spawn at mousemove
bubbles.delay = 50 // Should minimally be 10, otherwise the circles can't transition from small to big
bubbles.duration = 800
bubbles.minScale = 0.2 // The scale of the bubbles will be anywhere between 0.2 and 1 of the default size defined by the CSS
bubbles.minOpacity = 0.4
bubbles.maxOpacity = 0.7

document.getElementById('bubbles').addEventListener('mousemove', function (e) {
if (Math.random() < bubbles.chance) {
var $el = document.createElement('div')
var size = Math.random() * (1 - bubbles.minScale) + bubbles.minScale
var transition = Math.round(bubbles.duration * 0.9)

$el.style.transition = transition + 'ms ease-in-out'
$el.style.top = e.offsetY + 'px' // Seems to undergo a modulo for some periods of time
$el.style.left = e.offsetX + 'px' // This one too
$el.style[transform] = 'translate(-50%, -50%) scale(0)'
$el.style.opacity = Math.random() * (bubbles.maxOpacity - bubbles.minOpacity) + bubbles.minOpacity

window.setTimeout(function () {
$el.style[transform] = 'translate(-50%, -50%) scale(' + size + ')'
window.setTimeout(function () {
$el.style[transform] = 'translate(-50%, -50%) scale(0)'
window.setTimeout(function () {
$el.parentNode.removeChild($el)
}, transition)
}, transition + bubbles.duration)
}, bubbles.delay)

document.getElementById('bubbles').appendChild($el)
}
})

html, body{height:100%}body{margin:0;background-color:#17C}

#bubbles{
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}

#bubbles > div{
position: absolute;
width: 12vw;
height: 12vw;
border-radius: 50%;
background-color: #FFF;
}

<div id="bubbles"></div>





Now, for some reason, some of the bubbles aren't placed at the right coordinates. The script is supposed to literally take
e.offsetX
and
e.offsetY
every time it spawns a new bubble, but it sometimes seems to apply a modulo to the values.

The reason I think some kind of modulo is applied, is because when you only move in a horizontal line, all the displaced bubbles will also form a horizontal line. The same goes for vertical.

The script is vanilla JavaScript and the piece where the error seems to occur is here:

$el.style.top = e.offsetY + 'px'
$el.style.left = e.offsetX + 'px'


One weird thing to also note, is that the displacement isn't just occurring for one bubble at a time, but for all bubbles within short periods of time.

The bug occurs in all major browsers.

All input is appreciated!

Answer

I see why it's happening. If you happen to hover over a bubble instead of the blue background, it uses the bubble as reference for offsetX and Y. If it's a full page app, you could use e.clientX and e.clientY instead. Otherwise you need to listen only to the event if it's fired on #bubbles.