[new-theme | Library]: section-scroll.component: Scroll component used by connect home page updated - opacity changes according to intersectionRatio of IntersectionObserver | css for medium screens added.

This commit is contained in:
Konstantina Galouni 2022-01-28 11:01:22 +02:00
parent a59143f381
commit fca0f49119
2 changed files with 134 additions and 52 deletions

View File

@ -1,44 +1,65 @@
.section { /*.section {*/
position: relative; /*position: relative;*/
height: auto; /*height: auto;*/
/*display: flex;*/ /*display: flex;*/
} /*}*/
.section [top] { /*.section [top] {*/
/*height: 80vh;*/ /* !*height: 80vh;*!*/
/*border: 1px solid rebeccapurple;*/ /* !*border: 1px solid rebeccapurple;*!*/
} /*}*/
.section [top] { /*.section [top] {*/
position: sticky; /* top: 0;*/
top: 0;
z-index: 2;
height: auto;
/*max-height: 80vh;*/
/*border: 1px solid deeppink;*/
}
/*.content {*/
/* position: relative;*/
/* height: auto;*/ /* height: auto;*/
/* z-index: 1;*/ /* !*border: 1px solid deeppink;*!*/
/* border: 1px solid cyan;*/
/*}*/ /*}*/
[left] { [left] {
position: -webkit-sticky; /* Safari */
position: sticky; position: sticky;
top: 0; top: 0;
height: 100vh; height: 100vh;
/*border: 1px solid red;*/ /*border: 1px solid red;*/
} }
[left] img { [left] .imgContainer {
/*position: absolute;*/ position: absolute;
/*top: 50%;*/ top: 20%;
/*left: 50%;*/ left: 0;
/*transform: translate(-50%, -50%);*/ width: 100%;
position: sticky; height: 70%;
top: 50%;
left: 10%;
/*border: 1px solid greenyellow;*/ /*border: 1px solid greenyellow;*/
} }
@media (max-width: 960px) {
[left] .imgContainer {
top: 5%;
height: 40%;
}
[left] > * {
align-items: flex-start;
}
[scroll] > * {
align-items: flex-end;
}
}
[left] img {
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
}
[scroll] {
margin-top: 15vh;
margin-bottom: 25vh;
}
[scroll] > * {
height: 60vh;
/* border: 1px solid darkorange;*/
}

View File

@ -2,30 +2,26 @@ import {Component, HostListener, Input, OnInit, ViewEncapsulation} from "@angula
/** /**
* <section-scroll [customClass]="'optional classes for grid e.g. uk-flex-bottom'"> * <section-scroll [customClass]="'optional classes for section e.g. uk-section-primary'"
* <div fixed>...</div> * [childrenCustomClass]="'optional classes for content e.g. uk-container'">
* <div scroll>...</div> # use uk-flex-first to change order * <div top>...</div>
* <div left>...</div>
* <div scroll>...</div>
* </section-scroll> * </section-scroll>
* *
* */ * */
@Component({ @Component({
selector: 'section-scroll', selector: 'section-scroll',
template: ` template: `
<div class="section" [ngClass]="customClass">
<!--&lt;!&ndash;alternative&ndash;&gt;--> <ng-content select="[top]"></ng-content>
<!--<div class="section" [ngClass]="customClass">--> <div class="content" [ngClass]="childrenCustomClass">
<!-- <ng-content select="[top]"></ng-content>--> <div class="uk-grid">
<!-- <div class="uk-grid content" [ngClass]="childrenCustomClass">--> <ng-content select="[left]"></ng-content>
<!-- <ng-content select="[left]"></ng-content>--> <ng-content select="[scroll]"></ng-content>
<!-- <ng-content select="[scroll]"></ng-content>--> </div>
<!-- </div>--> </div>
<!--</div>--> </div>
<div class="section uk-grid" [ngClass]="customClass">
<ng-content select="[top]"></ng-content>
<ng-content select="[left]"></ng-content>
<ng-content select="[scroll]"></ng-content>
</div>
`, `,
styleUrls: ['section-scroll.component.css'], styleUrls: ['section-scroll.component.css'],
encapsulation: ViewEncapsulation.None encapsulation: ViewEncapsulation.None
@ -38,16 +34,22 @@ export class SectionScrollComponent implements OnInit {
public childrenCustomClass = null; public childrenCustomClass = null;
private absolute: HTMLCollectionOf<Element>; private absolute: HTMLCollectionOf<Element>;
private scroll: HTMLElement; private scroll: HTMLElement;
constructor() { private observer: IntersectionObserver = null;
}
constructor() {}
@HostListener('window:resize', ['$event']) @HostListener('window:resize', ['$event'])
onResize(event) { onResize(event) {
//this.setHeight(); //this.setHeight();
} }
ngOnDestroy() {
if(this.observer) {
this.observer.disconnect();
}
}
ngOnInit() { ngOnInit() {
//this.setHeight(); //this.setHeight();
} }
@ -66,4 +68,63 @@ export class SectionScrollComponent implements OnInit {
let htmlElement = this.absolute&&this.absolute.length>0?this.absolute[0]:null; let htmlElement = this.absolute&&this.absolute.length>0?this.absolute[0]:null;
return htmlElement?htmlElement['offsetHeight']:0; return htmlElement?htmlElement['offsetHeight']:0;
} }
ngAfterViewInit() {
if(typeof document !== "undefined") {
this.createObserver();
}
}
createObserver() {
let observer;
let options = {
root: null,
rootMargin: "-20%",
threshold: this.buildThresholdList()
};
let imgElement1: HTMLElement = document.getElementById("imgId1");
let imgElement2: HTMLElement = document.getElementById("imgId2");
let imgElement3: HTMLElement = document.getElementById("imgId3");
let imgElement4: HTMLElement = document.getElementById("imgId4");
let imgElement5: HTMLElement = document.getElementById("imgId5");
observer = new IntersectionObserver(entries => {
entries.forEach((entry) => {
entry.target['style'].opacity = entry.intersectionRatio;
if (entry.target.id == "1st") {
imgElement1.parentElement.style.opacity = String(entry.intersectionRatio);
} else if (entry.target.id == "2nd") {
imgElement2.parentElement.style.opacity = String(entry.intersectionRatio);
} else if (entry.target.id == "3rd") {
imgElement3.parentElement.style.opacity = String(entry.intersectionRatio);
} else if (entry.target.id == "4th") {
imgElement4.parentElement.style.opacity = String(entry.intersectionRatio);
} else if (entry.target.id == "5th") {
imgElement5.parentElement.style.opacity = String(entry.intersectionRatio);
}
});
}, options);
let targets: NodeListOf<HTMLElement> = document.getElementsByName('txt');
targets.forEach(target =>
{
observer.observe(target)
});
}
buildThresholdList() {
let thresholds = [];
let numSteps = 20;
for (let i=1.0; i<=numSteps; i++) {
let ratio = i/numSteps;
thresholds.push(ratio);
}
thresholds.push(0);
return thresholds;
}
} }