Issue
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:
- I should be able to send image url from the tag over which, I want to show the tooltip.
- The tooltip should show that image inside it.
Solution
This is how the overlay is setup:
- when you hover on button, overlay becomes visible
- when you move to anything other than the button, the overlay hides
The flickering you experience is due to a never-resolving situation:
- When you hover on the bottom part of the button, the overlay becomes visible
- But since the overlay starts from the middle of the button, technically you are now hovering on the overlay (and no longer over the button), so the overlay becomes hidden
- As soon as overlay becomes hidden, you are back to point #1 above...
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
Answered By - Akber Iqbal
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.