Skip to content

Commit

Permalink
feat(renderlevels): implemented multiple render levels to be shown dy…
Browse files Browse the repository at this point in the history
…namically for all common screen sizes.
  • Loading branch information
Benjamin Brandmeier committed Jun 13, 2016
1 parent 989170a commit f2dcffc
Show file tree
Hide file tree
Showing 7 changed files with 117 additions and 85 deletions.
4 changes: 2 additions & 2 deletions src/app/gallery.component.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="galleryContainer" #galleryContainer>
<div class="innerGalleryContainer">
<div *ngFor='let imgrow of gallery; let i = index' class="imagerow">
<img *ngFor='let img of imgrow; let j = index' class="thumbnail" [style.width.px]="img.width" [style.height.px]="img.height" (click)="openImageViewer(img)" [src]="img.thumbnail" />
<img *ngFor='let img of imgrow; let j = index' class="thumbnail" [style.width.px]="img.width" [style.height.px]="img.height" (click)="openImageViewer(img)" [src]="thumbnailBasePath + img.name" />
</div>
<div #asyncLoadingContainer class="asyncLoadingContainer"></div>
</div>
Expand All @@ -15,7 +15,7 @@
<img class="action close" src="assets/img/icon/close.svg" (click)="showBig = !showBig" [hidden]="!showBig" />
</div>
<div class="imageContainer" [hidden]="!showBig">
<img class="image" [src]="images[currentIdx].preview" [hidden]="!showBig" />
<img class="image" [src]="previewImage" [hidden]="!showBig" />
</div>
</div>

