Updating matrix transformation values & rAF


#1

I am stuck at how requestAnimationFrame really works. With numerous tutorials out there I have some hang of it, but unable to apply the learnings to my javascript code with confidence. And then there is also a delta (time based animation) which is spoken of at length in several articles and some people throw in the bezier-curves around as well.

Anyway,…

…here’s my code that applies certain transformation values to a DIV node like so:

// lots of javascript before this…
// OnMouseMove
function _handleMouseMove(event) {
    if (!event.target) return
    let eventDoc, doc, body, pageX, pageY
    event = event || w.event
    if (event.pageX === null && event.clientX !== null) {
        eventDoc = (event.target && event.target.ownerDocument) || d
        doc = eventDoc.documentElement
        body = eventDoc.body
        event.pageX = event.clientX +
            (doc && doc.scrollLeft || body && body.scrollLeft || 0) -
            (doc && doc.clientLeft || body && body.clientLeft || 0)
        event.pageY = event.clientY +
            (doc && doc.scrollTop || body && body.scrollTop || 0) -
            (doc && doc.clientTop || body && body.clientTop || 0)
    }
    d.getElementById('xaxis').textContent = event.pageX
    d.getElementById('yaxis').textContent = event.pageY
    _book.side = ((event.pageX - _book.plotter.origin.x) > 0) ? 'right' : 'left'
    _book.region = ((event.pageY - _book.plotter.origin.y) > 0) ? 'lower' : 'upper'
    _book.plotter.currentPointerPosition = JSON.parse(`{ "x": "${event.pageX - _book.plotter.origin.x}", "y": "${event.pageY - _book.plotter.origin.y}" }`);
    _book.plotter.θ = Math.acos(parseInt(_book.plotter.currentPointerPosition.x) * 2 / parseInt(_book.plotter.bounds.width)) // θ in radians
        console.log(`rotateY(${_degrees(_book.plotter.θ)}deg)`)
        // _book.pages.node.style = '' // Tried this but doesn't work.
        _book.pages.node.style = `transform: translate3d(0, 0, 0) rotateY(${_degrees(θ)}deg) skewY(0deg); transform-origin: 0px center 0px; transition:all 100ms ease-in;`
}

Effectively, on the last line I’m calculating the angle according to cursor position on mousemove and trying to apply the latest transformed value to the DIV element _book.pages.node. This doesn’t work as expected though.

What happens is that only the final transformation value is applied when mouseup. Why is it so?

And then where does rAF fit into this picture? :slight_smile:


#2

Hi marvindanig! Is your expectation that the transformation keeps applying while you have your mouse pressed down? If so, the reason is that your mousedown event only fires once. It doesn’t keep firing to update the current values with the latest mouse position. What you can do is listen to the mousemove event as well, but the better solution is the one you reference - using requestAnimationFrame.

Take a look at the example here: https://www.kirupa.com/canvas/follow_mouse_cursor.htm

We have an element following the mouse cursor. The way its position is kept in sync is by using requestAnimationFrame as the loop. What you would do in your example is something similar. Have a variable that you toggle to indicate whether the mouse is down or not. If the mouse is down, your requestAnimationFrame call will adjust the transform value and calculate the right angle. If the mouse is up, your requestAnimationFrame call doesn’t do anything.

Does that make sense? I kind of threw out a lot of things there, but I’d be happy to elaborate on any part of this that is confusing.

Cheers,
Kirupa


#3

Kirupa the expectation is for the transformation value to apply to the dom node as the mouse moves around. What happens instead is that only the last arrived value gets applied to it – a point in time where I go mouseup. I am not applying the matrix transformation on mousedown or mouseup (although toggling it would be easy with a localized global variable in a closure) at the moment.

See the last two lines!: I get the value of [quote=“marvindanig, post:1, topic:636495”]
console.log(rotateY(${_degrees(_book.plotter.θ)}deg))
[/quote] logged correctly in the console, but the dom element doesn’t react to the changing value of θ until I stop moving the cursor around. Should I set this experiment on a code playground?

I’ve seen the follow_mouse_cursor example and have some hang of rAF now. Just want to understand what’s happening without it, and then how to best use both rAF and delta between paint times to produce stable framerates.


#4

Interesting! Please do put this in a code playground. I am not sure what is going on here! :confounded:


#5

Here’s the repo containing the code with an index.html page where this javascript executes. It has plenty of iframes with custom content so isn’t straightforward to put out on codepen. Simply loading the index.html on chrome will work!

https://github.com/marvindanig/flippy.JS/tree/master/static

Fly over to line no. 732-736.