refs 2334. Scroll to top button
parent
3e8f8cc3db
commit
537a220fc4
|
@ -0,0 +1,74 @@
|
||||||
|
/* Posición por defecto (bottom-right) */
|
||||||
|
.scroll-to-top-button-bottom-right {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 30px;
|
||||||
|
right: 30px;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-bottom-left {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 30px;
|
||||||
|
left: 30px;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-top-right {
|
||||||
|
position: fixed;
|
||||||
|
top: 30px;
|
||||||
|
right: 30px;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-top-left {
|
||||||
|
position: fixed;
|
||||||
|
top: 30px;
|
||||||
|
left: 30px;
|
||||||
|
z-index: 1000;
|
||||||
|
transition: all 0.3s ease;
|
||||||
|
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Efectos hover para todas las posiciones */
|
||||||
|
.scroll-to-top-button-bottom-right:hover,
|
||||||
|
.scroll-to-top-button-bottom-left:hover,
|
||||||
|
.scroll-to-top-button-top-right:hover,
|
||||||
|
.scroll-to-top-button-top-left:hover {
|
||||||
|
transform: translateY(-2px);
|
||||||
|
box-shadow: 0 6px 16px rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Responsive para dispositivos móviles */
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.scroll-to-top-button-bottom-right,
|
||||||
|
.scroll-to-top-button-bottom-left {
|
||||||
|
bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-bottom-right {
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-bottom-left {
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-top-right,
|
||||||
|
.scroll-to-top-button-top-left {
|
||||||
|
top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-top-right {
|
||||||
|
right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-to-top-button-top-left {
|
||||||
|
left: 20px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
<button
|
||||||
|
[class]="getPositionClass()"
|
||||||
|
(click)="scrollToTop()"
|
||||||
|
mat-fab
|
||||||
|
color="primary"
|
||||||
|
[matTooltip]="showTooltip ? tooltipText : ''"
|
||||||
|
[matTooltipPosition]="tooltipPosition">
|
||||||
|
<mat-icon>keyboard_arrow_up</mat-icon>
|
||||||
|
</button>
|
|
@ -0,0 +1,61 @@
|
||||||
|
import { Component, OnInit, OnDestroy, Input } from '@angular/core';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-scroll-to-top',
|
||||||
|
templateUrl: './scroll-to-top.component.html',
|
||||||
|
styleUrls: ['./scroll-to-top.component.css']
|
||||||
|
})
|
||||||
|
export class ScrollToTopComponent implements OnInit, OnDestroy {
|
||||||
|
@Input() threshold: number = 300;
|
||||||
|
@Input() targetElement: string = '.header-container';
|
||||||
|
@Input() position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left' = 'bottom-right';
|
||||||
|
@Input() showTooltip: boolean = true;
|
||||||
|
@Input() tooltipText: string = 'Volver arriba';
|
||||||
|
@Input() tooltipPosition: 'left' | 'right' | 'above' | 'below' = 'left';
|
||||||
|
|
||||||
|
showScrollToTop: boolean = false;
|
||||||
|
private scrollListener: (() => void) | undefined;
|
||||||
|
|
||||||
|
ngOnInit(): void {
|
||||||
|
this.setupScrollListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
if (this.scrollListener) {
|
||||||
|
window.removeEventListener('scroll', this.scrollListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private setupScrollListener(): void {
|
||||||
|
this.scrollListener = () => {
|
||||||
|
this.showScrollToTop = window.scrollY > this.threshold;
|
||||||
|
};
|
||||||
|
window.addEventListener('scroll', this.scrollListener);
|
||||||
|
|
||||||
|
this.scrollListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
scrollToTop(): void {
|
||||||
|
try {
|
||||||
|
const targetElement = document.querySelector(this.targetElement);
|
||||||
|
if (targetElement) {
|
||||||
|
targetElement.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'start'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
window.scrollTo({
|
||||||
|
top: 0,
|
||||||
|
left: 0,
|
||||||
|
behavior: 'smooth'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getPositionClass(): string {
|
||||||
|
return `scroll-to-top-button-${this.position}`;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue