Translating vanilla JS into an Ember Component

Hello! Currently, I’m trying to translate some code from an existing source to an ember project. I’m fairly new, so I’m a bit lost and confused. My goal is to implement a zoom feature for images and then hover/navigate around that enlarged image. I’ve had seen an example of using eventListiner, but I don’t know how to translate that over to Ember. This is the original code that I’m trying to implement in an ember component:

class ZoomHover extends HTMLElement {
  constructor() {
    this.root = this.attachShadow({ mode: "open" });
    this.root.innerHTML = `
        <template id='zoom-template'>
                .zoom-img {
                          background-repeat: no-repeat;
                .zoom-img:hover img {
                        opacity: 0;
                        cursor: zoom-in;
                .tumb {
                        align-items: center;
                        justify-content: center;
                .tumb img {
                        max-width: 100%;
                        max-height: 100%;
             <figure class="tumb zoom-img">
               <img src='' alt="not found" />

    this.backgroundImage = "";
    this.backgroundPosition = "0% 0%";
    this.height = "400px";

  connectedCallback() {
    const content = this.root
    const image = content.querySelector("img");
    const figure = content.querySelector("figure");
      ? ( = `${this.getAttribute("height")}px`)
      : ( = this.height);
    if (this.hasAttribute("image")) {
      const imgAttr = this.getAttribute("image");
      this.backgroundImage = `url(${imgAttr})`;
      image.src = imgAttr;

    figure.addEventListener("mousemove", e => {
      const { left, top, width, height } =;
      const x = ((e.pageX - left) / width) * 100;
      const y = ((e.pageY - top) / height) * 100;
      this.backgroundPosition = `${x}% ${y}%`; = this.backgroundImage; = this.backgroundPosition;

    figure.addEventListener("mouseout", e => { = ""; = "0% 0%";

customElements.define("zoom-hover", ZoomHover);

module.exports = ZoomHover;

If anyone can point me in the right direction, I would appreciate it.

Hi @Luis_Miranda, welcome!

With the caveat that I haven’t used a web component or the shadow DOM in Ember I think there are a couple ways you could go here.

The most straightforward translation would be writing an “element modifier”, and attaching the modifier to a regular img tag (or whatever you choose in terms of the tag, could be a div or something too. A modifier is a bit of javascript that you attach to a DOM element much in the way that this web component is working. A theoretical invocation of this modifier might look something like:

<img src="..." {{zoom-hover height="600"}} />

or if it should be attached to a div maybe more like:

<div {{zoom-hover image="image-url-here" height="600"}}></div>

The other way you could go is write a regular component which does the same thing, but that is less of a tweak and reuse and more of a full rewrite situation to adapt the web component code to idiomatic Ember component code.

At first glance I’d think the modifier makes a lot of sense and would be a fairly easy translation. But like I said I’ve never actually tried shadow dom or other web-component-y stuff and I haven’t looked SUPER deeply at the code so i’m not 100% how much tweaking you’d have to do at the end of the day.