Polluted Water Popsicles

What if one were to create water popsicles from sewage water? Art students Hung I-chen, Guo Yi-hui, and Cheng Yu-ti from the National Taiwan University of the Arts did just so:

The group collected polluted water from 100 locations in Taiwan, first freezing the collected sewage samples and then preserving their creations in polyester resin.

The series of popsicles also comes with a packaging design:

Polluted Water Popsicles on Facebook →

(via)

Elsewhere , , Leave a comment

Gallery Invasion

A dynamic projection mapping by Antoon Verbeeck and Filip Sterckx located in Leuven, Belgium:

We used a Panasonic PT-VZ570U projector, which had the MH12-VZ75L Mirror Head from Dynamic Projection Institute mounted in front of the projector’s lens. This is basically a mirror that is motorized and programmable and that can rotate 270 degrees, as well as up or down. I used the MDC-X media server from Dynamic Projection Institute to control the Mirror Head and programmed it so it followed the same movement as I had prepared in my animation.

Gallery Invasion →

Elsewhere , Leave a comment

git-blame-someone-else

Always dissatisfying when running git blame, and turning out that it was you yourself whodunit. This is where git-blame-someone-else comes into place:

$ git blame-someone-else <author> <commit>

* evil laughter *

git-blame-someone-else

Elsewhere , Leave a comment

How the CSS minmax() Function Works

One incredibly useful new feature introduced with the CSS Grid Layout Specification is the minmax() function. This function opens the door to us being able to write much more powerful and succinct CSS by allowing us to set, as a value for a grid track, a function including both a minimum and maximum value.

Using minmax() – combined with repeat() – it’s possible to create responsive grid designs without the use of any media queries.

.grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}

How the CSS minmax() Function Works →

Elsewhere , , , Leave a comment

runes – Unicode-aware JS string splitting with full Emoji support

At Small Town Heroes I’m currently working on a newsreader app built using React Native. On Android (even 7.1.1) we noticed this weird issue where some emojis would render incorrectly when we were applying styling on it using index-based ranges: the range seemed to be off by one, splitting the emoji into its separate bytes. What made this issue even more weird is that this behaviour stopped when we connected the app to a debugging session.

Result of applying a specific style on this 41 symbol counting sentence
Figure: Result of applying a specific style on this 41 symbol counting sentence.

As you might be aware emoji can be multibyte strings and thus compromise two (or even more) bytes. When asking the length of a string, JavaScript will count the number of bytes, not the number of symbols. Technically correct, but no so good for us:

// I count 7, what about you my dear JavaScript?
>> 'Emoji 🤖'.length
8

When asking the length of a string, JavaScript will count the number of bytes, not the number of symbols.

To get the correct symbol count, you can use Array.from() or the spread operator (*):

>> Array.from('Emoji 🤖');
["E", "m", "o", "j", "i", " ", "🤖"]

>> Array.from('Emoji 🤖').length
7

>> [...'Emoji 🤖'].length
7

(*) Do note that this technique is not 100% bulletproof though. It has “problems” with skin tone modifiers and other emoji combinations – which in itself yields some fun results – but let’s ignore that for now.

Knowing how to get the correct count, it’s possible to extract proper substrings from that sentence, to apply your styling on (*):

// Wrong way to do it (not multibyte-aware)
>> 'Emoji 🤖'.substr(0,7);
"Emoji �"

// Correct way to do it (multibyte-aware)
>> [...'Emoji 🤖'].slice(0,7).join('');
"Emoji 🤖"

(*) Why not just use String#length and String#split all throughout our code (thus bypassing the whole thing) you might wonder? Well, the editor used to input the article *is* multibyte aware, so it would return 7 as the length of that sentence 😉

Now, even though we were using Array.from() to get the correct substrings, we ran into issues on Android whilst doing so: it would aways yield "Emoji �", no matter which technique we used. Long story short: we found out that the runtime on the Android phone – somehow – was using a non-multibyte aware Array.from(), explaining the wrong result.

// Android 7.1.1
>> Array.from('Emoji 🤖');
["E", "m", "o", "j", "i", " ",  "�", "�"] // <-- Wait, wut?

With this, we also found out that the JavaScript runtime used during a debugging session is different from the one used in standalone mode. For the debug session, the one contained in node (e.g. V8) would be used.

The solution to bypassing this mysterious problem was to use runes, a library that's Unicode-aware. Above that it also plays nice with skin tone modifiers and other emoji combinations, making it superior to the Array.from() technique.

const runes = require('runes');
 
// Standard String.split 
'♥️'.split('') => ['♥', '️']
'Emoji 🤖'.split('') => ['E', 'm', 'o', 'j', 'i', ' ', '�', '�']
'👩‍👩‍👧‍👦'.split('') => ['�', '�', '‍', '�', '�', '‍', '�', '�', '‍', '�', '�']
 
// ES6 string iterator 
[...'♥️'] => [ '♥', '️' ]
[...'Emoji 🤖'] => [ 'E', 'm', 'o', 'j', 'i', ' ', '🤖' ]
[...'👩‍👩‍👧‍👦'] => [ '👩', '', '👩', '', '👧', '', '👦' ]
 
// Runes 
runes('♥️') => ['♥️']
runes('Emoji 🤖') => ['E', 'm', 'o', 'j', 'i', ' ', '🤖']
runes('👩‍👩‍👧‍👦') => ['👩‍👩‍👧‍👦']
const runes = require('runes')
 
// String.substring 
'👨‍👨‍👧‍👧a'.substring(1) => '�‍👨‍👧‍👧a'
 
// Runes 
runes.substring('👨‍👨‍👧‍👧a', 1) => 'a'

runes – Unicode-aware JS string splitting with full Emoji support →

Related: The presentation Javascript ❤️ Unicode and accompnaying blogpost JavaScript has a Unicode Problem by Mathias Bynens is pure gold when it comes to JavaScript and Unicode 😉

Elsewhere , , , Leave a comment

The problem with maps // Playing with Projections

One of the core ideas covered in my talk named “Geoshizzle” on mapping is that the Mercator projection is way overdue. It’s main feature of preserving angle measurements is no longer feasible in this time and age (it was back when you were sailing a boat to get somewhere), and it’s distortion of areas has affected how we perceive the size of the world (e.g. Greenland and Antarctica really aren’t that big).

Michael Davis has created a really good article on this, filled with visualisations using Tissot’s indicatrices demonstrating the effects of each projection.

Pictured above you can see Tissot’s indicatrices drawn onto a globe, an equirectangular projecten, and the Mercator projection

A Frenchman named Tissot came up with something fancy. The general idea was to characterize local distortions; To show you what a small circle would look like when moved from the globe to the map.

The coolest part of the article/site is that the visualisations are interactive: you can give each globe a spin and simultaneously see how (the distortion of) the linked projection is affected by it.

The problem with maps →

👉 Want to see how the Mercator Projection affects the shape of a country when drawn on a map? Play the interactive Mercator Puzzle to find out.

(via Lensco)

Elsewhere , , Leave a comment

Introduction to commonly used ES2015 (ES6) features

Good overview to get started with ES2015 by Zell Liew in case you’re still not using it (which you should; just do it!). As he puts it:

JavaScript has progressed a ton in the recent years. If you’re learning JavaScript in 2017 and you haven’t touched ES6 ES2015, you’re missing out on an easier way to read and write JavaScript.

Introduction to commonly used ES6 features →

Elsewhere , , Leave a comment

Debugging Node.js using the Chrome DevTools

With Chrome 57+, the Node.js debugging feature is enabled by default. To start debugging, run your Node.js application [using Node 6.4+] with the --inspect flag.

Like so:

$ node --inspect <your_file>.js

Open the outputted URL or visit chrome://inspect/ to open dedicated DevTools for Node to start debugging 🙂

Debugging Node.js with Google Chrome →

Elsewhere , , , Leave a comment

Google Maps’s Quiet Transformation

Justin O’Beirne kept an eye on how a specific area evolved on Google Maps and on Apple Maps over time:

Patricia’s Green is the centerpiece of a vibrant and trendy neighborhood in central San Francisco, just blocks away from City Hall.

I wrote a script that takes monthly screenshots of Google and Apple Maps. Thirteen months later, we now have a year’s worth of images

On Apple Maps, the area looks much as it did a year ago. But it’s quite a different story on Google Maps: as the months went on, Google continued adding detail.

As a mapping aficionado, I’m intrigued by this kind of stuff 🙂

A year of Google Maps and Apple Maps →

Elsewhere , , , Leave a comment

npm v5.0.0

This release marks months of hard work for the young, scrappy, and hungry CLI team, and includes some changes we’ve been hoping to do for literally years. npm@5 takes npm a pretty big step forward, significantly improving its performance in almost all common situations, fixing a bunch of old errors due to the architecture, and just generally making it more robust and fault-tolerant.

Great to see that npm will now – finally! – auto --save by default and generate a package-lock.json file after installing a dependency. They’re two features I felt that were absolutely missing in npm, as the lack of the introduced quite a lot of issues (e.g. colleagues forgetting to save a dependency breaking my code after a pull, deploys going wrong because the server would receive new versions of dependencies, etc.)

And oh, it’s also way faster:

I’d like to think that the “competition” introduced by yarn – which got me very excited – accelerated the release of npm@5 🙂

The npm blog – v5.0.0 →

Elsewhere , , Leave a comment