Strava Global Heatmap

Strava has released a Global Heatmap powered by Mapbox GL, plotting all locations where their users go run / go cycle / do water activities / do winter activities.

The raw input activity streams data comes from a Spark/S3/Parquet data warehouse. This data includes every one of the 3 trillion GPS points ever uploaded to Strava. Several algorithms clean up and filter this data.

[…]

The full global heatmap was built across several hundred machines in just a few hours, with a total compute cost of only a few hundred dollars.

I like the fact that it’s possible to filter on activity type, revealing some hotspots like Wielercentrum Eddy Merckx for cycling, and the adjacent Watersportbaan and Blaarmeersen for running in Gent.

Strava Global Heatmap →
Strava Engineering: The Global Heatmap, Now 6x Hotter →

Elsewhere , , , Leave a comment

SQIP – SVG-Based Image Placeholder

In an in-depth analysis on how Medium loads up their images, José M. Pérez explains how their “blur-up technique” works:

  1. Display a resized version of the original at the original size, with a blur filter on top to hide the artifacts.
  2. Load in the bigger one.
  3. Once the big version is loaded, replace the small image with the big one.

Now, at Medium they don’t just swap out the small image for the big one, but animate between the two. For this they render everything on a <canvas> element. The author of the post has recreated the animation using CSS filters:

See the Pen Reproducing Medium loading image effect by José Manuel Pérez (@jmperez) on CodePen.

In a follow-up post on using SVGs as placeholders he researches how SVGs can be used as placeholders.

Now I must say his self-made results aren’t that satisfying … the jump between the lo-res SVG and the original is too big. What caught my eye in said article however, is the mention of SQIP which yields some very – very – nice results:

It makes use of Primitive to generate a SVG consisting of several simple shapes that approximate the main features visible inside the image, optimizes the SVG using SVGO and adds a Gaussian Blur filter to it. This produces a SVG placeholder which weighs in at only ~800–1000 bytes, looks smooth on all screens and provides an visual cue of image contents to come.

# Generate a SVG placeholder and print an example <img> tag to stdout
sqip input.jpg

# Save the placeholder SVG to a file instead of printing the <img> to stdout
sqip -o output.svg input.jpg

# Customize the number of primitive SVG shapes (default=8) to influence bytesize or level of detail
sqip -n 4 input.jpg

There’s also a Node implementation available.

SQIP – SVG-Based Image Placeholder →

Elsewhere , , , , Leave a comment

JSON5 – JSON for Humans

JSON isn’t the friendliest to write. Keys need to be quoted, objects and arrays can’t have trailing commas, and comments aren’t allowed — even though none of these are the case with regular JavaScript today.

JSON5 is a proposed extension to JSON that allows these kinds of things. Here’s an example showcasing most of its features:

{
    foo: 'bar',
    while: true,

    this: 'is a \
multi-line string',

    // this is an inline comment
    here: 'is another', // inline comment

    /* this is a block comment
       that continues on another line */

    hex: 0xDEADbeef,
    half: .5,
    delta: +10,
    to: Infinity,   // and beyond!

    finally: 'a trailing comma',
    oh: [
        "we shouldn't forget",
        'arrays can have',
        'trailing commas too',
    ],
}

Note that the JSON5 proposal is in no way official (technically a new MIMEType is required), and – I fear – most likely won’t get that much adoption/traction …

JSON5 JS Parser →
JSON5 PHP Parser →

Elsewhere , Leave a comment

Accessing a tweet using only its ID (and without the Twitter API)

Today I learned that Twitter totally ignores the username in the “tweet detail route” on their website. This allows you to view details of a (public) tweet when knowing only its ID, without needing to access the Twitter API (which is the default geeky approach I was first going to take).

Twitter’s tweet detail route has the form of https://twitter.com/{userName}/status/{tweetId}. When passing in a tweetId with a non-matching/invalid userName, the Twitter website will automatically redirect to the URL with the correct userName

Example: To see the contents of the tweet with id 932586791953158144 just visit https://twitter.com/anyuser/status/932586791953158144 and you’ll be redirected to its actual URL: https://twitter.com/bramus/status/932586791953158144

Handy 😊

Elsewhere , Leave a comment

Two column <dl> with CSS Grid

Thanks to CSS Grid it’s really easy to make the <dt> and <dd> elements appear in two columns.

The original code was created by Lea Verou. This altered version here plays nice with multiple successive <dt> and <dd> elements.

Elsewhere , , Leave a comment

PHP Session Locking: How to Prevent Blocking Requests

Today I learned about “PHP Session Locking”:

PHP writes its session data to a file by default. When a request is made to a PHP script that starts the session (session_start()), this session file is locked. What this means is that if your web page makes numerous requests to PHP scripts, for instance, for loading content via Ajax, each request could be locking the session and preventing the other requests from completing.

The other requests will hang on session_start() until the session file is unlocked. This is especially bad if one of your Ajax requests is relatively long-running.

As a developer you can prematurely close the session by calling session_write_close() or – with PHP7 – close it automatically after starting:

session_start([
    'read_and_close' => true,
]);

PHP Session Locking: How To Prevent Sessions Blocking in PHP requests →
PHP Session Locks – How to Prevent Blocking Requests →

Elsewhere , , Leave a comment

AnimojiStudio – Make Animoji Videos with Unlimited Duration

Record Animoji videos with unlimited duration with this standalone app. This app uses the private AvatarKit framework, the same one that’s used by Apple’s iMessage app. It leverages ReplayKit’s screen recording capabilities to allow for longer recordings than the standard app.

As this app uses a private framework, it cannot be found in / published to the App Store. The source however is freely available, so you can compile it yourself 🙂

If you’re feeling adventurous there’s also a prebuilt IPA available which can be loaded onto your iPhone using Cydia Impactor. Not sure if that’ll void your warranty and/or will brick your phone or not …

AnimojiStudio – Make Animoji videos with unlimited duration →

Elsewhere , , , Leave a comment

react-native-maps-directions – Directions/Routing component for react-native-maps

One of the things I found missing in the aforementioned react-native-maps was the ability to route between to coordinates.

Combining the feedback from the related issues on GitHub (#52, #778, and #929) I’ve created a standalone component that does exactly that.

The MapViewDirections component can route between an origin and destination coordinate. As routing is handled by the Google Maps Directions API, an apikey for use with Google Maps is also required:

<MapView initialRegion={…}>
  <MapView.Marker coordinate={origin} />
  <MapView.Marker coordinate={destination} />
  <MapViewDirections
    origin={origin}
    destination={destination}
    apikey={GOOGLE_MAPS_APIKEY}
  />
</MapView>

Once the directions in between both coordinates has been fetched, a MapView.Polyline between the two will be drawn. Therefore all MapView.Polyline props – except for coordinates – are also accepted.

Installation per npm/yarn:

yarn add react-native-maps-directions

react-native-maps-directions (GitHub) →

Elsewhere , , , , Leave a comment

What’s new, Atlas?

It’s great – and also terrifying at the same time – to see how the Atlas evolves every year (see 2016, 2013, 2011)

Elsewhere , , Leave a comment

Expanding Grid Item Animation

Nice implementation of a master-detail view, inspired upon the Surf Project Dribble Shot by Filip Slováček (pictured above). You can see this kind of animations – where elements are reused and moved from one viewstate to the other – in quite a few mobile apps nowadays (take the App Store App on iOS11 for example).

Do note that the animation itself is done using anime.js. By the looks of it, CSS Grid is only used to position the items in the list.

Expanding Grid Item Animation →

Elsewhere , Leave a comment