Retrieving the current DOM element in Vue's styling

My goal is to incorporate a transform effect that only applies to the hovered video or image. The effect is dynamically computed and cannot be implemented directly in a Vue method, but I am exploring the option of modifying the target element for the useMouseInElement(). The component WorkThumbnail.vue is part of a v-for loop and displays multiple videos/images.

I'm trying to figure out how to access the current DOM Element in the :style attribute. Using $event doesn't seem to be the solution 😅

WorkThumbnail.vue

<template>
<div
    v-if="work.video === false"
    class="work_thumbnail"
    :style="{
    backgroundImage: 'url(' + require(`@/assets/img/works/${work.thumbnail}.jpg`) + ')',
    transition: 'transform 0.25s ease-out', transform: [currentWork === selectWork($event) ? { cardTransform } :  '']}"
    @mouseover="selectWork($event)"
    >
    <div class="WorkHeadline">{{work.name}}</div>
</div>

<div
    v-if="work.video === true"
    class="work_thumbnail"
    @click="showWork(work)"
    :style="{
    transform: [currentWork === selectWork($event) ? { cardTransform } :  ''],
    transition: 'transform 0.25s ease-out'
    }"
    @mouseover="selectWork($event)"
    >
    <div class="WorkHeadline">{{work.name}}</div>
    <video :poster="require(`@/assets/img/works/${work.vidPreview}.jpg`)" autoplay loop>
        <source
            :src="require(`@/assets/img/works/${work.thumbnail}.mp4`)"
            type="video/mp4">
    </video>
</div>
</template>

<script>
import {
    useMouseInElement
} from '@vueuse/core'
import {computed } from 'vue'

var currentWork

const {
    elementX,
    elementY,
    elementHeight,
    elementWidth,
    isOutside
} = useMouseInElement(currentWork)

const cardTransform = computed(() => {

    const Max_Rotation = 40

    const rX = (
        Max_Rotation / 2 -
        (elementY.value / elementHeight.value) * Max_Rotation).toFixed(2)

    const rY = (
        (elementX.value / elementWidth.value) * Max_Rotation - Max_Rotation / 2).toFixed(2)

    return isOutside.value
        ? ''
        : `perspective(${elementWidth.value}px) rotateX(${rX}deg) rotateY(${rY}deg)`
})

export default {

    
    props: {
        work: {
            type: Object,
            required: true
        },
        index: {
            type: Number,
            required: true
        }
    },
    methods: {
        showWork(work) {
            if (work.direct === true) {
                window.open(work.link, '_blank').focus();
            }
        },
        selectWork(event) {
            currentWork = event.target
            return event.target
        },
    },
    setup() {
        return {
            cardTransform,
            elementX,
            elementY,
            elementHeight,
            elementWidth,
            currentWork
        }
    }
}


</script>

Parent Component (Explore.vue)

<template>
    <div class="Section Explore">^
        

        <div class="WorkList flex_c_h flex_wrap gap1">
            <WorkThumbnail v-for="(work, index) in works" :key="work" :work="work" :index="index"/>
        </div>

    </div>
</template>

<script>
import WorkThumbnail from '@/components/Explore/WorkThumbnail.vue'
export default {
    name: 'Explore',
    components: {
        WorkThumbnail
    },
    computed: {
        works() {
            return this.$store.state.works
        }
    },
        
    }
</script>

Answer â„–1

Upon reviewing the documentation for useMouseInElement, it appears that you can utilize the Vue $ref attribute to pass the DOM element within your div, and easily access the built-in isOutside property:

<div
  v-if="work.video === true"
  ref="target"
  class="work_thumbnail"
  :style="{
    transform: [!isOutside ? { cardTransform } :  ''],
    transition: 'transform 0.25s ease-out'
  }"
  @click="showWork(work)"
>
</div>

Ensure you use ref() in your setup loop to make the properties reactive:

setup() {
  const target = ref(null)
  const {
    elementX,
    elementY,
    elementHeight,
    elementWidth,
    isOutside
  } = useMouseInElement(target)
    
  return {
    cardTransform,
    elementX,
    elementY,
    elementHeight,
    elementWidth,
    isOutside
  }
}

You will also need to import the necessary modules from Vue for the setup:

import { computed, ref } from 'vue'
import { useMouseInElement } from '@vueuse/core'

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

insert the JSON object directly into the designated division

I am in the process of setting up a special FAN section on Facebook dedicated to my loyal followers, where I plan to exclusively feature all available products for them. Currently, my PHP file generates plain HTML content, and I am looking to integrate th ...

Issue with Jest while testing a React component library that has been bundled without the React library

I have extensive experience building React applications and decided to create a React Component library. After researching different approaches, I chose to use Webpack and Babel for bundling without including React itself in the library. This decision was ...

