The behavior

Before we start coding the Vue app, let's analize what we need to achieve the desired animation, let's take a look again to the reference:

Our input in this case will be the mouse position, depending on it we should change the rotation of the container. This rotation should be controlled as we don't want the object to rotate 360 degrees, it actually rotates just enough to get the feeling that it faces the mouse, I'd say around 20 degrees in each direction.

Now we can setup our Vue app with that knowledge, let's declare a constant with the degrees of freedom and also a couple of data properties to keep track of the object rotation:

constmaxRotationDegrees=20newVue({el:'#app',data:{rotX:0,rotY:0}})

The next step is to add a method to follow the mouse position, we want to know its position everywhere in our app, not just the widget, so we need to add a mousemove handler in the main HTML node like this:

<divid="app"@mousemove="mouseMoved"><!-- the rest of the markup -->

The mouseMoved method needs to be created, inside it we will get the mouse position with the pageX and pageY properties of the event. After that we will normalize the inputs, multiply that by the degrees of freedom and finally store them into our rotX and rotY properties:

// vue app ...methods:{mouseMoved(e){// This gives us a number between -1 and 1constmousePercX=(e.pageX/document.body.clientWidth)*2-1constmousePercY=(e.pageY/document.body.clientHeight)*2-1this.rotX=mousePercX*maxRotationDegreesthis.rotY=mousePercY*-maxRotationDegrees}}

To start seeing some movement in our widget we need to change the style of it, so we will create a computed property called rotation that will generate the CSS transform to be applied to the widget:

You might have noticed that we have the rotateY property with the rotX property, and something similar with the rotateX, this is not a mistake.

What happens is that when rotating an object in a 3D space, the rotation in the Y axis makes and object change its facing direction horizontally and the rotation in the X axis does it vertically.

You can see it more clearly in the next image, the orange arrow corresponds to the rotateY property and the green one is the rotateX property:

With that explained, we can now add those transforms to our widget in an inline style property, like this:

<!-- app --><divclass="container center":style="rotation">

If we test that we should see the widget moving... but something is not right, the object is completely flat:

Even though we are adding a perspective property in the computed rotation, we still need to change the z position of the inner parts. It should look like the image is behind, the title is in the middle and the card is in front, so let's change their CSS a bit: