How NetEase’s Color Test H5 Was Built: SPA Architecture, Animations, and Result Logic

This article details the technical implementation of NetEase Cloud Music’s color‑test H5, covering its single‑page React architecture, preloading optimizations, canvas and WebGL animation techniques, and the deterministic front‑end algorithm that calculates single‑ or dual‑color results from user choices.

NetEase Cloud Music Tech Team
NetEase Cloud Music Tech Team
NetEase Cloud Music Tech Team
How NetEase’s Color Test H5 Was Built: SPA Architecture, Animations, and Result Logic

Overall Structure

The activity is a single‑page application built with React and react‑router, containing 13 pages (home, question pages, result page, etc.). Page transitions use react-transition-group for fade effects, while canvas provides a curtain‑like animation between questions.

Because the navigation path is fixed, the router preloads the next page to achieve instant navigation and to preload video DOM nodes for immediate playback on click events.

Optimizes user experience by removing loading delays.

Ensures video elements are ready before the click event triggers the video tag.

Animation Effects

Two main approaches are used:

Pre‑rendered videos for complex, non‑interactive backgrounds, compressed to keep resource size manageable.

Real‑time rendering with canvas, WebGL, or physics engines for interactive effects.

Page‑Flip Effect

Each question transition features a flexible curtain animation implemented with canvas. Five points (P1‑P5) define a mask; P4 and P5 stay fixed while P1‑P3 move left, updating a Bezier curve via the bezierCurveTo API to create the pulling effect.

Cloud Effect

In question 5, a cloud animation is rendered with three.js and WebGL. ShaderMaterial loads vertex and fragment shaders, applies a texture, and moves the camera to simulate flying through clouds. Cloud positions are randomized per user.

Drop Effect

Question 7 introduces a physics‑based drop animation using Matter.js , simulating free fall and collisions. The final positions are random, giving each user a unique experience.

Result Calculation

Each answer option maps to one or more colors (e.g., Question 1: A → Gold, Green; B → Purple, Silver, Orange; C → Pink, Blue). The app records selections, aggregates color counts, and determines whether the final result is single‑color or dual‑color based on the answer to Question 8 (“Sad” → single, “Romantic” → dual).

For a single‑color result, the color with the highest count is chosen. For a dual‑color result, the predefined nine color‑pair combinations are evaluated, and the pair with the highest combined count wins. Ties are resolved using a priority list supplied by the designers.

Example selection path: [B, C, A, C, C, C, C, A] Aggregated counts:

{'紫':3, '银':6, '橙':3, '金':3, '绿':2, '粉':2, '蓝':3}

Because Question 8 chose “Romantic”, a dual‑color result is required. The pair 金+橙 has the highest sum, so the final result is 金+橙.

Total possible answer paths are 3^7 × 2 = 4374, producing 7 single‑color outcomes and 9 dual‑color outcomes (16 in total). All calculations run entirely on the front end; no back‑end services are involved.

The calculation logic follows the personality‑color methodology described by Tom Maddron in “The Most Accurate Personality Color Measurement Tool”.

Implementation Note

The configuration file uses Chinese keys directly, taking advantage of JavaScript’s Unicode support and CSS Modules which hash class names to safe identifiers. Example export:

export default {
  蓝: {
    attracted: ['橙粉', '粉金'],
    keepAway: ['金', '银'],
    // …
  }
}

Unicode variable names and even Chinese class names are supported in modern browsers, and CSS Modules convert them to hashed strings, eliminating compatibility concerns.

Conclusion

The article shares the technical details of the color‑test H5, including SPA routing, animation techniques, and the deterministic front‑end algorithm that maps user choices to single‑ or dual‑color results.

References

react‑transition‑group: https://reactcommunity.org/react-transition-group/

CanvasRenderingContext2D.bezierCurveTo: https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/bezierCurveTo

three.js: https://threejs.org/

Matter.js: https://brm.io/matter-js/

Unicode variable names: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Grammar_and_types#%E5%8F%98%E9%87%8F

Unicode in CSS class names: https://stackoverflow.com/questions/19123336/can-i-safely-use-unicode-characters-e-g-accents-in-css-class-names-or-ids

NetEase Cloud Music Front‑End Team: https://github.com/x-orpheus

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

animationReactCanvasSPAThree.jsMatter.jsResult Calculation
NetEase Cloud Music Tech Team
Written by

NetEase Cloud Music Tech Team

Official account of NetEase Cloud Music Tech Team

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.