mouse down event causing unexpected behavior in selection handle

I'm attempting to create a gap in the rectangle by using the middle selection handle. I have two middle selection handles, and if I choose either of them, it should create a gap in the middle, dividing the rectangle into two equal halves (like curtain ...

How can I customize the tooltip placement in Bootstrap 5 while utilizing the 'text-truncate' attribute?

In my HTML table, I have long text in a cell that I don't want to display fully. To truncate the text, I am using the 'text-truncate' CSS attribute. Additionally, I am considering using Bootstrap tooltip to show the full text when needed. He ...

Tips for effectively showcasing JSON in an Angular directive

I am facing an issue with my Angular app that utilizes ui-router. I have set up a service and directive, but I am unable to display JSON data. Surprisingly, it works perfectly fine without the directive when I directly display it in the main template (home ...

When arrays are recalled, access to functions is lost for Javascript object instances

Check out this code snippet I have: var cobj = { a: 0, b: 0, c: 0, asdinit: function(x, y, w, h) { this.a = x; this.b = y; this.c = w; this.h = h; }, adsfads: function(a, b, c, d) { this.a = a; this.b = b; this.c ...

Unable to execute controller due to service call testing failure

I'm currently working on writing a code to test the service call in my controller. The goal is to unit test a specific function within the controller that makes the service call and retrieves data. While I am using local JSON for testing purposes, the ...

Making an "associated" route the active route within Aurelia

In my Aurelia application, I have implemented two routes: a list route called Work and a detail route called WorkDetail. Currently, only the list route is visible in the navigation menu: Home | *Work* | Contact | . . . When users navigate to the W ...

Unable to locate module: Unable to locate the file './Header.module.scss' in '/vercel/path0/components/Header'

I encountered an error while attempting to deploy my next application on Vercel. I have thoroughly reviewed my imports, but I am unable to pinpoint the issue. Module not found: Can't resolve './Header.module.scss' in '/vercel/path0/comp ...

Having trouble targeting a div with jQuery

Is it possible to target a specific div within an unordered list and list items? I'm having trouble with it. Here is the HTML code: <ul class="grid"> <div id='categoria' cat='web'></div> <li id=' ...

Tips on effectively implementing vuedraggable to manage nested components responsible for handling data within nested arrays of data stored in Vuex

I am currently working with a system where I have a collection of items, each of which can contain its own nested list of items that can go to any depth. These items are draggable within the list of object trees and the data is managed using Vuex. The drag ...

I am attempting to display the number of guilds that my bot is currently in through a status update feature, however, the information does not seem to be updating

I need help creating a dynamic status for my Discord bot that updates to show the number of servers the bot is in whenever it joins a new server. This is the current code I have: bot.on('ready', () => { console.log(`${bot.user.username} is n ...

Utilizing a template to refine a JSON object

Looking to mask JSON objects' properties and values based on a dynamic template for security purposes. It's akin to seeing the JSON objects through a veil that is revealed only at runtime. Let's consider this JSON object: { "id": "1", "f ...

React Native does not support Laravel Echo's listenForWhisper functionality

I have successfully implemented private channels and messaging in my Laravel App using websockets:serve. Now, I am attempting to enable whisper functionality for the typing status but encountering some issues. When sending a whisper: Echo.private('c ...

Creating an engaging user experience with a Django form

Creating a dynamic calculator <div id="calculator"> <h2>Calculate the price of sawing materials</h2> <form method="post" action="{% url 'products' %}"> {% csrf_token %} & ...

Angular 14 presents an issue where the injectable 'PlatformLocation' requires compilation with the JIT compiler; however, the '@angular/compiler' module is currently missing

I've encountered the following error and have tried multiple solutions, but none of them have been successful: Error: The injectable 'PlatformLocation' requires JIT compilation with '@angular/compiler', which is not available. ...

You cannot pair Reanimated 2 withSequence using a direct value

Trying to implement withSequence with a direct value as the initial input resulted in crashing the application. animatedValue.value = withSequence(startValue, withTiming(endValue)); Although the following code appeared to be functioning correctly, it did ...

Is there a repeated call detected in the Readable stream node?

The issue at hand Currently, I have encountered a problem with this code snippet. It involves a Readable stream that retrieves movements from the database in a paginated manner, but it seems to be returning duplicate records inexplicably. const read ...

How do I set a new value for a variable from within a function?

After retrieving initial numbers from a JSON file, I want to update them using an ajax call. How do I go about replacing the values of homePoints and awayPoints with the new ones fetched through ajax? I have reviewed the provided answers but none seem to ...

I find it frustrating to constantly remove node_modules and reinstall the packages just to get npm run prod to function properly

Encountering this issue repeatedly: $ npm run production @ production /var/www/html/**** cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js xnpm ERR! ...