15 changed files with 384 additions and 125 deletions
@ -0,0 +1,28 @@ |
|||
<div class="component-home"> |
|||
<div class="content"> |
|||
<div [ngClass]="'slide-' + item.width" *ngFor="let item of homeItems"> |
|||
<div class="box" [ngClass]="'skew-' + (item.id % 6)" (click)="showDetails(item.id)"> |
|||
<img class="image" *ngIf="item.loading" src="/assets/images/loader.webp" alt="loading"> |
|||
<img class="image" [hidden]="item.loading" (load)="onLoad(item.id)" [src]="basePath+item.image"> |
|||
<div class="text"> |
|||
<span class="title">{{item.title}}</span> |
|||
<span class="type" *ngIf="section != 'exhibitions'">{{item.type}}</span> |
|||
|
|||
<div class="date-container" *ngIf="section == 'exhibitions'"> |
|||
<div class="date-row"> |
|||
<span class="date-indication" *ngIf="item.date_from != item.date_to">from</span> |
|||
<span class="date-indication" *ngIf="item.date_from == item.date_to">on</span> |
|||
<span class="date">{{item.date_from | date}}</span> |
|||
</div> |
|||
<div class="date-row"> |
|||
<span class="date" *ngIf="item.date_from != item.date_to"> <span class="date-indication">to</span> {{item.date_to | date}}</span> |
|||
</div> |
|||
</div> |
|||
|
|||
<span class="tags">{{item.tags}}</span> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
@ -0,0 +1,139 @@ |
|||
@import "../../assets/scss/variables"; |
|||
|
|||
.component-home { |
|||
display: flex; |
|||
padding-top: 100px; |
|||
height: 100vh; |
|||
|
|||
.content { |
|||
display: inline-flex; |
|||
margin: auto; |
|||
animation: slide 120s ease-in-out infinite; |
|||
|
|||
@each $width in 1,2,3,4,5,6 { |
|||
.slide-#{$width} { |
|||
width: #{($width+2)*100}px; |
|||
} |
|||
} |
|||
|
|||
.box { |
|||
position: relative; |
|||
display: flex; |
|||
background: $black-alpha2; |
|||
border-radius: 0; |
|||
overflow: hidden; |
|||
margin: auto 0; |
|||
padding: 40px 20px; |
|||
height: calc(80vh - 90px); |
|||
min-height: 300px; |
|||
max-height: 700px; |
|||
cursor: pointer; |
|||
transition: transform .4s, background .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
|
|||
.image { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
height: 100%; |
|||
width: 100%; |
|||
object-fit: cover; |
|||
transform: translate(-50%, -50%); |
|||
opacity: .5; |
|||
filter: grayscale(100%) contrast(3); |
|||
transition: opacity .4s, filter .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.text { |
|||
display: block; |
|||
margin: auto; |
|||
text-align: center; |
|||
transform: translate(0%, 0%); |
|||
color: $yellow; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 1; |
|||
|
|||
.title { |
|||
display: block; |
|||
font-size: $font-20; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.type { |
|||
display: block; |
|||
font-size: $font-16; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.tags { |
|||
display: block; |
|||
font-size: $font-12; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
padding-top: 10px; |
|||
} |
|||
|
|||
.date-container { |
|||
display: inline-flex; |
|||
flex-wrap: wrap; |
|||
|
|||
.date-row { |
|||
display: block; |
|||
width: 100%; |
|||
|
|||
.date { |
|||
display: inline-flex; |
|||
margin: auto; |
|||
font-size: $font-20; |
|||
} |
|||
|
|||
.date-indication { |
|||
margin: 2px 5px auto 5px; |
|||
font-size: $font-12; |
|||
} |
|||
|
|||
&:nth-of-type(2) { |
|||
margin-top: -12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@each $angle in 0,1,2,3,4,5,6 { |
|||
&.skew-#{$angle} { |
|||
//transform: skew(#{$angle - 3}deg, #{$angle - 3}deg) scale(1.2); |
|||
transform: skew(-6deg, -6deg) rotate(6deg); |
|||
} |
|||
} |
|||
|
|||
&:hover { |
|||
background: $black; |
|||
z-index: 50; |
|||
|
|||
@each $angle in 0,1,2,3,4,5,6 { |
|||
&.skew-#{$angle} { |
|||
transform: scale(1.4) rotate(0deg) skew(0deg, 0deg); |
|||
} |
|||
} |
|||
.image { |
|||
filter: grayscale(0%); |
|||
opacity: .5; |
|||
} |
|||
} |
|||
} |
|||
|
|||
&:hover { |
|||
animation-play-state: paused; |
|||
} |
|||
} |
|||
} |
|||
|
|||
|
|||
@keyframes slide { |
|||
0% {transform: translateX(-100%) translateX(100vw);} |
|||
50% {transform: translateX(0%);} |
|||
100% {transform: translateX(-100%) translateX(100vw);} |
|||
} |
@ -0,0 +1,25 @@ |
|||
import { async, ComponentFixture, TestBed } from '@angular/core/testing'; |
|||
|
|||
import { HomeComponent } from './home.component'; |
|||
|
|||
describe('HomeComponent', () => { |
|||
let component: HomeComponent; |
|||
let fixture: ComponentFixture<HomeComponent>; |
|||
|
|||
beforeEach(async(() => { |
|||
TestBed.configureTestingModule({ |
|||
declarations: [ HomeComponent ] |
|||
}) |
|||
.compileComponents(); |
|||
})); |
|||
|
|||
beforeEach(() => { |
|||
fixture = TestBed.createComponent(HomeComponent); |
|||
component = fixture.componentInstance; |
|||
fixture.detectChanges(); |
|||
}); |
|||
|
|||
it('should create', () => { |
|||
expect(component).toBeTruthy(); |
|||
}); |
|||
}); |
@ -0,0 +1,53 @@ |
|||
import { Component, OnInit } from '@angular/core' |
|||
import { Router, NavigationEnd } from '@angular/router' |
|||
import { ApisService } from '../services/apis.service' |
|||
import { environment } from '../../environments/environment' |
|||
|
|||
@Component({ |
|||
selector: 'app-home', |
|||
templateUrl: './home.component.html', |
|||
styleUrls: ['./home.component.scss'] |
|||
}) |
|||
export class HomeComponent implements OnInit { |
|||
|
|||
public basePath = `${environment.BASE_PATH}` |
|||
|
|||
public homeItems: any = [] |
|||
public section: string = 'portfolio' |
|||
|
|||
constructor( |
|||
private apisService: ApisService, |
|||
private router: Router) |
|||
{ } |
|||
|
|||
ngOnInit(): void { |
|||
this.apisService.getPortfolio(this.section, true).toPromise().then((response) => { |
|||
this.homeItems = response.items |
|||
|
|||
let cnt = 0 |
|||
let width = 0 |
|||
let tot = 0 |
|||
|
|||
this.homeItems.forEach((e) => { |
|||
e.loading = true |
|||
e.width = Math.floor(Math.random()*4)+1 |
|||
cnt++ |
|||
}) |
|||
|
|||
},(error) => { |
|||
console.error('getPortfolio ERROR', error) |
|||
}).catch((e) => { |
|||
console.error('getPortfolio CATCH', e) |
|||
}) |
|||
} |
|||
|
|||
showDetails(id): void { |
|||
const section = this.section == 'exhibitions' ? 'exhibitions' : 'works' |
|||
this.router.navigate([`/detail/${section}/${id}`]) |
|||
} |
|||
|
|||
onLoad(id): void { |
|||
this.homeItems.filter(item => item.id == id)[0].loading = false |
|||
} |
|||
|
|||
} |
@ -1,119 +1,133 @@ |
|||
@import "../../assets/scss/variables"; |
|||
|
|||
.component-portfolio { |
|||
padding-top: 140px; |
|||
|
|||
.box { |
|||
position: relative; |
|||
display: flex; |
|||
background: $black-alpha; |
|||
border-radius: 10px; |
|||
overflow: hidden; |
|||
margin: 10px 0; |
|||
padding: 40px 20px; |
|||
min-height: 250px; |
|||
cursor: pointer; |
|||
transition: transform .4s, background .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
|
|||
.image { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
height: 100%; |
|||
width: 100%; |
|||
object-fit: cover; |
|||
transform: translate(-50%, -50%); |
|||
opacity: .9; |
|||
filter: grayscale(100%) brightness(.4); |
|||
transition: opacity .4s, filter .4s; |
|||
padding-top: 160px; |
|||
|
|||
.row-container { |
|||
transform: skew(-2deg, -2deg) rotate(-2deg); |
|||
width: calc(100% - 50px); |
|||
max-width: 1400px; |
|||
margin: auto; |
|||
|
|||
.box { |
|||
position: relative; |
|||
display: flex; |
|||
border-radius: 4px; |
|||
overflow: hidden; |
|||
background: $black-alpha; |
|||
margin: 6px; |
|||
padding: 40px 20px; |
|||
min-height: 250px; |
|||
cursor: pointer; |
|||
transform: skew(6deg, -6deg) rotate(6deg); |
|||
transition: transform .4s, background .4s, box-shadow .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.text { |
|||
display: block; |
|||
margin: auto; |
|||
text-align: center; |
|||
transform: translate(0%, 0%); |
|||
color: $yellow; |
|||
//transition: color .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 1; |
|||
|
|||
.title { |
|||
display: block; |
|||
font-size: $font-20; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
.image { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
height: 100%; |
|||
width: 100%; |
|||
object-fit: cover; |
|||
transform: translate(-50%, -50%); |
|||
opacity: .9; |
|||
filter: grayscale(100%) brightness(.4); |
|||
transition: opacity .4s, filter .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.type { |
|||
display: block; |
|||
font-size: $font-16; |
|||
font-weight: bold; |
|||
.loader { |
|||
position: absolute; |
|||
top: 50%; |
|||
left: 50%; |
|||
height: 100%; |
|||
width: 100%; |
|||
object-fit: cover; |
|||
filter: invert(100%); |
|||
transform: translate(-50%, -50%); |
|||
z-index: 0; |
|||
} |
|||
|
|||
.tags { |
|||
.text { |
|||
display: block; |
|||
font-size: $font-12; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
padding-top: 10px; |
|||
} |
|||
margin: auto; |
|||
text-align: center; |
|||
transform: translate(0%, 0%); |
|||
color: $yellow; |
|||
//transition: color .4s; |
|||
-webkit-backface-visibility: hidden; |
|||
z-index: 1; |
|||
|
|||
.title { |
|||
display: block; |
|||
font-size: $font-20; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.date-container { |
|||
display: inline-flex; |
|||
flex-wrap: wrap; |
|||
.type { |
|||
display: block; |
|||
font-size: $font-16; |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.date-row { |
|||
.tags { |
|||
display: block; |
|||
width: 100%; |
|||
font-size: $font-12; |
|||
text-transform: uppercase; |
|||
font-weight: bold; |
|||
padding-top: 10px; |
|||
} |
|||
|
|||
.date { |
|||
display: inline-flex; |
|||
margin: auto; |
|||
font-size: $font-20; |
|||
} |
|||
.date-container { |
|||
display: inline-flex; |
|||
flex-wrap: wrap; |
|||
|
|||
.date-indication { |
|||
margin: 2px 5px auto 5px; |
|||
font-size: $font-12; |
|||
} |
|||
.date-row { |
|||
display: block; |
|||
width: 100%; |
|||
|
|||
&:nth-of-type(2) { |
|||
margin-top: -12px; |
|||
.date { |
|||
display: inline-flex; |
|||
margin: auto; |
|||
font-size: $font-20; |
|||
} |
|||
|
|||
.date-indication { |
|||
margin: 2px 5px auto 5px; |
|||
font-size: $font-12; |
|||
} |
|||
|
|||
&:nth-of-type(2) { |
|||
margin-top: -12px; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
@each $angle in 0,1,2,3,4,5,6 { |
|||
&.skew-#{$angle} { |
|||
transform: skew(#{$angle - 3}deg, #{$angle - 3}deg); |
|||
} |
|||
} |
|||
|
|||
&:hover { |
|||
background: $black; |
|||
z-index: 50; |
|||
&:hover { |
|||
box-shadow: 0 0 20px $white-alpha2; |
|||
background: $black; |
|||
z-index: 50; |
|||
|
|||
@each $angle in 0,1,2,3,4,5,6 { |
|||
&.skew-#{$angle} { |
|||
//transform: scale(1.4) rotate(2deg) skew(#{3 - $angle}deg, #{3 - $angle}deg); |
|||
transform: scale(1.4) rotate(0deg) skew(0deg, 0deg); |
|||
} |
|||
} |
|||
transform: scale(1.4) rotate(4deg) skew(3deg); |
|||
|
|||
.image { |
|||
filter: grayscale(0%) brightness(1); |
|||
opacity: .5; |
|||
} |
|||
.text { |
|||
//color: $yellow; |
|||
.image { |
|||
filter: grayscale(0%) brightness(1); |
|||
opacity: .7; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
@media (min-width: map-get($grid-breakpoints, 'md')) { |
|||
.component-portfolio { |
|||
.row-container { |
|||
width: calc(100% - 100px); |
|||
} |
|||
} |
|||
} |
|||
|
Loading…
Reference in new issue