I am using Angular here.I am trying to display an image/video inside the tooltip when hovered over the certain content. However, when I hover over the content, the image gives a flickering effect before being rendered. The transition isn't as smooth as when I put text in place of the image. How do I fix it?
I am trying to set the image src in input to the tooltip component. I have a directive which is generating the tooltip content. Code here is as:
app.component.html
<button awesomeTooltip="Hello World!" image="https://imgplaceholder.com/420x320/ff7f7f/333333/fa-image">Hi there, I have a tooltip</button>
tooltip.component.ts
import { Component, Input } from '@angular/core';
import { animate, style, transition, trigger } from '@angular/animations';
@Component({
selector: 'awesome-tooltip',
styleUrls: ['./tooltip.component.css'],
templateUrl: './tooltip.component.html',
animations: [
trigger('tooltip', [
transition(':enter', [
style({ opacity: 0 }),
animate(300, style({ opacity: 1 })),
]),
transition(':leave', [
animate(300, style({ opacity: 0 })),
]),
]),
],
})
export class AwesomeTooltipComponent {
@Input() image=''
@Input() text = '';
}
tooltip.component.html
<div @tooltip>
<img [src]="image" width="20px" height="30px">
<!-- Hello -->
</div>
tooltip.directive.ts
import { ComponentRef, Directive, ElementRef, HostListener, Input, OnInit } from '@angular/core';
import { Overlay, OverlayPositionBuilder, OverlayRef } from '@angular/cdk/overlay';
import { ComponentPortal } from '@angular/cdk/portal';
import { AwesomeTooltipComponent } from './tooltip.component';
@Directive({ selector: '[awesomeTooltip]' })
export class AwesomeTooltipDirective implements OnInit {
@Input('awesomeTooltip') text = '';
@Input('image') image = '';
private overlayRef: OverlayRef;
constructor(private overlay: Overlay,
private overlayPositionBuilder: OverlayPositionBuilder,
private elementRef: ElementRef) {
}
ngOnInit(): void {
const positionStrategy = this.overlayPositionBuilder
.flexibleConnectedTo(this.elementRef)
.withPositions([{
originX: 'center',
originY: 'top',
overlayX: 'center',
overlayY: 'bottom',
offsetY: -8,
}]);
this.overlayRef = this.overlay.create({ positionStrategy });
}
@HostListener('mouseenter')
show() {
const tooltipRef: ComponentRef<AwesomeTooltipComponent>
= this.overlayRef.attach(new ComponentPortal(AwesomeTooltipComponent));
tooltipRef.instance.text = this.text;
tooltipRef.instance.image = this.image;
}
@HostListener('mouseout')
hide() {
this.overlayRef.detach();
}
}
The stackblitz link is here:
I result I am looking for is:
This is how the overlay is setup:
The flickering you experience is due to a never-resolving situation:
This goes on and on, which is why you experience flickering effect.
for solution, add the following code to your tooltip.component.css, which place the overlay under the button, so that this recursive flickering doesn't happen:
::ng-deep .cdk-overlay-connected-position-bounding-box{top:60px !important; position:absolute;}
UPDATE: for a bigger button, the top value can be changed to make sure that the overlay starts from under the button and that there is no overlap. demo here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With