Frontend Development 9 min read

Creating a Flaming Elden Ring Logo with React and Three.js

This tutorial demonstrates how to build a fire‑animated Elden Ring logo using React, Three.js, and the Fire.js extension, covering background setup, resource import, scene initialization, fire effect configuration, responsive scaling, camera animation, and rendering loop with complete code examples.

Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Rare Earth Juejin Tech Community
Creating a Flaming Elden Ring Logo with React and Three.js

The article explains how to recreate the Elden Ring logo with a realistic fire effect by leveraging the React + Three.js stack and the Fire.js extension. It starts with a background overview, noting that the logo consists of arcs and lines and that the fire effect is achieved primarily through Fire.js.

Effect preview shows the final animated logo, which loads with a near‑to‑far transition and then animates with vertical easing. Online demos are provided via two URLs.

Fire.js basics are introduced, listing configurable properties such as color1 , color2 , color3 , burnRate , viscosity , windX , windY , etc., and common methods like addSource , clearSources , and setSourceMap .

Resource import shows how to import the required modules:

import React from 'react';
import * as THREE from './libs/three.module.js';
import { Fire } from './libs/Fire.js';
import { TWEEN } from "three/examples/jsm/libs/tween.module.min.js";
import ringTexture from './images/ring.png';

The page DOM contains a single WebGL container with id #container :

<div className='ring_page' id="container"></div>

Scene initialization creates the renderer, camera, and lights:

const container = document.getElementById('container');
const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild(renderer.domElement);
renderer.setClearAlpha(0);
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 0, 100);
camera.lookAt(new THREE.Vector3(0, 0, 0));
const ambientLight = new THREE.AmbientLight(0xffffff, 1);
scene.add(ambientLight);

To make the background transparent, the renderer is created with alpha: true and renderer.setClearAlpha(0) is called, allowing CSS to set a custom background.

Adding the logo uses a PlaneBufferGeometry as the fire carrier and configures the Fire.js instance with many parameters:

const ring = new Fire(new THREE.PlaneBufferGeometry(20, 25), {
  textureWidth: 800,
  textureHeight: 1000,
  debug: false,
});
ring.setSourceMap(new THREE.TextureLoader().load(ringTexture));
ring.color1 = new THREE.Color(0xffffff);
ring.color2 = new THREE.Color(0xf59e00);
ring.color3 = new THREE.Color(0x08120a);
ring.colorBias = .6;
ring.burnRate = 10;
ring.diffuse = 1;
ring.viscosity = .5;
ring.expansion = -1.6;
ring.swirl = 10;
ring.drag = 0.4;
ring.airSpeed = 18;
ring.windX = 0.1;
ring.windY = 0.2;
ring.speed = 100;
ring.massConservation = false;
ring.position.y = 4;
ring.position.z = -6;
scene.add(ring);

Responsive scaling is handled by listening to the resize event and updating the camera aspect and renderer size:

window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
}, false);

Camera animation uses OrbitControls and a custom Animations.animateCamera helper to move the camera from a distant position to the origin over 2400 ms:

const controls = new OrbitControls(camera, renderer.domElement);
Animations.animateCamera(camera, controls, { x: 0, y: 0, z: 22 }, { x: 0, y: 0, z: 0 }, 2400, () => {
  controls.enabled = false;
});

The render loop updates the scene, stats, and TWEEN animations, and animates the logo’s vertical position with a sinusoidal function:

let step = 0;
const animate = () => {
  requestAnimationFrame(animate);
  renderer.render(scene, camera);
  stats && stats.update();
  TWEEN && TWEEN.update();
  step += .03;
  ring && (ring.position.y = Math.abs(2.2 + Math.sin(step)));
};

In summary, the tutorial covers the basic usage of Fire.js, setting renderer transparency, importing resources, initializing a Three.js scene, configuring fire parameters, handling responsive layout, and adding simple camera and object animations. The full source code is available on GitHub.

frontendreactThree.jsWebGL3DFire.js
Rare Earth Juejin Tech Community
Written by

Rare Earth Juejin Tech Community

Juejin, a tech community that helps developers grow.

0 followers
Reader feedback

How this landed with the community

login 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.