Holiday Map

four32c

Holiday Map

This holiday season, we wanted to share some of our favorite West Chelsea places with our friends and clients, so we put together a handy-dandy interactive guide as well as created a limited-edition FOUR32C holiday shopping tote to hold your holiday haul!

– FOUR32C
Background

Holiday Cheer from FOUR32C

The folks from FOUR32C reached out to me to help create an experience that could be shared to friends & clients.

logo-light
// this.blocks is an array of THREE.CSS3DObject's
const flipBlocks = (blocks = []) => {
    blocks.forEach((block, index) => {
        const { rotation } = block;
        const isX = Math.round(Math.random()) === 1;
        const tweenObj = {
            x: isX ? MathPI * 2 : rotation.x,
            y: isX ? rotation.y : MathPI * 2,
            ease: Back.easeOut,
            delay: index * 0.015
        }
        TweenMax.to(rotation, 1.4, tweenObj);
    });
}
Like butter

Smooooooth Animations

By using the Three.js CSS3DRenderer, performance for the “blocks” were easily at 60 fps.

K.I.S.S.

Page.js

Making routing super straightforward in ~1200 bytes by the folks from VisionMedia.

const handleViewChangeStart = (context, next) => {
    const {
        name
    } = currentView;
    if (currentView) {
        if (context.path.search(/\/question\//g) === -1
            || context.path.search(/\/map\//g) === -1) {
                currentView.playOut();
            }
        if (currentView.name !== undefined) {
            document.body.classList.remove(currentView.name);
        };
    }
    next();
}
const handleViewChangeComplete = () => {
    const {
        name
    } = currentView;
    if (name !== undefined) {
        document.body.classList.add(name);
    };
}
const quiz = (context, next) => {
    // create & || provide view with any updated data
    const { id } = context.params;
}
const map = (context, next) => {
    // create & || provide view with any updated data
    const { id } = context.params;
}
const intro = (context, next) => {
    // create & || provide view with any updated data
}
page('/quiz/question/:id', handleViewChangeStart, quiz, handleViewChangeComplete);
page('/map', handleViewChangeStart, map, handleViewChangeComplete);
page('/map/:id', handleViewChangeStart, map, handleViewChangeComplete);
page('*', handleViewChangeStart, intro, handleViewChangeComplete);

The Result

Holiday Map

Launch Project
The Tech

Loading up the toolbox

I am a huge fan of GSAP all the way back from the days of Flash. With the exception of three.js the rest of the technologies I used were standard: HTML5, SCSS, Webpack, and JSON for data-modeling.

Experience MLS like a die-hard fan

ESPN

Experience MLS like a die-hard fan

Raucous fans make the MLS matchday atmosphere among the best in American pro sports.

Background

ESPN

This featured article was created to demonstrate the energized fans that fill up stadiums all over the county. ESPN chose to pick 5 teams and highlight their traditions that make going to a game a unique experience.

Content

The Chosen 5 Teams

ESPN went on the road to gather editorial from the Atlanta United FC, Minnesota United FC, Portland Timbers, Seattle Sounders FC, and the Sporting Kansas City. They came back with 360º videos, HD video, and imagery that captures the fans excitement

Capturing the excitement

Using 360º Video

My initial thought to display 360º video, was to create a custom player with three.js. From my discovery I found that videojs has a plugin for vr. After a prototype, I decided to go with the plugin which ultimately saved a few hours.

The Result

Experience MLS like a die-hard fan

Launch Project
The Tech

Loading up the toolbox

I am a huge fan of GSAP all the way back from the days of Flash. With the exception of GSAP and Videojs-vr the rest of the technologies I used were standard: HTML5, SCSS, Webpack, and JSON for data-modeling.

Considerations and Recommendations

As project manager, I chose tools that help the team organize tasks and assets. For ESPN, I recommended Trello and created a board that borrows features from agile planning.  This provides visibility to the client for the work that is outstanding, in development and completed.

Google Sheets

JSON

Nunjucks

HTML5

FEED ME!

Content Management

ESPN has their own CMS to handle article content, however developers do not have access to it. In order to get the copy deck into HTML markup, the content team at ESPN edits a google sheet, then I export it to JSON, and use that to compile the markup (via Nunjucks). When updates are required, the team makes the changes in google sheets, and I export a fresh JSON file, compile it and then they can copy & paste the markup into their CMS.

Oncology Pipeline Explorer

Amgen

Oncology Pipeline Explorer

An interactive kiosk for Amgen that demonstrates the relationships between different cells and their research on Oncology.

Background

The Brief from Broth

The Broth agency reached out to me from a recommendation through a friend. They had a few bids out for the job and asked me to send examples and an estimate. Within a week I had secured the job. Over a few meetings face to face I had my marching orders and was ready to get prototyping.

What’s on the hook

A relational map of circles.

The challenge was not only taking a rough abstract idea sold to the client into fruition, but to also complete this task in a very short timeline. The brief was provided to me the Monday after Thanksgiving 2018 and needed to be sent off for MAC review January 10th, 2019

A lot of work, in a short time, with little to go with. Within a holiday month.

List of conferences:

ASCO GU 2019 2/14 – 2/16 | Las Vegas
AACR 2019 3/31 – 4/3 | Atlanta
ASCO 2019 5/31 – 6/4 | Chicago

THE PROCESS

The work in progress…

I quickly had gathered up my tools and got to work. I was very attracted to a 3D immersive map that the user could explore. Due to the abstract brief, I wanted to be sure the client would be comfortable in my idea of 3D.

Prototype

Within a couple of days I had placed this rough and dirty prototype in the hands of the client and let them play. I had to communicate where this could materialize from, explaining that the ‘orbs’ and ‘satellites’ would have a glassy material, the navigation may be different, number of orbs in view, orbs would have labels- as some options to research.

View Prototype

Testing materials & performance

WebGL is a GPU hog and will make your laptop sound like it’s about to take off. So I had to get the best bang for your buck as far as performance went. I researched reflections on all the orbs, but realized it was going to be too taxing on the GPU.

View material test 

Review 1

Ready for review – whew… The first conference was going to launch with three categories, as the client could not provide all the brochures and assets for the ‘Targets’ category. Navigation in, labels on, tons of data feed in. There were some bugs and kinks that I still needed to work out.

View Review 

Release Candidate

This was the release candidate that was sent out the first conference in Las Vegas. It was received very well, the client was thrilled and proud to show off their kiosk. Their feedback was positive, and was looking forward to the next version with the added Targets.

View Release

THE APP

Amgen’s Interactive Oncology Pipeline

The Tech

Loading up the toolbox

I chose tools that I am very comfortable with as I was in a short deadline. My go to’s consist of react, three.js, webpack, json for modeling, etc.

Considerations and Reccommendations

Due to the demand on the GPU for WebGL, I made sure that the hardware would be more than enough to handle the application. Broth supplied me with options from a third party vendor, and I provided my recommendation.

Discovery & Pride

There was so much I was proud about, especially now looking back with what I was given and what I was able to create. One of my favorite pieces of the code was how I was able to interpolate over time the labels to look at the camera.

/**
 * Helper function to get quaternion from src
 * looking at target 
 */
const getLookAtQuaternion = (srcObj, targetObj) => {
    var q1 = new THREE.Quaternion();
    var m1 = new THREE.Matrix4();
    var target = new THREE.Vector3();
    var position = new THREE.Vector3();
    var quaternion = srcObj.quaternion.clone();
    const { x, y, z } = targetObj;
    target.set(x, y, z);
    var parent = srcObj.parent;
    srcObj.updateWorldMatrix(true, false);
    position.setFromMatrixPosition(srcObj.matrixWorld);
    m1.lookAt(target, position, srcObj.up);
    quaternion.setFromRotationMatrix(m1);
    if (parent) {
        m1.extractRotation(parent.matrixWorld);
        q1.setFromRotationMatrix(m1);
        quaternion.premultiply(q1.inverse());
    }
    return quaternion
}

/**
 * On ever render tick, have the label and cta move its
 * quaternion towards the camera
 */
update = slerpSpeedOverride => {
    const {
        type
    } = this.data;
    const q = getLookAtQuaternion(this.textContainer, ThreeView.camera.position)
    this.textContainer.quaternion.slerp(q, slerpSpeedOverride || this.slerpSpeed);
    if (this.plane) {
        this.plane.quaternion.slerp(q, 1);
    }   
}

Google Sheets

JSON

Nunjucks

HTML5

FEED ME!

Content Management

When choosing a CMS for the project, I consider who will be the publisher. Tools like Contentful or sites like WordPress often need a little hand holding for those that are not too tech-savy. Most of my clients are comfortable in Excel. It’s my rough and dirty way to get the client to add the data, for me to extrapolate it and then export to JSON.

Conclusion

Strong relationships were developed with both Broth and Amgen. Resulting in future work with both Amgen and Broth for the remainder of 2019.

RESULTS
Orbs

81

Number of Paths

Infinite

Successful Conferences

3

Avg. Session Duration

00:02:44

Total Sessions

314

Orbs Clicked

2,299