Browse Source

add home template

add random param in portfolio api
new portfolio graphic
hotfix/class_typo
Dslak 5 years ago
parent
commit
9e6fe92230
  1. 1
      package.json
  2. 3
      src/apis/index.php
  3. 3
      src/app/app-routing.module.ts
  4. 4
      src/app/app.module.ts
  5. 6
      src/app/header/header.component.ts
  6. 28
      src/app/home/home.component.html
  7. 139
      src/app/home/home.component.scss
  8. 25
      src/app/home/home.component.spec.ts
  9. 53
      src/app/home/home.component.ts
  10. 38
      src/app/portfolio/portfolio.component.html
  11. 196
      src/app/portfolio/portfolio.component.scss
  12. 6
      src/app/portfolio/portfolio.component.ts
  13. 4
      src/app/services/apis.service.ts
  14. 1
      src/assets/scss/variables.scss
  15. 2
      src/main.ts

1
package.json

@ -23,6 +23,7 @@
"@angular/router": "~9.1.7",
"@kolkov/angular-editor": "^1.1.4",
"bootstrap": "^4.5.3",
"hammerjs": "^2.0.8",
"ng-particles": "^2.1.11",
"ngx-image-gallery": "^2.0.5",
"rxjs": "~6.5.4",

3
src/apis/index.php

@ -15,7 +15,8 @@ if(isset($_GET['query'])) {
case "performances":
case "workshops":
if($_GET['query'] == 'portfolio') {$filter = '';} else {$filter = "WHERE type='".$_GET['query']."'";}
$qe = mysqli_query($conn,"SELECT * FROM `works` $filter ORDER BY id DESC");
if($_GET['random']) {$order .= 'ORDER BY id RAND()';} else {$order = "ORDER BY id DESC";}
$qe = mysqli_query($conn,"SELECT * FROM `works` $filter $order");
if(mysqli_num_rows($qe) > 0) {
$content = null;
$content->items = array();

3
src/app/app-routing.module.ts

@ -4,6 +4,7 @@ import { AppLayoutComponent } from './app-layout/app-layout.component'
import { AboutComponent } from './about/about.component'
import { PortfolioComponent } from './portfolio/portfolio.component'
import { DetailComponent } from './detail/detail.component'
import { HomeComponent } from './home/home.component'
import { AdminComponent } from './admin/admin.component'
const routes: Routes = [
@ -12,7 +13,7 @@ const routes: Routes = [
component: AppLayoutComponent,
children: [
//{ path: '', redirectTo: '/portfolio', pathMatch: 'full' },
{ path: '', component: PortfolioComponent },
{ path: '', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: 'portfolio', component: PortfolioComponent },
{ path: 'exhibitions', component: PortfolioComponent },

4
src/app/app.module.ts

@ -14,6 +14,7 @@ import { AboutComponent } from './about/about.component';
import { PortfolioComponent } from './portfolio/portfolio.component';
import { DetailComponent } from './detail/detail.component';
import { AdminComponent } from './admin/admin.component';
import { HomeComponent } from './home/home.component';
@NgModule({
declarations: [
@ -23,7 +24,8 @@ import { AdminComponent } from './admin/admin.component';
AboutComponent,
PortfolioComponent,
DetailComponent,
AdminComponent
AdminComponent,
HomeComponent
],
imports: [
BrowserModule,

6
src/app/header/header.component.ts

@ -9,7 +9,7 @@ import { DOCUMENT } from '@angular/common'
})
export class HeaderComponent implements OnInit {
public isSticky: boolean = false
public isSticky: boolean = true
public isMenuOpen: boolean = false
public isFirstScroll: boolean = true
@ -22,7 +22,7 @@ export class HeaderComponent implements OnInit {
}
ngOnInit(): void {
this.isSticky = this.router.url != '/'
//this.isSticky = this.router.url != '/'
}
@HostListener('window:scroll', ['$event'])
@ -32,7 +32,7 @@ export class HeaderComponent implements OnInit {
|| document.body.scrollTop || 0
this.isFirstScroll = this.router.url == '/'
this.isSticky = this.isFirstScroll ? this.isMenuOpen || verticalOffset > 10 : true
//this.isSticky = this.isFirstScroll ? this.isMenuOpen || verticalOffset > 10 : true
}
toggleMenu(): void {

28
src/app/home/home.component.html

@ -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>

139
src/app/home/home.component.scss

@ -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);}
}

25
src/app/home/home.component.spec.ts

@ -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();
});
});

53
src/app/home/home.component.ts

@ -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
}
}

38
src/app/portfolio/portfolio.component.html

@ -1,27 +1,25 @@
<div class="component-portfolio">
<div class="container">
<div class="row">
<div class="col-12 col-sm-6 mx-auto" [ngClass]="'col-md-' + item.width" *ngFor="let item of portfolioItems">
<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="row no-gutters row-container">
<div class="col-12 col-sm-6 mx-auto" [ngClass]="'col-md-' + item.width" *ngFor="let item of portfolioItems">
<div class="box" (click)="showDetails(item.id)">
<img class="loader" *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 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>
<span class="tags">{{item.tags}}</span>
</div>
<span class="tags">{{item.tags}}</span>
</div>
</div>
</div>

196
src/app/portfolio/portfolio.component.scss

@ -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);
}
}
}

6
src/app/portfolio/portfolio.component.ts

@ -42,7 +42,6 @@ export class PortfolioComponent implements OnInit {
case 1:
width = Math.floor(Math.random()*3)+3
cnt++
if(tot + width > 9) {
width = 12 - tot
tot = 0
@ -50,7 +49,6 @@ export class PortfolioComponent implements OnInit {
} else {
tot = tot + width
}
break;
case 2:
width = 12 - tot
@ -58,11 +56,7 @@ export class PortfolioComponent implements OnInit {
cnt = 0
break;
}
e.width = width
//((e.id % 5)+3)
//Math.floor((Math.random()*3)+1)+2
})
},(error) => {
console.error('getPortfolio ERROR', error)

4
src/app/services/apis.service.ts

@ -16,8 +16,8 @@ export class ApisService extends BaseService {
super()
}
getPortfolio(section): Observable<any> {
let urlApi = `${this.restApi}?query=${section}`
getPortfolio(section, randon = false): Observable<any> {
let urlApi = `${this.restApi}?query=${section}&random=${randon}`
return this.http.get<any>(urlApi).pipe(
catchError(this.handleError)
)

1
src/assets/scss/variables.scss

@ -34,6 +34,7 @@ $yellow: #a2dc02;
$white-alpha: rgba(255, 255, 255, 0.8);
$white-alpha2: rgba(255, 255, 255, 0.4);
$black-alpha: rgba(0, 0, 0, 0.8);
$black-alpha2: rgba(0, 0, 0, 0.4);
$yellow-alpha: rgba(160, 220, 0, 0.8);
// Fonts

2
src/main.ts

@ -4,6 +4,8 @@ import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';
import 'hammerjs';
if (environment.production) {
enableProdMode();
}

Loading…
Cancel
Save