mt-portfolio
Version:
A Portfolio maker for Angular with image, heading, caption, ability to add contact form and demo
358 lines (347 loc) • 19.9 kB
JavaScript
import { animation, style, animate, keyframes, trigger, transition, useAnimation } from '@angular/animations';
import * as i0 from '@angular/core';
import { Pipe, Component, Input, EventEmitter, Directive, Output, HostListener, NgModule } from '@angular/core';
import * as i1 from '@angular/platform-browser';
import * as i1$1 from '@angular/common';
import { CommonModule } from '@angular/common';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
class PortfolioModel {
constructor() {
this.src = '';
this.srcLarge = '';
this.srcMedium = '';
this.alt = '';
this.x = '';
this.y = '';
}
}
class SelectableModel {
constructor() {
this.title = '';
this.titleFull = '';
this.linkTitle = '';
this.caption = '';
this.link = '';
}
}
// =========================
// =========================
var AnimationType;
(function (AnimationType) {
AnimationType["Scale"] = "scale";
AnimationType["Fade"] = "fade";
AnimationType["Flip"] = "flip";
AnimationType["JackInTheBox"] = "jackInTheBox";
})(AnimationType || (AnimationType = {}));
// =========================
// Scale
// =========================
const scaleIn = animation([
style({ opacity: 0, transform: "scale(0.5)" }),
animate("{{time}} cubic-bezier(0.785, 0.135, 0.15, 0.86)", style({ opacity: 1, transform: "scale(1)" }))
]);
const scaleOut = animation([
animate("{{time}} cubic-bezier(0.785, 0.135, 0.15, 0.86)", style({ opacity: 0, transform: "scale(0.5)" }))
]);
// =========================
// Fade
// =========================
const fadeIn = animation([
style({ opacity: 0 }),
animate("{{time}} cubic-bezier(0.785, 0.135, 0.15, 0.86)", style({ opacity: 1 }))
]);
const fadeOut = animation([
animate("{{time}} cubic-bezier(0.785, 0.135, 0.15, 0.86)", style({ opacity: 0 }))
]);
// =========================
// Flip
// =========================
const flipIn = animation([
animate("{{time}} cubic-bezier(0.785, 0.135, 0.15, 0.86)", keyframes([
style({
opacity: 1,
transform: "perspective(400px) rotate3d(1, 0, 0, 90deg)",
offset: 0
}),
style({ transform: "perspective(400px)", offset: 1 })
]))
]);
const flipOut = animation([
// just hide it
]);
// =========================
// Jack in the box
// =========================
const jackIn = animation([
animate("{{time}} ease-in", keyframes([
style({
animationFillMode: "forwards",
transform: "scale(0.1) rotate(30deg)",
transformOrigin: "center bottom",
offset: 0
}),
style({
transform: "rotate(-10deg)",
offset: 0.5
}),
style({
transform: "rotate(3deg)",
offset: 0.7
}),
style({
transform: "perspective(400px)",
offset: 1
})
]))
]);
const jackOut = animation([
// just hide it
]);
class NoSanitizePipe {
constructor(domSanitizer) {
this.domSanitizer = domSanitizer;
}
transform(html) {
if (html)
return this.domSanitizer.bypassSecurityTrustHtml(html);
else
return '';
}
}
NoSanitizePipe.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: NoSanitizePipe, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Pipe });
NoSanitizePipe.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: NoSanitizePipe, name: "noSanitize" });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: NoSanitizePipe, decorators: [{
type: Pipe,
args: [{ name: 'noSanitize' }]
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; } });
class HeaderComponent {
constructor() {
this.headerList = [];
}
ngOnInit() {
}
}
HeaderComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: HeaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
HeaderComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.4", type: HeaderComponent, selector: "mt-header", inputs: { headerList: "headerList" }, ngImport: i0, template: "<div class=\"toolbar\" role=\"banner\" *ngIf=\"headerList.length\" >\n <ng-container *ngFor=\"let headerItem of headerList; let i = index\" class=\"wrap\">\n <div *ngIf=\"headerItem.enabled\">\n <a target=\"_blank\" rel=\"noopener\" [href]=\"headerItem.href\" [title]=\"headerItem.title\">\n <div [innerHtml]=\"headerItem.icon | noSanitize\"> </div>\n </a>\n </div>\n </ng-container>\n</div>", styles: [".toolbar{position:absolute;top:0;left:0;right:0;height:60px;display:flex;align-items:center;flex-direction:row-reverse;color:#f93;font-weight:600;z-index:100}.toolbar div{margin:0 6px}.toolbar a{margin:0 8px}.toolbar a:last-child{margin:0 16px}.toolbar a:hover{opacity:.8}\n"], directives: [{ type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }], pipes: { "noSanitize": NoSanitizePipe } });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: HeaderComponent, decorators: [{
type: Component,
args: [{
selector: 'mt-header',
templateUrl: './header.component.html',
styleUrls: ['./header.component.scss']
}]
}], ctorParameters: function () { return []; }, propDecorators: { headerList: [{
type: Input
}] } });
class SwipeDirective {
constructor() {
this.next = new EventEmitter();
this.previous = new EventEmitter();
this.swipeCoord = [0, 0];
this.swipeTime = new Date().getTime();
}
onSwipeStart($event) {
this.onSwipe($event, 'start');
}
onSwipeEnd($event) {
this.onSwipe($event, 'end');
}
onSwipe(e, when) {
this.swipe(e, when);
}
swipe(e, when) {
const coord = [e.changedTouches[0].clientX, e.changedTouches[0].clientY];
const time = new Date().getTime();
if (when === 'start') {
this.swipeCoord = coord;
this.swipeTime = time;
}
else if (when === 'end') {
const direction = [coord[0] - this.swipeCoord[0], coord[1] - this.swipeCoord[1]];
const duration = time - this.swipeTime;
if (duration < 1000 //
&& Math.abs(direction[0]) > 30 // Long enough
&& Math.abs(direction[0]) > Math.abs(direction[1] * 3)) { // Horizontal enough
const swipeDir = direction[0] < 0 ? 'next' : 'previous';
if (swipeDir === 'next') {
this.next.emit();
}
else {
this.previous.emit();
}
}
}
}
}
SwipeDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: SwipeDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
SwipeDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.2.4", type: SwipeDirective, selector: "[swipe]", outputs: { next: "next", previous: "previous" }, host: { listeners: { "touchstart": "onSwipeStart($event)", "touchend": "onSwipeEnd($event)" } }, ngImport: i0 });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: SwipeDirective, decorators: [{
type: Directive,
args: [{
selector: '[swipe]'
}]
}], ctorParameters: function () { return []; }, propDecorators: { next: [{
type: Output
}], previous: [{
type: Output
}], onSwipeStart: [{
type: HostListener,
args: ['touchstart', ['$event']]
}], onSwipeEnd: [{
type: HostListener,
args: ['touchend', ['$event']]
}] } });
class MtPortfolioComponent {
constructor(sanitizer) {
this.sanitizer = sanitizer;
this.portfolioList = [];
this.animationType = 'scale';
this.header = [];
this.currentSlide = 0;
}
onPreviousClick() {
const previous = this.currentSlide - 1;
this.currentSlide = previous < 0 ? this.portfolioList.length - 1 : previous;
// console.log("previous clicked, new current slide is: ", this.currentSlide);
}
onNextClick() {
const next = this.currentSlide + 1;
this.currentSlide = next === this.portfolioList.length ? 0 : next;
// console.log("next clicked, new current slide is: ", this.currentSlide);
}
ngOnInit() {
this.preloadImages();
if (location.hash !== "") {
const locationHash = this.portfolioList.find(s => { var _a; return ((_a = s.selectable) === null || _a === void 0 ? void 0 : _a.link) == location.hash; }) ? this.portfolioList.find(s => { var _a; return ((_a = s.selectable) === null || _a === void 0 ? void 0 : _a.link) == location.hash; }) : new PortfolioModel();
if (locationHash) {
this.currentSlide = this.portfolioList.indexOf(locationHash);
}
}
}
onSlideClick(slide) {
// const next = this.currentSlide + 1;
this.currentSlide = this.portfolioList.indexOf(slide);
}
preloadImages() {
for (const slide of this.portfolioList) {
new Image().src = slide.src;
}
}
}
MtPortfolioComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioComponent, deps: [{ token: i1.DomSanitizer }], target: i0.ɵɵFactoryTarget.Component });
MtPortfolioComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.4", type: MtPortfolioComponent, selector: "mt-portfolio", inputs: { portfolioList: "portfolioList", animationType: "animationType", header: "header" }, ngImport: i0, template: "<mt-header [headerList]=\"header\"></mt-header>\n<div class=\"container\">\n <div class=\"carousel\" *ngIf=\"portfolioList.length\">\n <ng-container *ngFor=\"let slide of portfolioList; let i = index\">\n <picture [@slideAnimation]=\"animationType\" swipe (next)=\"onNextClick()\" (previous)=\"onPreviousClick()\">\n <source media=\"(min-width:650px)\" srcset=\"{{slide.srcLarge? slide.srcLarge : slide.src}}\">\n <source media=\"(min-width:465px)\" srcset=\"{{slide.srcMedium? slide.srcMedium : slide.src}}\">\n <img *ngIf=\"i === currentSlide\" [src]=\"slide.src\" [alt]=\"slide.alt\" class=\"slide\"\n [@slideAnimation]=\"animationType\" />\n </picture>\n <div *ngIf=\"i === currentSlide\" class=\"my-name-div\" [style.right]=\"slide.x\" [style.top]=\"slide.y\"\n [@slideAnimation]=\"animationType\">\n <h1 class=\"header\" *ngIf=\"slide.selectable?.title\">\n {{slide.selectable?.title}}<span>{{slide.selectable?.titleFull}}</span></h1>\n <p *ngIf=\"slide.selectable?.caption\" [innerHTML]=\"slide.selectable?.caption | noSanitize\"></p>\n </div>\n\n </ng-container>\n\n\n <div class=\"control next selectable\">\n\n <div *ngFor=\"let slide of portfolioList; let i = index\">\n\n\n <a *ngIf=\"slide.selectable\" href=\"{{slide.selectable.link}}\"\n (click)=\"onSlideClick(slide)\">{{slide.selectable.linkTitle}}</a>\n </div>\n </div>\n\n <!-- controls -->\n <button *ngIf=\"currentSlide != 0\" class=\"control prev\" (click)=\"onPreviousClick()\">\n <span class=\"arrow left\"></span>\n </button>\n <button class=\"control next\" (click)=\"onNextClick()\">\n <span class=\"arrow right\"></span>\n </button>\n </div>\n</div>", styles: [".container{position:fixed;display:block;width:100vw;height:100vh;height:-webkit-fill-available}:host{flex:1}.carousel{position:relative;height:100%;width:100%;overflow:hidden}.slide{position:absolute;top:0;left:0;width:100%;height:100%;-o-object-fit:cover;object-fit:cover;transition:transform .15s cubic-bezier(.25,.46,.45,.84)}.slide:hover{transform:scale(1.025)}.control{border:none;background-color:transparent;outline:0;position:absolute;cursor:pointer;display:flex;flex-direction:column;justify-content:center;padding:.5em;color:#fff;font-weight:bold;font-size:3em;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;height:20%;opacity:80%;transition:opacity .15s cubic-bezier(.25,.46,.45,.84);bottom:0}.control.selectable{bottom:40vh;text-align:center;font-size:large}.control.selectable a{color:#a9a9a9;text-decoration:none;padding:5px;border:2px solid #ff9933;display:block;margin-bottom:5px}.control.selectable a:hover,.control.selectable a:focus{color:#fff}.control:hover,.control:focus{opacity:1}.control.next{right:0}.control.prev{left:0}.arrow{display:block;border-left:.1em solid white;border-bottom:.1em solid white;width:.5em;height:.5em}.arrow.left{transform:rotate(45deg)}.arrow.right{transform:rotate(225deg)}.header{color:#f93;font-size:50px;font-weight:bold;font-family:monospace;letter-spacing:7px;cursor:pointer}@media (max-width: 641px){.header{font-size:40px}}.my-name-div{position:absolute;color:#f0f8ff;width:40vw}.header span{transition:1s linear}.header:hover span:nth-child(1){margin-right:5px}.header:hover span:nth-child(2){margin-left:30px}.header:hover span{color:#fff;text-shadow:0 0 10px #fff,0 0 20px #fff,0 0 40px #fff}\n"], components: [{ type: HeaderComponent, selector: "mt-header", inputs: ["headerList"] }], directives: [{ type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: SwipeDirective, selector: "[swipe]", outputs: ["next", "previous"] }], pipes: { "noSanitize": NoSanitizePipe }, animations: [
trigger("slideAnimation", [
/* scale */
transition("void => scale", [
useAnimation(scaleIn, { params: { time: "1500ms" } })
]),
transition("scale => void", [
useAnimation(scaleOut, { params: { time: "1500ms" } })
]),
/* fade */
transition("void => fade", [
useAnimation(fadeIn, { params: { time: "1750ms" } })
]),
transition("fade => void", [
useAnimation(fadeOut, { params: { time: "1750ms" } })
]),
/* flip */
transition("void => flip", [
useAnimation(flipIn, { params: { time: "500ms" } })
]),
transition("flip => void", [
useAnimation(flipOut, { params: { time: "500ms" } })
]),
/* JackInTheBox */
transition("void => jackInTheBox", [
useAnimation(jackIn, { params: { time: "700ms" } })
]),
transition("jackInTheBox => void", [
useAnimation(jackOut, { params: { time: "700ms" } })
])
])
] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioComponent, decorators: [{
type: Component,
args: [{
selector: 'mt-portfolio',
templateUrl: './mt-portfolio.component.html',
styleUrls: ['./mt-portfolio.component.scss'],
animations: [
trigger("slideAnimation", [
/* scale */
transition("void => scale", [
useAnimation(scaleIn, { params: { time: "1500ms" } })
]),
transition("scale => void", [
useAnimation(scaleOut, { params: { time: "1500ms" } })
]),
/* fade */
transition("void => fade", [
useAnimation(fadeIn, { params: { time: "1750ms" } })
]),
transition("fade => void", [
useAnimation(fadeOut, { params: { time: "1750ms" } })
]),
/* flip */
transition("void => flip", [
useAnimation(flipIn, { params: { time: "500ms" } })
]),
transition("flip => void", [
useAnimation(flipOut, { params: { time: "500ms" } })
]),
/* JackInTheBox */
transition("void => jackInTheBox", [
useAnimation(jackIn, { params: { time: "700ms" } })
]),
transition("jackInTheBox => void", [
useAnimation(jackOut, { params: { time: "700ms" } })
])
])
]
}]
}], ctorParameters: function () { return [{ type: i1.DomSanitizer }]; }, propDecorators: { portfolioList: [{
type: Input
}], animationType: [{
type: Input
}], header: [{
type: Input
}] } });
class MtPortfolioModule {
}
MtPortfolioModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
MtPortfolioModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioModule, declarations: [HeaderComponent,
NoSanitizePipe,
SwipeDirective,
MtPortfolioComponent], imports: [CommonModule,
BrowserAnimationsModule], exports: [MtPortfolioComponent] });
MtPortfolioModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioModule, imports: [[
CommonModule,
BrowserAnimationsModule
]] });
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.4", ngImport: i0, type: MtPortfolioModule, decorators: [{
type: NgModule,
args: [{
declarations: [
HeaderComponent,
NoSanitizePipe,
SwipeDirective,
MtPortfolioComponent
],
imports: [
CommonModule,
BrowserAnimationsModule
],
exports: [
MtPortfolioComponent
]
}]
}] });
/*
* Public API Surface of mt-portfolio
*/
/**
* Generated bundle index. Do not edit.
*/
export { MtPortfolioComponent, MtPortfolioModule };
//# sourceMappingURL=mt-portfolio.js.map