Basic Usage
Let's build a simple 3D scene using ThreeJS loaded through HCS-3 recursion.
Step 1: Create Basic HTML Structure
Note: Before proceeding, you'll need to include the latest HCS-3 Recursion SDK.
- Visit the HCS Recursion SDK repository
- Copy the contents of
hcs-recursion-sdk.js
- Add it to your HTML file before any other HCS-3 related scripts using a script tag:
<!DOCTYPE html>
<html>
<head>
<title>ThreeJS with HCS-3</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
<!-- Configure HCS-3 -->
<script
data-hcs-config
data-hcs-cdn-url="https://kiloscribe.com/api/inscription-cdn/"
data-hcs-network="mainnet"
data-hcs-debug="true"
data-hcs-retry-attempts="5"
data-hcs-retry-backoff="500"
data-hcs-show-loading-indicator="true"
data-hcs-loading-callback-name="setLoadingIndicator"
></script>
<!-- Load Dependencies -->
<script
data-src="hcs://1/0.0.6614307"
data-script-id="threejs"
data-load-order="1"
></script>
<script
data-src="hcs://1/0.0.6627067"
data-script-id="animejs"
data-load-order="2"
></script>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="loading"></div>
<!-- Paste the copied SDK code here -->
<script id="hcs-sdk">
// Paste the copied SDK code here
</script>
<script>
// Loading indicator
window.setLoadingIndicator = function(id, status) {
const loading = document.getElementById('loading');
loading.innerHTML = ``;
if (status === 'loaded' && id === 'animejs') {
setTimeout(() => {
loading.style.display = 'none';
}, 1000);
}
}
// Main application
window.HCSReady = async function() {
};
</script>
</body>
</html>
Step 2: Add Required Scripts
Add ThreeJS and other dependencies using HCS-3 recursion. Note the data-load-order
to ensure proper loading sequence:
<!-- Load ThreeJS from HCS -->
<script
data-src="hcs://1/0.0.6614307"
data-script-id="threejs"
data-load-order="1"
></script>
<!-- Optional: Load AnimeJS for animations -->
<script
data-src="hcs://1/0.0.6627067"
data-script-id="animejs"
data-load-order="2"
></script>
Step 3: Add Loading Indicator
<script>
window.setLoadingIndicator = function(id, status) {
const loading = document.getElementById('loading');
loading.innerHTML = ``;
}
</script>
Step 4: Initialize ThreeJS Scene
Add the main application code that will run after all resources are loaded:
<script>
window.HCSReady = async function() {
// Setup ThreeJS
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('canvas')
});
renderer.setSize(window.innerWidth, window.innerHeight);
// Create a cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
// Animation loop
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
// Handle window resizing
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
};
</script>
Step 5: Add Textures (Optional)
To load and apply textures from HCS:
// Inside HCSReady function
const textureUrl = await window.HCS.preloadImage('0.0.4840659'); // Your texture topic ID
const texture = new THREE.TextureLoader().load(textureUrl);
const material = new THREE.MeshBasicMaterial({ map: texture });
Putting It All Together
Now, let's put it all together:
<!DOCTYPE html>
<html>
<head>
<title>ThreeJS with HCS-3</title>
<style>
body { margin: 0; }
canvas { display: block; }
#loading {
position: fixed;
top: 20px;
left: 20px;
color: white;
font-family: Arial, sans-serif;
background: rgba(0,0,0,0.7);
padding: 10px;
border-radius: 5px;
}
</style>
<!-- Configure HCS-3 -->
<script
data-hcs-config
data-hcs-cdn-url="https://kiloscribe.com/api/inscription-cdn/"
data-hcs-network="mainnet"
data-hcs-debug="true"
data-hcs-retry-attempts="5"
data-hcs-retry-backoff="500"
data-hcs-show-loading-indicator="true"
data-hcs-loading-callback-name="setLoadingIndicator"
></script>
<!-- Load Dependencies -->
<script
data-src="hcs://1/0.0.6614307"
data-script-id="threejs"
data-load-order="1"
></script>
<script
data-src="hcs://1/0.0.6627067"
data-script-id="animejs"
data-load-order="2"
></script>
<!-- Paste the copied SDK code here -->
<script>
// Paste the copied SDK code here
</script>
</head>
<body>
<canvas id="canvas"></canvas>
<div id="loading"></div>
<script>
// Loading indicator
window.setLoadingIndicator = function(id, status) {
const loading = document.getElementById('loading');
loading.innerHTML = ``;
if (status === 'loaded' && id === 'animejs') {
setTimeout(() => {
loading.style.display = 'none';
}, 1000);
}
}
// Main application
window.HCSReady = async function() {
// Setup scene
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
const renderer = new THREE.WebGLRenderer({
canvas: document.getElementById('canvas'),
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0x000033);
// Load texture from HCS
const textureUrl = await window.HCS.preloadImage('0.0.4840659');
const texture = new THREE.TextureLoader().load(textureUrl);
// Create textured cube
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ map: texture });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
// Add animation with AnimeJS
anime({
targets: cube.rotation,
y: Math.PI * 2,
duration: 4000,
easing: 'linear',
loop: true
});
// Animation loop
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
renderer.render(scene, camera);
}
animate();
// Handle window resizing
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
};
</script>
</body>
</html>
Key Points
- The HCS-3 Recursion SDK is automatically injected when utilizing the KiloScribe CDN. This ensures you always have the latest version.
- Resources are loaded in order specified by
data-load-order
- All initialization code goes inside the
HCSReady
callback - The Recursion SDK ships with helper functions for common tasks like loading textures and GLBs.
- Topic IDs (like
0.0.6614307
) are real HCS-1 inscribed resources