Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - tsaiDavid/emulsion: Explore film types through my exploration of working with mostly Vanilla JS. · GitHub
Skip to content

Repository files navigation

Emulsion - A Photo Grid for Film Lovers and Slackers

Introduction

Emulsion is a photography-focused web application built from the ground up using "Vanilla JS". Users learn and visualize different photographic films through a curated assortment from Flickr's API. Extra educational text is provided, highlighting unique characteristics of each film.

While the basic idea of using "Vanilla JS" to fetch photos and display them in a grid/lightbox remains the same, the product concept was important to me - since film photography (and subsequently Flickr) were a huge part of my life.

We live in a fast paced world - we engineers blitz forward, often forgetting to slow down... missing countless moments. Film photography taught me just that. Given a finite amount of "shots" I could take - each one had to be calculated, impactful, and thoughtful. For this reason, the user is guided into a state of being unable to "go back" to the previous type of film viewed. Just like shooting film, once you advance to the next frame, you generally cannot rewind and see the shot you just took.

I hope the app proves to be meaningful - showing everyone that film photography can be a beautiful thing!

Screenshot of Emulsion

Documentation

Tech Overview

While Emulsion doesn't rely on external libraries or frameworks, it leverages Babel for ES6.

  • Gulp
  • Babel
  • ESLint
  • SCSS

Application Design

Overview

Originally conceived with a MVC (Model-View-Controller) pattern in mind, this idea soon fell out of favor. With limited time, I needed to highlight my major needs within my code:

  • Extensible (modular)
  • Maintainable (documentation helps here)

With these key features in mind, I shifted my attention to use component-based architecture. Inspired by my personal passion for exploring highly functional languages and patterns - I believe state management should be easy! Emulsion's main app.js is where most of the magic happens - it's got a 'global' event listener, waiting for custom stateChange events. These events bubble up from anywhere else and carry a payload. Based on its action type, we can update state and UI simultaneously from the top-level app.

Here are some key features that stand out in my code:

  • Application state is referred to as the "single source of truth"
    • This makes it easier to reason about, as opposed to juggling stores and various models.
  • Minimal side effects, use pure functions
  • Maximize modularity - callback heaven!
  • Avoid touching the window object

I should mention that although my code is original - if you're wondering what inspired me to take this top-down approach, I was inspired by my learnings in:

  • React's Flux / Redux architectures
  • Clojure / ClojureScript
  • Elm

App State and Management

Previously, I explained how I arrived at using "state" in the context of a Emulsion global namespace.

Since app and user actions can readily be defined, I chose to conceptually highlight the major ones (a few examples):

  • fetch photos (set)
  • switch photos (when loading a new set)
  • render photos
  • remove photos

Since all events bubble up to the top-level app, debugging becomes easier. With a simple console.log, we can reveal both the action that was emitted and the current 'state' of the application. Without the crazy tangle of 100% traditional two-way data binding, state starts to become a little easier to reason about.

Another intent behind this project's methodology, was to demonstrate that "simple Vanilla JS" apps could benefit from a different approach, not reliant on heavy frameworks and libraries by other folks.

Source

Browse Emulsion's source code

Play with Live Demo

File Structure

The application's file structure is described below:

emulsion
│ README.md (you're reading this now!)
│ package.json (make sure to run npm install)
│ .eslintrc (I hope you're a stickler for clean code!)
│ .gulpfile.babel.js (Gulp's tasks configured here)
│
└───app
│ index.html
│
├───scripts
│ │ app.js (the main app)
│ │ grid.js (the grid module, responsible for the image grid)
│ │ helpers.js (all our $EH helper functions go here)
│ │ init.js (this script helps attach some event listeners!)
│ │ filmText.js (contains all our film descriptions)
│
└───styles
│ main.scss (our main style sheet, requiring all others via imports)
│ base (the app's base styles go here)
│ components (component styles like the overlay, button, etc)
│ layout (styles involving general page layout)
│ utils (reusable variables, functions, etc)
│ vendor (vendor files like Normalize can go here)

Please note that I've followed the suggested pattern for directory structure for SASS, albeit slightly condensed for this smaller app

Get Started

Before you start, you'll want to install the necessary npm packages.

npm install

Now we can begin having fun!

To run the application and take advantage of Browser Sync's live reloading:

gulp serve

To run the apps' tests and take advantage of Browser Sync's live reloading:

gulp serve:test

To build the files (to a 'dist' directory), run:

gulp

Code Style and Methodology

Application uses no frameworks, instead relying on a "global" app state.

Code style is heavily inspired by the new "standard" that AirBnb has set forth, which is actually now the standard used by MDN! I softened some of the rules for this project.

Roadmap

With a short time frame to complete this project there are some other things I would like to finish:

  • More unit tests
  • Evaluate further code modularity
  • Implement client-side bundling (browserify, webpack)
  • ES6 Fetch Polyfill (just because!)
  • Generate JSdocs (I have already prepared my app for it, see source code)
  • Fix small CSS bugs
    • I prioritized general code cleanliness and a thorough approach to code construction and documentation. I realize there are a few CSS issues that can be improved - and will likely fix those ASAP!

Flickr

Note: API KEYS should never be exposed! The one you see in the app is for demo use only.

To learn more about the Flickr endpoint I used: https://www.flickr.com/services/api/misc.urls.html

About

Explore film types through my exploration of working with mostly Vanilla JS.

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages