How to animate rotation of an image inside input control?

43 views Asked by At

Based on this answer, I managed to put an image as my icon appearing inside an INPUT control at its right edge. If I use a GIF that rotates, I'm all set. I only need to set the class on my control and it is "progressing".

input.busy {
  background-image: url(...);
  ...
}

However... Now, I want to control the pace of the rotation, so I need to actually animate the image. I can do that as shown in this blog, which works for many, but not all, elements. And my INPUT is one of the unfortunate exceptions.

div::after {
  content: "this shows";
  background-image: url(...);
}

input::after {
  content: "this shows not";
  background-image: url(...);
}

How can I rotate (in fact, animate the rotation) of an image (let's say PNG) that will reside at the rightmost edge of an INPUT tag?

1

There are 1 answers

2
Eliseo On

To animate anything in after you can simply use

.loading::after{
  content:'';
  display:inline-block;
  width:50px;
  height:50px;
  background-image:url('https://picsum.photos/id/63/50/50');
 }
 .loading.rotate::after{
   animation: rotation 2s infinite linear;
 }
 @keyframes rotation {
   from {
     transform: rotate(0deg);
   }
   to {
     transform: rotate(359deg);
   }
}

And use, e.g.

<div (click)="toogle=!toogle" class="loading" [class.rotate]="toogle">
  here
</div>

But the problem is when we use an input. I don't know if there're a better solution but always we can create a directive

@Directive({
  selector: '[pending]',
  standalone: true,
  exportAs: 'child',
})
export class InputPending implements OnInit {
  div = this.render.createElement('div');
  @Input('pending') set _(value: boolean) {
    if (value) {
      this.render.insertBefore(
        this.elementRef.nativeElement.parentElement,
        this.div,
        this.render.nextSibling(this.elementRef.nativeElement)
      );
    } else
      this.render.removeChild(
        this.elementRef.nativeElement.parentElement,
        this.div
      );
  }
  constructor(private elementRef: ElementRef, private render: Renderer2) {}
  ngOnInit() {
    this.render.setAttribute(this.div, 'class', 'pendding');
    this.render.setStyle(
      this.div,
      'width',
      this.elementRef.nativeElement.offsetHeight + 'px'
    );
    this.render.setStyle(
      this.div,
      'height',
      this.elementRef.nativeElement.offsetHeight + 'px'
    );
  }
}

And we use like

<input [pending]="toogle">

the .css

input ~ .pendding{
  background-image: url("https://picsum.photos/id/237/50/50");
  display:inline-block;
  margin-bottom:-6px;
  margin-left:2px;
  animation: rotation 2s linear infinite
 }
 @keyframes rotation {
  from {
   transform: rotate(0deg);
  }
  to {
   transform: rotate(359deg);
  }
}

the stackblitz