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"; | @import "../../assets/scss/variables"; | ||||
| 
 | 
 | ||||
| .component-portfolio { | .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; |       -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; |         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; |           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