# Integrated with tracking.js

**URL:** https://forum.8thwall.com/t/integrated-with-tracking-js/465
**Category:** Technical Support
**Created:** [February 26, 2024, 3:59pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465 "2024-02-26T15:59:33Z")
**Posts on this page:** 12
**Page:** 1

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 26, 2024, 3:59pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/1 "2024-02-26T15:59:33Z")

</div>

Hi,  
I want to integrate color detection from this sample project. 👇

> **[Tracking Color Blobs in Webcam Feed Using Tracking.js - TangibleJS](https://tangiblejs.com/posts/tracking-color-blobs-in-webcam-feed-using-tracking-js)**
>
> This article will show you how you can pick a color from a live webcam feed and track its movement in real-time using the tracking.js library.

Could you tell me the proper way to start with integrating into the 8th wall? Is that possible to integrate?  
I was trying to upload external JS files and call them, but I got a lot of errors.  
Thank you!

---

<div class="post-metadata">

### Author: ![Evan](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.8thwall.com/evan/32/431_2.png) [@Evan](https://forum.8thwall.com/u/Evan)
#### Post date: [February 26, 2024, 9:14pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/2 "2024-02-26T21:14:09Z")

</div>

Hi Lily! Are you using A-Frame or three.js?

If you’re using the cloud editor, you can load external libraries in `head.html` via script tags:

```auto
<script src="https://cdn.jsdelivr.net/gh/eduardolundgren/tracking.js@latest/build/tracking-min.js"></script>

```

This will load the library to the `window` object, so you can access the library at `window.tracking`.

I haven’t worked with this specific library before, but it looks like to get started you need a reference to the video DOM element. To do that in 8th Wall, you can create a custom camera pipeline module and obtain a reference to the video DOM element in the `onCameraStatusChange` lifecycle method:

```auto
const customPipelineModule = {
  name: 'custom',
  onCameraStatusChange: (event) => {
    if (event.status === 'hasVideo') {
      console.log(window.tracking)
      console.log(event.video)
    }
  },
}

```

That being said, it looks like this library was last updated in 2016 so I’m not sure it will work out-of-the-box.

---

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 27, 2024, 10:36pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/4 "2024-02-27T22:36:58Z")

</div>

hi Evan,  
Thank you for your reply.  
I am using A-Frame.  
May I know where I should put the customPipelineModule?

Or do you have other possible resources to do this color detection interaction?

Thank you again!

---

<div class="post-metadata">

### Author: ![Evan](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.8thwall.com/evan/32/431_2.png) [@Evan](https://forum.8thwall.com/u/Evan)
#### Post date: [February 27, 2024, 10:56pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/5 "2024-02-27T22:56:56Z")

</div>

Since you’re using A-Frame, you should add the custom camera pipeline module in an A-Frame component:

```auto
const myComponent = {
  init() {
    const onxrloaded = () => {
      XR8.addCameraPipelineModule({
        name: 'custom',
        onCameraStatusChange: (event) => {
          if (event.status === 'hasVideo') {
            console.log(window.tracking)
            console.log(event.video)
          }
        },
      })
    }
    window.XR8 ? onxrloaded() : window.addEventListener('xrloaded', onxrloaded)
  },
}

```

If this particular library doesn’t work, you might consider integrating a computer vision library to handle color detection: [Camera Pipeline: QR Code | 8th Wall | 8th Wall](https://www.8thwall.com/8thwall/camera-qrcode)

---

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 28, 2024, 7:13pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/7 "2024-02-28T19:13:03Z")

</div>

Hi Evan,

Thank you so much for your response again.  
I already loaded external library that you provided. (tracking-min.js)

But I still got the error below:

ERROR in ./head.html  
Module build failed (from /var/task/node\_modules/extract-loader/lib/extractLoader.js):  
/tmp/src/readymake.colordetected/tracking-min.js:287  
}(window));  
^

ReferenceError: window is not defined

---

<div class="post-metadata">

### Author: ![Evan](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.8thwall.com/evan/32/431_2.png) [@Evan](https://forum.8thwall.com/u/Evan)
#### Post date: [February 28, 2024, 8:10pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/8 "2024-02-28T20:10:19Z")

</div>

This looks like a build error, the code is not able to compile perhaps because code has been placed in the wrong place. Can you please share your `head.html` and `app.js`?