Expand Down
35 changes: 31 additions & 4 deletions src/app/gallery.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export class GalleryAppComponent {
@ViewChild('galleryContainer') galleryContainer: ElementRef;
@ViewChild('asyncLoadingContainer') asyncLoadingContainer: ElementRef;

thumbnailBasePath = 'assets/img/gallery/preview_xxs/'
localState = { value: '' }
currentImg: string
currentIdx: number = 0
Expand All @@ -37,6 +38,7 @@ export class GalleryAppComponent {
heightCoefficient = 6
imgIterations = 1;
allImagesLoaded = false
previewImage = ''

// TypeScript public modifiers
constructor(private _ngZone: NgZone, private http: Http, private router: Router) {
Expand All @@ -47,6 +49,7 @@ export class GalleryAppComponent {
window.onresize = function(event) {
this._ngZone.run(() => {
this.scaleGallery()
this.updatePreviewImage()
})
}.bind(this)

Expand All @@ -71,7 +74,7 @@ export class GalleryAppComponent {

let tempRow = [data[0]]
let rowIndex = 0
let i = 0;
let i = 0

for (i; i < this.imgIterations && i < data.length; i++) {
while (data[i + 1] && this.shouldAddCandidate(tempRow, data[i + 1])) {
Expand Down Expand Up @@ -177,7 +180,7 @@ export class GalleryAppComponent {
this.currentIdx++
this.updateArrowActivation()
}
this.currentImg = this.images[this.currentIdx].url
this.currentImg = this.thumbnailBasePath + this.images[this.currentIdx].name

}

Expand All @@ -186,7 +189,7 @@ export class GalleryAppComponent {
this.currentIdx--
this.updateArrowActivation()
}
this.currentImg = this.images[this.currentIdx].url
this.currentImg = this.thumbnailBasePath + this.images[this.currentIdx].name
}

updateArrowActivation() {
Expand All @@ -203,6 +206,7 @@ export class GalleryAppComponent {
else {
this.rightArrowActive = true
}
this.updatePreviewImage();
}

openImageViewer(img) {
Expand All @@ -212,7 +216,7 @@ export class GalleryAppComponent {
}

openFullsize() {
window.location.href = this.images[this.currentIdx].url
window.location.href = 'assets/img/gallery/raw/' + this.images[this.currentIdx].name
}

private getGalleryWidth() {
Expand All @@ -238,4 +242,27 @@ export class GalleryAppComponent {
}
}
}

private updatePreviewImage() {
let height = window.innerHeight
let basePath = 'assets/img/gallery/'

if (height <= 375) {
basePath += 'preview_xxs/'
} else if (height <= 768) {
basePath += 'preview_xs/'
} else if (height <= 1080) {
basePath += 'preview_s/'
} else if (height <= 1600) {
basePath += 'preview_m/'
} else if (height <= 2160) {
basePath += 'preview_l/'
} else if (height <= 2880) {
basePath += 'preview_xl/'
} else {
basePath += 'raw'
}

this.previewImage = basePath + this.images[this.currentIdx].name
}
}
2 changes: 2 additions & 0 deletions src/assets/img/gallery/.gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
data.json
raw
preview_*
1 change: 0 additions & 1 deletion src/assets/img/gallery/preview/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion src/assets/img/gallery/raw/.gitignore

This file was deleted.

1 change: 0 additions & 1 deletion src/assets/img/gallery/thumbnail/.gitignore

This file was deleted.

158 changes: 82 additions & 76 deletions tools/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,106 +4,109 @@ var mkdirp = require('mkdirp');
var process = require("process");
var gm = require('gm');

var sortFunction;
var projectRoot = getProjectRootPath();
var basePath = projectRoot + "/tools/images_to_convert";
var assetBasePath = projectRoot + "/src/assets/img/gallery/";
var rawBasePath = "assets/img/gallery/raw/";
var thumbnailBasePath = "assets/img/gallery/thumbnail/";
var previewBasePath = "assets/img/gallery/preview/";
var imageMetadataArray = [];
var resolutions = [
{ name: 'preview_xxs', height: 375 },
{ name: 'preview_xs', height: 768 },
{ name: 'preview_s', height: 1080 },
{ name: 'preview_m', height: 1600 },
{ name: 'preview_l', height: 2160 },
{ name: 'preview_xl', height: 2880 }
];

function convert() {
createFolderStructure();

fs.readdir(basePath, function(err, files) {
if (err) throw err;
var files = fs.readdirSync(basePath);

// TODO: Implement different sorting mechanisms (e.g. by filename, manually, ...)
var sortFunction = sortByCreationDate;

var processCount = 0;
var imagesToProcess = 0;

console.log('\nIdentifying images...')
files.forEach(function(file, index) {
if (file != '.gitignore') {
var filePath = path.join(basePath, file);
if (fs.lstatSync(filePath).isFile()) {
process.stdout.write('Identified '+(++imagesToProcess)+' images.\r');
gm(filePath)
.identify(function(err, features) {
if (err) {
console.log(filePath)
console.log(err)
throw err;
}

var fileMetadata = {
url: rawBasePath + file,
thumbnail: thumbnailBasePath + file,
preview: previewBasePath + file,
date: features['Profile-EXIF']['Date Time Original'],
width: features.size.width,
height: features.size.height
};

imageMetadataArray[processCount] = fileMetadata;

// copy raw images to assets folder
fs.createReadStream(filePath).pipe(fs.createWriteStream(assetBasePath + 'raw/' + file));

// create thumbnails and save them
createThumbnail(file, filePath);

// create thumbnails and save them
createPreview(file, filePath);

process.stdout.write('Converted '+(++processCount)+' images.\r');
if (processCount == imagesToProcess) {

// after image processing sort image metadata as requested
sortFunction();

// save meta data file
saveMetadataFile();
}
});
}
}
});
console.log('\n\nConverting images...');
process.stdout.write('Converted 0 images.\r');
});
// TODO: Implement different sorting mechanisms (e.g. by filename, manually, ...)
sortFunction = sortByCreationDate;

precheckFile(files, 0);

console.log('\nConverting images...');
}

function createFolderStructure() {
console.log('\nCreating folder structure...');
mkdirp.sync(assetBasePath + 'raw', function(err) {
if (err) throw err;
});
mkdirp.sync(assetBasePath + 'thumbnail', function(err) {
if (err) throw err;
});
mkdirp.sync(assetBasePath + 'preview', function(err) {
if (err) throw err;
});

for (var i in resolutions) {
mkdirp.sync(assetBasePath + resolutions[i].name, function(err) {
if (err) throw err;
});
}

console.log('...done (folder structure)');
}

function createThumbnail(file, filePath) {
function precheckFile(files, fidx) {
if (fidx < files.length) {
var file = files[fidx];
if (file != '.gitignore') {
var filePath = path.join(basePath, file);
if (fs.lstatSync(filePath).isFile()) {
identifyImage(files, fidx, filePath, file);
}
else {
precheckFile(files, ++fidx);
}
}
else {
precheckFile(files, ++fidx);
}
}
else {
// after image processing sort image metadata as requested
sortFunction();
}
}

function identifyImage(files, fidx, filePath, file) {
gm(filePath)
.resize(null, 350)
.write(assetBasePath + 'thumbnail/' + file, function(err) {
if (err) throw err;
.identify(function(err, features) {
if (err) {
console.log(filePath)
console.log(err)
throw err;
}

var fileMetadata = {
name: file,
raw: rawBasePath + file,
date: features['Profile-EXIF']['Date Time Original'],
width: Math.round((375/features.size.height)*features.size.width),
height: 375
};

imageMetadataArray.push(fileMetadata);

// copy raw image to assets folder
fs.createReadStream(filePath).pipe(fs.createWriteStream(assetBasePath + 'raw/' + file));

createPreviewImageSync(files, fidx, filePath, file, 0);
});
}

// TODO: create different resolution stages based and show them based on viewport size
function createPreview(file, filePath) {
gm(filePath)
.resize(null, 1000)
.write(assetBasePath + 'preview/' + file, function(err) {
if (err) throw err;
function createPreviewImageSync(files, fidx, filePath, file, index) {
// create various preview images
gm(filePath)
.resize(null, resolutions[index].height)
.write(assetBasePath + resolutions[index].name + '/' + file, function(err) {
if (err) throw err;
if (index < resolutions.length-1) {
createPreviewImageSync(files, fidx, filePath, file, ++index);
} else {
process.stdout.write('Converted '+(fidx)+' images.\r');
precheckFile(files, ++fidx);
}
});
}

Expand All @@ -120,6 +123,9 @@ function sortByCreationDate() {
}
});
console.log('...done (sorting)');

// save metadata file
saveMetadataFile();
}

function saveMetadataFile() {
Expand Down

0 comments on commit f2dcffc

Please sign in to comment.