summaryrefslogtreecommitdiff
path: root/README.md
blob: 78ceb79f17cd0c82ebd929aabe64a72b2b43f0bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
<div align="center">
<img src="assets/logo.svg" width="300">

# Imagine
> A simple Image Editor

[Source Code](https://source.orangerot.dev/university/imagine) | [Preview](https://orangerot.dev/archive/uni/imagine)
</div>
    
## Idee

> Ihre App verwendet mindestens ein HTML5 Feature erfolgreich.

Imagine ist eine Single Page Application um einfache Bildbearbeitungen
durchzuführen. Dabei stehen dem Nutzer im Editor mehrere Filter zur verfügung.

Bilder können über drei Wege geladen werden. Erstens können Bilder geladen
werden, indem der nutzer auf einen Knopf auf dem Startbildschirm drückt, wodurch
ein Dateiauswahl-Dialog erscheint. Auf Mobilgeräten (getestet auf Android) wird
hier ebenfalls die möglichkeit geboten ein Bild über die Kamera aufzunehmen. Auf
anderen Geräten kann ein Bild gemacht werden, indem der Nutzer auf ein Knopf auf
dem Startbildschirm drückt, wodurch der Feed einer Webcam auf der Webseite
gezeigt wird. Zuletzt kann ein Bild auch jederzeit geladen werden, indem es per
Drag-'n-Drop in den Viewport gezogen wird. 

Sobald ein Bild importiert wurde, öffnet sich der Editor. Hier erscheint das
Bild und eine Reihe an Filtern, welche auf das Bild angewendet werden können.
Die Intensität der Filter können über einen Slider justiert werden. Ein
Zurücksetzen-Knopf ermöglicht es, den Filter wieder zurück zu dem neutralen
Zustand zu setzen. Ein Lensflare-Knopf ermöglicht es, einen Lensflare-Shader zu
dem Bild hinzuzufügen. Die Richtung der Einstrahlung kann mit eingestellt
werden, indem man die Maus mit gedrückter linken Maustaste über das Bild bewegt
oder sein Mobiltelefon in die gewünschte Richtung neigt. 

Sobald das Bild nach seinen Wünschen angepasst ist, kann man das Bild entweder
lokal herunterladen oder auf anderen Apps teilen (getestet
Anrdoid/Chromium/Bromite). 

### Verwendete HTML5 Features

Diese Anwendung verwendet einige HTML5-Features. So wird der `<video>`-Tag
verwendet, um den Videofeed der Webcam zu zeigen. Ein `<canvas>`-Element wird
verwendet, um alle Filter auf das Bild anzuwenden. Zuletzt werden mehrere
Browser-APIs verwendet, darunter: `navigator.share`, `deviceorientation`,
`mousemove`, `camera`, ...

## Code-Qualität

> Ihre Website ist sauber strukturiert (HTML, CSS, JS Dateien
getrennt) und hat eine saubere sowie einheitliche Formatierung

HTML, CSS und JavaScript sind jeweils in eigene Dateien aufgeteilt. Das HTML
beinhaltet kein inline CSS und kein inline JavaScript. Alle Datein sind mit zwei
Leerzeichen eingerückt. Zusätzlich wurden alle Dateien mit dem Formatter
`prettier` formatiert. 

## Dokumentation

> Ihr Code ist dokumentiert.

Das HTML enthält Kommentare zur strukturellen Unterteilunge, als auch zum
erklären und begründen verwendeter Elemente.

JavaScript enthält JSDoc zum beschreiben der einzelnen Funktionen und einzelne
Kommentare zum erklären und begründen von Code-Segmenten. 

## Technische Raffinesse

> Ihre Umsetzung ist nicht trivial (zum Beispiel verarbeiten Sie
Sensordaten, Nutzen APIs etc.), Gesamtumfang > 1000 Zeilen

Von der technischen Seite nutzt die Anwendung mehrere Sensordaten und zudem
einige Browser-APIs. Gleich zu Begin, beim laden des Bildes, steht dem Nutzer
die Option ein Bild von dem Videofeed der Webcam zu machen. Dafür wird die API
`navigator.mediaDevices.getUserMedia` verwendet. Des Weiteren werden für den
Lensflare-Shader Sensordaten erhoben, um die Einstrahlung zu bestimmen. Dafür
wird einmal die Mausposition mit dem Event `mousemove` abgefragt. Außerdem kann
man die Eintrahlung über die Neigung des Gerätes mit dem Event
`deviceorientation` einstellen.

Weitere Browser-APIs, die genutzt wurden, sind die drag-'n-drop api mit dem
Event `dragover` und die `navigator.share`-API, um das Bild mit anderen Apps zu
teilen. 

Möglichst viel wurde in HTML und CSS abgebildet. Der Wechsel von
Startbildschirm, Camera-Aufnahme und Editor wurde durch das Ändern der Klasse
von `body`-Tag gelösst. Insgesamt werden keine dynamischen Elemente in
JavaScript erzeugt. Es müssen weniger Abfragen und Änderungen im DOM gemacht
werden. Das macht den JavaScript-Code einfacher und folgt der Trennung von Logik
und Aussehen. 

Der Lensflare ist als Shader umgesetzt, um möglichst realistisch auszusehen und
um es einfach zu machen in der zukunft andere Shader zu nutzen. Als Grundlage
dient ein GLSL Shader, welcher optimiert wurde, um je Pixel möglichst wenige
mathematische Operationen berechnen und wenig Speicher zu allokieren. 

Zeichenaufrufe wurden so weit minimiert, dass das Bild immer nur bei Änderungen
der Filter neu berechnet wird. Ansonsten bräuchten der Blur-Filter und
Lensflare-Shader zu viel Rechenleistung, sodass die Anwendung zum stocken käme. 

## Responsive 

> Ihre Website funktioniert mit unterschiedlichen Displaygrößen
(Handy, Tablet, Laptop, etc.)

Die Anwendung zeigt immer nur das Nötigste an, um dem Nutzer nur Elemente zu
zeigen, die zu dem Zeitpunkt nutzbar sind und um Bildschirmplatz zu sparen,
wodurch auch auf kleinen Displaygrößen noch alles bedienbar ist. 

Der Editor verändert die Position der Filter je nach Displaygröße. Auf dem
Desktop werden die Filter als Seitenseite angezeigt. Auf Tablet und Smartphones
verschwindet diese Seitenleiste. Stattdessen kann man manuell oder mit inem
Knopf runterscrollen, wodurch die Filter von unten Sichtbar werden und den
Viewport verdecken. Durch hochscrollen oder drücken auf einen weiteren Knopf
gehen die Filter wieder nach unten, um den Viewport wieder sichtbar zu machen. 

Realisiert wird dieser Effekt dadurch, dass der Viewport sich trotz scrollen
nicht bewegt (`display: sticky`), während die Filter über dem Viewport liegen
(`z-index`). Das Ein- und Ausblenden je nach Displaygröße realisiert das
CSS-Framework Bulma durch `@mediaquery`. 

## Used Resources

- https://developer.mozilla.org/en-US/docs/Web/API/Media_Capture_and_Streams_API/Taking_still_photos

### Used Libraries

- https://bulma.io/
- https://github.com/eliajf/bulma-slider

## License

This project is licensed under the AGPL-3 License - see the `LICENSE` file for details