---

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 28, 2024, 10:12pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/9 "2024-02-28T22:12:56Z")

</div>

Hi here is my `head.html`

```auto
<meta name="8thwall:renderer" content="aframe:1.3.0">

<meta name="8thwall:package" content="@8thwall.xrextras">

<meta name="8thwall:package" content="@8thwall.landing-page">

<script src="https://cdn.jsdelivr.net/gh/eduardolundgren/tracking.js@latest/build/tracking-min.js"></script>

<script src="script.js"></script>

```

And `app.js`

```auto
import './index.css'

import {myComponent} from './camerapipeline'

AFRAME.registerComponent('camerapipeline', myComponent)

```

And I got this error

```auto
ERROR in ./head.html
Module build failed (from /var/task/node_modules/extract-loader/lib/extractLoader.js):
/tmp/src/readymake.colortest2/script.js:2
window.addEventListener("load", function(e) {
^

ReferenceError: window is not defined

```

Sorry, I’m beginner with a-frame, so I may import the script.js file in the wrong way.  
Thank you again.

---

<div class="post-metadata">

### Author: ![Evan](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.8thwall.com/evan/32/431_2.png) [@Evan](https://forum.8thwall.com/u/Evan)
#### Post date: [February 28, 2024, 10:34pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/10 "2024-02-28T22:34:49Z")

</div>

can you also share `script.js` and `camerapipeline.js`?

---

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 28, 2024, 10:51pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/11 "2024-02-28T22:51:52Z")

</div>

sure! I just use the js file from that color detection website.

`script.js`

> window.addEventListener(“load”, function(e) {
> 
> console.log(“Page loaded!”);
> 
> // Store the color we will be tracking (selectable by clicking on the webcam feed)  
> var color = {r: 255, g: 0, b: 0};
> 
> // Grab reference to the tags we will be using  
> var slider = document.getElementById(“tolerance”);  
> var canvas = document.getElementById(‘canvas’);  
> var context = canvas.getContext(‘2d’);  
> var webcam = document.getElementById(‘webcam’);  
> var swatch = document.getElementById(“color”);
> 
> // Register our custom color tracking function  
> tracking.ColorTracker.registerColor(‘dynamic’, function(r, g, b) {  
> return getColorDistance(color, {r: r, g: g, b: b}) \< slider.value  
> });
> 
> // Create the color tracking object  
> var tracker = new tracking.ColorTracker(“dynamic”);
> 
> // Add callback for the “track” event  
> tracker.on(‘track’, function(e) {
> 
> ```
> context.clearRect(0, 0, canvas.width, canvas.height);
> 
> if (e.data.length !== 0) {
> 
> e.data.forEach(function(rect) {
> // console.log(rect);
> drawRect(rect, context, color);
> });
> 
> }
> 
> ```
> 
> });
> 
> // Start tracking  
> tracking.track(webcam, tracker, { camera: true } );
> 
> // Add listener for the click event on the video  
> webcam.addEventListener(“click”, function (e) {
> 
> ```
> // Grab color from the video feed where the click occured
> var c = getColorAt(webcam, e.offsetX, e.offsetY);
> 
> // Update target color
> color.r = c.r;
> color.g = c.g;
> color.b = c.b;
> 
> // Update the div's background so we can see which color was selected
> swatch.style.backgroundColor = "rgb(" + c.r + ", " + c.g + ", " + c.b + ")";
> 
> ```
> 
> });
> 
> });
> 
> // Calculates the Euclidian distance between the target color and the actual color  
> function getColorDistance(target, actual) {  
> return Math.sqrt(  
> (target.r - actual.r) \* (target.r - actual.r) +  
> (target.g - actual.g) \* (target.g - actual.g) +  
> (target.b - actual.b) \* (target.b - actual.b)  
> );  
> }
> 
> // Returns the color at the specified x/y location in the webcam video feed  
> function getColorAt(webcam, x, y) {
> 
> // To be able to access pixel data from the webcam feed, we must first draw the current frame in  
> // a temporary canvas.  
> var canvas = document.createElement(‘canvas’);  
> var context = canvas.getContext(‘2d’);  
> canvas.width = webcam.width;  
> canvas.height = webcam.height;  
> context.drawImage(webcam, 0, 0, webcam.width, webcam.height);
> 
> // Then we grab the pixel information from the temp canvas and return it as an object  
> var pixel = context.getImageData(x, y, 1, 1).data;  
> return {r: pixel[0], g: pixel[1], b: pixel[2]};
> 
> }
> 
> // Draw a colored rectangle on the canvas  
> function drawRect(rect, context, color) {  
> context.strokeStyle = “rgb(” + color.r + ", " + color.g + ", " + color.b + “)”;  
> context.strokeRect(rect.x, rect.y, rect.width, rect.height);  
> }

