InVision Studio

Stunning new work by the folks over at InVision:

Coming January 2018

InVision Studio →

Elsewhere , Leave a comment

Stealing your browser history with the W3C Ambient Light Sensor API

A few years ago window.getComputedStyle and the like where adjusted to return the default color of links, instead of the actual color on screen.

Security and privacy were the driving factors behind that decision: by styling :visited links with a different color than their non-visited counterparts, a hacker could easily determine which sites a user has visited by simply checking the color of each link.

// @ref
var links = document.links;
for (var i = 0; i < links.length; ++i) {
    var link = links[i];
    if (getComputedStyle(link, "").color == "rgb(0, 0, 128)") {
        // we know link.href has not been visited
    } else {
        // we know link.href has been visited

With that hole now plugged for quite some time, Lukasz Olejnik turned towards the Ambient Light Sensor API to perform a likewise hack:

Since a website can apply different styles to visited and unvisited links, but cannot detect how the links are displayed to the user, we use the sensor to identify its true color:

  1. Set link styles: visited (white), unvisited (black).
  2. Calibrate: display a white background, then follow with a black background to identify the light levels in the user’s environment; this is also possible, but more difficult, if sensor readings fluctuate significantly.
  3. Iterate through a list of links, one by one, displaying each of them in turn as a large rectangle which fills the entire screen. Visited links will show up as white, unvisited as black.
  4. Log the light levels in response to displaying each link, identifying its color. Since we calibrated the screen in step #2, we know which color each reading represents.

At the end the attacker obtains a list of links for which the screen was white and knows that the user had previously visited the given pages.

Using the same technique it's also possible read out QR codes.

Stealing sensitive browser data with the W3C Ambient Light Sensor API →

Elsewhere , , , , Leave a comment

Luna Display’s “Camera Button”

What do you do when Apple keeps on taking away buttons from their devices (and when swipe gestures from nearly all edges are already taken by something else)? Well, you invent a new button:

So when we ran out of buttons to hide our software’s UI behind, it really forced us to use our imagination. Instead of squeezing UI in where it didn’t fit, we built a new button to conceal it: it’s called the Camera Button.

The Camera Button basically transforms your iDevice’s camera lens into an ambient light sensor:

The Camera Button works by detecting the amount of light coming in through the camera. Covering up the camera with your finger blocks all light, triggering a response from the iPad. The tricky part was getting it to work in all lighting conditions, across all iPad cameras.


While Apple is taking away buttons, we found a way to add one →

Elsewhere , , Leave a comment

Browsershot: Convert a webpage to an image or PDF using headless Chrome

The folks over at Spatie have just release Browsershot v3:

Browsershot is a PHP package which can convert a webpage to an image or pdf. The conversion is done behind the scenes by Puppeteer which controls a headless version of Google Chrome.

Conversion is easy-peasy, hence this example:

use Spatie\Browsershot\Browsershot;

// an image will be saved

To save to a PDF give the target path a .pdf extension, or use the savePdf() method. Here’s an example with some more manipulations:

   ->paperSize($width, $height)
   ->margins($top, $right, $bottom, $left)

Don’t forget to install the required puppeteer:

npm install puppeteer

Browsershot →

Elsewhere , , , , Leave a comment

Building a desktop application with Electron

Good introductory tutorial on getting started with Electron.

A detailed guide on building your very own sound machine using JavaScript, Node.js and Electron

Building a desktop application with Electron →

Elsewhere , , , Leave a comment


Nice scroll effect on the BADASS Films website:

The effect is achieved by placing a duplicate (but clipped) list on top of another one, in combination with scroll velocity calculation to define the slant of the list.

BADASS &rarr

Elsewhere , , , Leave a comment

Behind the Magic of Rogue One: A Star Wars Story

This full-length reel represents a sample of the work created for over 1750 shots by hundreds of artists, scientists, and engineers around the world.

Elsewhere , , Leave a comment

Sticky Sidebar

Sticky Sidebar ⬆⬇ is a pure JavaScript plugin for making smart and high performance sticky sidebar, works with sidebar if it’s taller or shorter than the viewport, integrated with resize sensor to re-calculate the dimensions automatically when the size of sidebar or its container is changed, supports jQuery/Zepto and compatible with Firefox, Chrome, Safari, and IE9+.

<div id="main-content" class="main">
    <div id="sidebar" class="sidebar">
        <div class="sidebar__inner">
            <!-- Content goes here -->
    <div id="content" class="content">
        <!-- Content goes here -->

<script type="text/javascript">
    var sidebar = new StickySidebar('#sidebar', {
        containerSelector: '#main-content',
        innerWrapperSelector: '.sidebar__inner',
        topSpacing: 20,
        bottomSpacing: 20

Sticky Sidebar →

Elsewhere , , 2 Comments

Create and share beautiful images of your source code with Carbon

Carbon is a great tool to create lovely source code screenshots you can share.

Just start typing, or drop a file into the textarea.

An example image generated by Carbon is included above. Supports several themes and syntaxes.

Carbon →

Elsewhere , , Leave a comment

Easier imports with Webpack’s resolve.alias

One of the things I find annoying when using import in my JS code is the fact that you need to refer to other local files using (relative) paths. Like so:

// Without resolve.alias 😭

import Modal from '../../../components/objects/modal/modal';

Coming from a PHP background – where you have include paths and autoloaders – I essentially want the code to know that all components can be found in src/ui/components, allowing me to freely move files around without needing to update the paths of all import statements.

Turns out Webpack allows one to do exactly just that, using resolve.alias:

const webpackConfig = {
  resolve: {
    alias: {
      Components: path.resolve(__dirname, 'src/ui/components/'),
      Containers: path.resolve(__dirname, 'src/ui/containers/')

With resolve.alias in place, imports can now be written as such, regardless of the location of the file importing it:

// With resolve.alias 😊

import Modal from 'Components/objects/modal/modal';

Aaah, much better 🙂

Webpack: resolve.alias

Elsewhere , , , Leave a comment