Muffin Man's writings

or the front end playground

Front end development, maybe occasional rants and music.

localStorage and sessionStorage in Safari's private mode

If you didn’t know, in Safari’s private mode both localStorage and sessionStorage are not working. To be exact, Safari sets storage’s limit to 0, so you can’t write anything to it. I keep forgetting this, until QA people report it at some point.

So I quickly wrote a small facade for it, which fails silently in this case. That means it still doesn’t work but it won’t throw an error and break your application.

This is the version for localStorage, just replace it with sessionStorage if you need it.

const LS_TEST_KEY = 'ls-test';
let isLocalStorageSupported = typeof localStorage === 'object';

// Try to
try {
  localStorage.setItem(LS_TEST_KEY, 'test');
  localStorage.removeItem(LS_TEST_KEY);
} catch (e) {
  isLocalStorageSupported = false;

  // If we get error that we exceeded storage's quota
  // but storage is still empty we are in private mode
  if (e.code === DOMException.QUOTA_EXCEEDED_ERR && localStorage.length === 0) {
    // Private mode
  } else {
    throw e;
  }
}

const LocalStorage = {
  getItem: (key) => {
    if (isLocalStorageSupported) {
      return localStorage.getItem(key);
    }

    return null;
  },

  setItem: (key, value) => {
    if (isLocalStorageSupported) {
      localStorage.setItem(key, value);
    }
  },

  removeItem: (key) => {
    if (isLocalStorageSupported) {
      localStorage.removeItem(key);
    }
  },
};


export default LocalStorage;

Get element offset in JavaScript

When we left jQuery behind and embraced modern JavaScript frameworks, we thought we would never touch DOM directly again. Well that is not entirely true. There are a lot of cases when you need to get some DOM element size. For element’s dimensions .offsetWidth and .offsetHeight are great way to do it.

But one of the other common tasks is getting element’s offset, top and left. I’ll show you two ways to get those.

Read more

Plx - React parallax component

I’m becoming predictable. Again, I haven’t found component I like, so I wrote my own.

This time, I’ve build React component for parallax (on scroll) effects. Check the live demo. It is called Plx, it is open source and available on GitHub and npm.

What it does

So far in my career, I’ve built so many parallax components. Parallax is actually wrong term here1, but it got accepted by development community.

Designers love them and users are fascinated by fancy effects. Simply explained as you scroll the page down something is changed relative to the scroll position. For example, as you scroll down clock arms are rotating. Just check the demo.

There is a lot of solutions out there, but IMHO they are usually bloated or not performant or complicated to use. And as I’m using React a lot, I decided to collect what I have learned about implementing on scroll effects in React and create standalone component. Most of the code in this component is pulled out from my existing projects and glued together.

1 the effect whereby the position or direction of an object appears to differ when viewed from different positions, e.g. through the viewfinder and the lens of a camera.

Read more

waifu2x super resolution image resizer

I use the same wallpaper1 (warning, 6mb file) for a long time now. Not sure who is the author (if anyone knows the original author, please let me know in the comments). But with high resolution displays, wallpaper started to look blurry and noisy, so I stopped using it.

But recently, my girlfriend reminded me of this great website which super-scales images using magic. Ok, not magic, but it uses “Deep Convolutional Neural Networks”, which is pretty much the same thing. Results are amazing, try it yourself.

The best thing, website is free to use and project is opensource. Code is available on GitHub.

It supports max scaling of 2x, so if you need more you’ll need to process image multiple times. Or you can dig in the code and add option for arbitrary scaling.

1 This is the resized image using waifu2x.

Example

Original, 250x250px jpeg 2

Original 250x250px image

Result, 500x500px png

Resized 2x 500x500px image

If you ask me, results are really impressive, kudos to nagadomi!

2 Image is from my favorite animated show Rick and Morty

Animate React component by calling 'setState' in 'componentDidMount'

On the front end, we do a lot of animations. Most of the simple animations I create by using CSS transitions. Either I will change class or inline style of the element, and define transitions in CSS file.

Easiest way to do this in React is to render initial state, and then when it renders, change the state to apply class or style to animate. The easiest way to do it in React is to change state in componentDidMount. Setting state in componentDidMount is considered to be anti-pattern, as it forces rerender and can lead to property/layout thrashing. But in our case, that is exactly what we want to do.

When we do that, we hit the wall - only second state is rendered and there is no transition between two states. It happens because of browsers optimization - browsers are not rerendering stuff that changed in the same animation frame. But they merge changes and render the end result.

The problem I just described is not React exclusive, but browser related. Same will happen if we try something like this:

const element = document.querySelector('.AnimateMe');
element.style.height = '50px';
element.style.height = '250px';

So let’s start with example of the problem.

Read more