`camerapipeline.js`

> const myComponent = {  
> init() {  
> const onxrloaded = () =\> {  
> XR8.addCameraPipelineModule({  
> name: ‘custom’,  
> onCameraStatusChange: (event) =\> {  
> if (event.status === ‘hasVideo’) {  
> console.log(window.tracking)  
> console.log(event.video)  
> }  
> },  
> })  
> }  
> window.XR8 ? onxrloaded() : window.addEventListener(‘xrloaded’, onxrloaded)  
> },  
> }

and `index.css`

```auto
body {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.display {
  position: relative;
}

video {
  display: block;
  /*transform: scaleX(-1);*/
}

canvas {
  display: block;
  position: absolute;
  top: 0;
  pointer-events: none; /* Prevents canvas from intercepting clicks */
  /*transform: scaleX(-1);*/
}

.ui {
  margin-top: 10px;
  width: 640px;
  display: flex;
  justify-content: space-between;
}

  .ui .controls {
    display: flex;
    flex-direction: column;
    justify-content: center;
    width: 70%;
    border: 1px solid gray;
    box-sizing: border-box;
    padding: 0 15px;
    flex-grow: 1;
  }

  .ui .controls p {
    margin-top: 0;
  }

  .ui #color {
    box-sizing: border-box;
    background-color: red;
    width: 100px;
    height: 100px;
    border: 1px solid gray;
    margin-left: 10px;
  }

.controls div {
  display: flex;
}

.controls div label {
  width: 25%;
}

.controls div input {
  width: 75%;
}

```

Thank you!

---

<div class="post-metadata">

### Author: ![lily\_hsiao](https://avatars.discourse-cdn.com/v4/letter/l/ac91a4/32.png) [@lily\_hsiao](https://forum.8thwall.com/u/lily_hsiao)
#### Post date: [February 29, 2024, 5:08pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/12 "2024-02-29T17:08:28Z")

</div>

Sorry, bad for formatting, but the whole code is above. Thank you!

---

<div class="post-metadata">

### Author: ![Evan](https://sea1.discourse-cdn.com/flex019/user_avatar/forum.8thwall.com/evan/32/431_2.png) [@Evan](https://forum.8thwall.com/u/Evan)
#### Post date: [March 1, 2024, 7:29pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/13 "2024-03-01T19:29:38Z")

</div>

The first problem is the way that `script.js` is being loaded. In the cloud editor, `app.js` is the entry point for custom javascript.

So, instead of loading a custom javascript file in `head.html` with a `script` tag:

```auto
<script src="script.js"></script>

```

You should simply import that file in `app.js`:

```auto
import './script'

```

But this isn’t the right approach, anyways. The next issue you’d encounter with this approach is that the window `load` event would not consistently emit, so the code in `script.js` wouldn’t be executed. See [here](https://forum.8thwall.com/t/window-onload-event-not-firing/209) for more information.

The right approach would be to convert `script.js` into a 8th Wall camera pipeline module, which you have already started in `camerapipeline.js`.

> **[CameraPipelineModule | 8th Wall](https://www.8thwall.com/docs/api/camerapipelinemodule/)**
>
> 8th Wall camera applications are built using a camera pipeline module framework. Applications install modules which then control the behavior of the application at runtime.

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex019/uploads/x8thwall/original/2X/9/9212a857458f1b03a6accb129e0f8cbea408e3e5.png) [@system](https://forum.8thwall.com/u/system)
#### Post date: [May 14, 2024, 10:03pm UTC](https://forum.8thwall.com/t/integrated-with-tracking-js/465/14 "2024-05-14T22:03:41Z")

</div>

This topic was automatically closed 4 days after the last reply. New replies are no longer allowed.
