diff --git a/src/components/tools/networked-drawing.js b/src/components/tools/networked-drawing.js
index 7ff84444dde720d2bd6831ef031621e012b28478..71e31c58fc8bc99776f65c05673a984bfc56cb81 100644
--- a/src/components/tools/networked-drawing.js
+++ b/src/components/tools/networked-drawing.js
@@ -3,55 +3,172 @@
  * Networked Drawing
  * @component networked-drawing
  */
+
+import SharedBufferGeometryManager from "../../vendor/sharedbuffergeometrymanager";
+
 AFRAME.registerComponent("networked-drawing", {
-  schema: {},
+  schema: {
+    drawPoints: { default: [] },
+    segments: { default: 8 },
+    radius: { default: 0.02 }
+  },
 
   init() {
-    this.points = [];
-
-    var sampleClosedSpline = new THREE.CatmullRomCurve3([
-      new THREE.Vector3(0, -40, -40),
-      new THREE.Vector3(0, 40, -40),
-      new THREE.Vector3(0, 140, -40),
-      new THREE.Vector3(0, 40, 40),
-      new THREE.Vector3(0, -40, 40)
-    ]);
-
-    var params = {
-      scale: 0.02,
-      extrusionSegments: 100,
-      radiusSegments: 3,
-      closed: true,
-      animationView: false,
-      lookAhead: false,
-      cameraHelper: false
+    const material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, color: 0xff0000 });
+
+    this.sharedBufferGeometryManager = new SharedBufferGeometryManager();
+    this.sharedBufferGeometryManager.addSharedBuffer(0, material, THREE.TriangleStripDrawMode);
+
+    this.lastSegments = [];
+    this.currentSegments = [];
+    for (var x = 0; x < this.data.segments; x++) {
+      this.lastSegments[x] = new THREE.Vector3();
+      this.currentSegments[x] = new THREE.Vector3();
+    }
+
+    this.sharedBuffer = this.sharedBufferGeometryManager.getSharedBuffer(0);
+    this.drawing = this.sharedBuffer.getDrawing();
+    let sceneEl = document.querySelector("a-scene");
+    this.scene = sceneEl.object3D;
+    this.scene.add(this.drawing);
+
+    this.lastPoint = new THREE.Vector3();
+    this.lastPointSet = false;
+    this.initialized = false;
+  },
+
+  getLastPoint() {
+    return this.lastPoint;
+  },
+
+  startDraw: (() => {
+    const normal = new THREE.Vector3();
+    return function(position, direction) {
+      this.addPoint(position, direction);
+      this.getNormal(position);
+      this.drawStart(normal, direction);
+    };
+  })(),
+
+  endDraw: (() => {
+    const endPoint = new THREE.Vector3();
+    const direction = new THREE.Vector3();
+    return function(position, direction) {
+      //add the final point  and cap
+      this.addPoint(position, direction);
+      direction.copy(direction).multiplyScalar(this.data.radius);
+      endPoint.copy(position).add(direction);
+      this.drawCap(endPoint, this.currentSegments);
+
+      //reset
+      this.sharedBuffer.restartPrimitive();
+      this.lastPointSet = false;
+      this.lastSegmentsSet = false;
+      this.timeSinceLastDraw = 0;
     };
+  })(),
+
+  //add a "cap" to the start or end of a drawing
+  drawCap(point, segments) {
+    let j = 0;
+    for (let i = 0; i < this.data.segments * 2 - 1; i++) {
+      if ((i - 1) % 3 === 0) {
+        this.addVertex(point);
+      } else {
+        this.addVertex(segments[j % this.data.segments]);
+        j++;
+      }
+    }
+    this.sharedBuffer.update();
+  },
+
+  //calculate the segments for a given point
+  addSegments(segmentsList, point, forward, up) {
+    const angleIncrement = Math.PI * 2 / this.data.segments;
+    for (let i = 0; i < this.data.segments; i++) {
+      const segment = segmentsList[i];
 
-    var geometry = new THREE.TubeBufferGeometry(
-      sampleClosedSpline,
-      params.extrusionSegments,
-      2,
-      params.radiusSegments,
-      params.closed
-    );
-
-    var wireframeMaterial = new THREE.MeshBasicMaterial({
-      color: 0x000000,
-      opacity: 0.3,
-      wireframe: true,
-      transparent: true
-    });
-    var material = new THREE.MeshLambertMaterial({ color: 0xff00ff });
-    var mesh = new THREE.Mesh(geometry, material);
-
-    var wireframe = new THREE.Mesh(geometry, wireframeMaterial);
-    mesh.add(wireframe);
-    mesh.scale.set(params.scale, params.scale, params.scale);
-
-    this.el.object3D.add(mesh);
+      this.rotatePointAroundAxis(segment, point, forward, up, angleIncrement * i, this.data.radius);
+    }
   },
 
-  play() {},
+  addVertex(point) {
+    this.initialized = true;
+    this.sharedBuffer.addVertex(point.x, point.y, point.z);
+  },
+
+  //get lastSegments, draw the start cap
+  drawStart: (() => {
+    const startPoint = new THREE.Vector3();
+    const inverseDirection = new THREE.Vector3();
+    return function(normal, direction) {
+      this.addSegments(this.lastSegments, this.lastPoint, direction, normal);
+
+      inverseDirection
+        .copy(direction)
+        .negate()
+        .multiplyScalar(this.data.radius);
+      startPoint.copy(this.lastPoint).add(inverseDirection);
+
+      //add the first vertex of the lastSegments if this drawing has already been initialized
+      if (this.initialized) {
+        this.addVertex(this.lastSegments[0]);
+      }
+
+      this.drawCap(startPoint, this.lastSegments);
+
+      this.sharedBuffer.restartPrimitive();
+      this.addVertex(this.lastSegments[0]);
+    };
+  })(),
+
+  //helper function to get normal of direction of drawing cross direction to camera
+  getNormal: (() => {
+    const directionToCamera = new THREE.Vector3();
+    return function(normal, position, direction) {
+      if (this.data.camera) {
+        directionToCamera.subVectors(position, this.data.camera.object3D.position).normalize();
+        normal.crossVectors(direction, directionToCamera);
+      } else {
+        normal.copy(this.el.object3D.up);
+      }
+    };
+  })(),
 
-  pause() {}
+  addPoint: (() => {
+    const normal = new THREE.Vector3();
+    return function(position, direction) {
+      if (this.lastPointSet) {
+        this.getNormal(normal, position);
+
+        this.addSegments(this.currentSegments, position, direction, normal);
+
+        //draw the triangle strip
+        for (let j = 0; j <= this.data.segments; j++) {
+          this.addVertex(this.lastSegments[j % this.data.segments]);
+          this.addVertex(this.currentSegments[j % this.data.segments]);
+        }
+
+        //update the drawing
+        this.sharedBuffer.update();
+
+        //copy the currentSegments to lastSegments
+        for (var j = 0; j < this.data.segments; j++) {
+          this.lastSegments[j].copy(this.currentSegments[j]);
+        }
+      }
+
+      this.lastPoint.copy(position);
+      this.lastPointSet = true;
+    };
+  })(),
+
+  rotatePointAroundAxis: (() => {
+    const calculatedDirection = new THREE.Vector3();
+    return function(out, point, axis, up, angle, radius) {
+      calculatedDirection.copy(up);
+      calculatedDirection.applyAxisAngle(axis, angle);
+      out.copy(point).add(calculatedDirection.normalize().multiplyScalar(radius));
+    };
+  })()
 });
diff --git a/src/components/tools/pen.js b/src/components/tools/pen.js
index ac9e57fb18d4ccdb381ed2c4ce49e9a31c88255a..a62981f2479a4ec2201025b933578a04feb99af9 100644
--- a/src/components/tools/pen.js
+++ b/src/components/tools/pen.js
@@ -5,29 +5,19 @@ const EPS = 10e-6;
  * @component pen
  */
 
-import SharedBufferGeometryManager from "../../vendor/sharedbuffergeometrymanager";
-
 AFRAME.registerComponent("pen", {
   schema: {
-    drawPoints: { default: [] },
     drawFrequency: { default: 100 },
     minDistanceBetweenPoints: { default: 0.05 },
     defaultDirection: { default: { x: 1, y: 0, z: 0 } },
-    segments: { default: 8 },
-    radius: { default: 0.02 },
-    debug: { default: false },
-    camera: { type: "selector" }
+    camera: { type: "selector" },
+    drawing: { type: "selector" }
   },
 
   init() {
     this.onMouseDown = this.onMouseDown.bind(this);
     this.onMouseUp = this.onMouseUp.bind(this);
 
-    const material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide, color: 0xff0000 });
-
-    this.sharedBufferGeometryManager = new SharedBufferGeometryManager();
-    this.sharedBufferGeometryManager.addSharedBuffer(0, material, THREE.TriangleStripDrawMode);
-
     this.isDrawing = false;
     this.timeSinceLastDraw = 0;
 
@@ -36,27 +26,13 @@ AFRAME.registerComponent("pen", {
     this.direction = new THREE.Vector3();
     this.direction.copy(this.data.defaultDirection);
 
-    this.lastPoint = new THREE.Vector3();
-    this.lastPointSet = false;
-    this.initialized = false;
-
-    this.lastSegments = [];
-    this.currentSegments = [];
-    for (var x = 0; x < this.data.segments; x++) {
-      this.lastSegments[x] = new THREE.Vector3();
-      this.currentSegments[x] = new THREE.Vector3();
-    }
+    this.handleDrawingInitialized = this.handleDrawingInitialized.bind(this);
 
-    this.sharedBuffer = this.sharedBufferGeometryManager.getSharedBuffer(0);
-    this.drawing = this.sharedBuffer.getDrawing();
-    let sceneEl = document.querySelector("a-scene");
-    this.scene = sceneEl.object3D;
-    this.scene.add(this.drawing);
+    this.data.drawing.addEventListener("componentinitialized", this.handleDrawingInitialized);
+  },
 
-    if (this.data.debug) {
-      this.debugGeometry = new THREE.SphereGeometry(0.005, 16, 16);
-      this.debugMaterial = new THREE.MeshBasicMaterial({ color: 0xffff00 });
-    }
+  remove() {
+    this.data.drawing.removeEventListener("componentinitialized", this.handleDrawingInitialized);
   },
 
   play() {
@@ -71,174 +47,43 @@ AFRAME.registerComponent("pen", {
 
   tick(t, dt) {
     const currentPosition = this.el.object3D.position;
+    const drawing = this.currentDrawing;
 
-    if (currentPosition.distanceToSquared(this.lastPosition) > EPS) {
-      this.direction.subVectors(currentPosition, this.lastPoint).normalize();
+    if (drawing && currentPosition.distanceToSquared(this.lastPosition) > EPS) {
+      this.direction.subVectors(currentPosition, drawing.getLastPoint()).normalize();
     }
     this.lastPosition.copy(currentPosition);
 
-    if (this.isDrawing) {
+    if (drawing && this.isDrawing) {
       const time = this.timeSinceLastDraw + dt;
       if (
         time >= this.data.drawFrequency &&
-        this.lastPoint.distanceTo(currentPosition) >= this.data.minDistanceBetweenPoints
+        drawing.getLastPoint().distanceTo(currentPosition) >= this.data.minDistanceBetweenPoints
       ) {
-        this.addPoint(currentPosition);
+        drawing.addPoint(currentPosition, this.direction);
       }
 
       this.timeSinceLastDraw = time % this.data.drawFrequency;
     }
   },
 
+  handleDrawingInitialized(e) {
+    if (e.detail.name === "networked-drawing") {
+      this.currentDrawing = this.data.drawing.components["networked-drawing"];
+    }
+  },
+
   onMouseDown(e) {
-    if (e.button === 0) {
+    if (this.currentDrawing && e.button === 0) {
       this.isDrawing = true;
-      this.startDraw();
+      this.currentDrawing.startDraw(this.el.object3D.position, this.direction);
     }
   },
 
   onMouseUp(e) {
-    if (e.button === 0) {
+    if (this.currentDrawing && e.button === 0) {
       this.isDrawing = false;
-      this.endDraw();
+      this.currentDrawing.endDraw(this.el.object3D.position, this.direction);
     }
-  },
-
-  startDraw: (() => {
-    const normal = new THREE.Vector3();
-    return function() {
-      this.addPoint(this.el.object3D.position);
-      this.getNormal(normal, this.el.object3D.position);
-      this.drawStart(normal);
-    };
-  })(),
-
-  endDraw: (() => {
-    const endPoint = new THREE.Vector3();
-    const direction = new THREE.Vector3();
-    return function() {
-      //add the final point  and cap
-      this.addPoint(this.el.object3D.position);
-      direction.copy(this.direction).multiplyScalar(this.data.radius);
-      endPoint.copy(this.el.object3D.position).add(direction);
-      this.drawCap(endPoint, this.currentSegments);
-
-      //reset
-      this.sharedBuffer.restartPrimitive();
-      this.lastPointSet = false;
-      this.lastSegmentsSet = false;
-      this.timeSinceLastDraw = 0;
-      // this.direction.copy(this.data.defaultDirection);
-    };
-  })(),
-
-  //add a "cap" to the start or end of a drawing
-  drawCap(point, segments) {
-    let j = 0;
-    for (let i = 0; i < this.data.segments * 2 - 1; i++) {
-      if ((i - 1) % 3 === 0) {
-        this.addVertex(point);
-      } else {
-        this.addVertex(segments[j % this.data.segments]);
-        j++;
-      }
-    }
-    this.sharedBuffer.update();
-  },
-
-  //calculate the segments for a given point
-  addSegments(segmentsList, point, forward, up) {
-    const angleIncrement = Math.PI * 2 / this.data.segments;
-    for (let i = 0; i < this.data.segments; i++) {
-      const segment = segmentsList[i];
-
-      this.rotatePointAroundAxis(segment, point, forward, up, angleIncrement * i, this.data.radius);
-    }
-  },
-
-  addVertex(point) {
-    this.initialized = true;
-    this.sharedBuffer.addVertex(point.x, point.y, point.z);
-
-    if (this.data.debug) {
-      const sphere = new THREE.Mesh(this.debugGeometry, this.debugMaterial);
-      this.scene.add(sphere);
-      sphere.position.copy(point);
-    }
-  },
-
-  //get lastSegments, draw the start cap
-  drawStart: (() => {
-    const startPoint = new THREE.Vector3();
-    const inverseDirection = new THREE.Vector3();
-    return function(normal) {
-      this.addSegments(this.lastSegments, this.lastPoint, this.direction, normal);
-
-      inverseDirection
-        .copy(this.direction)
-        .negate()
-        .multiplyScalar(this.data.radius);
-      startPoint.copy(this.lastPoint).add(inverseDirection);
-
-      //add the first vertex of the lastSegments if this drawing has already been initialized
-      if (this.initialized) {
-        this.addVertex(this.lastSegments[0]);
-      }
-
-      this.drawCap(startPoint, this.lastSegments);
-
-      this.sharedBuffer.restartPrimitive();
-      this.addVertex(this.lastSegments[0]);
-    };
-  })(),
-
-  //helper function to get normal of direction of drawing cross direction to camera
-  getNormal: (() => {
-    const directionToCamera = new THREE.Vector3();
-    return function(normal, position) {
-      if (this.data.camera) {
-        directionToCamera.subVectors(position, this.data.camera.object3D.position).normalize();
-        normal.crossVectors(this.direction, directionToCamera);
-      } else {
-        normal.copy(this.el.object3D.up);
-      }
-    };
-  })(),
-
-  addPoint: (() => {
-    const normal = new THREE.Vector3();
-    return function(position) {
-      if (this.lastPointSet) {
-        this.getNormal(normal, position);
-
-        this.addSegments(this.currentSegments, position, this.direction, normal);
-
-        //draw the triangle strip
-        for (let j = 0; j <= this.data.segments; j++) {
-          this.addVertex(this.lastSegments[j % this.data.segments]);
-          this.addVertex(this.currentSegments[j % this.data.segments]);
-        }
-
-        //update the drawing
-        this.sharedBuffer.update();
-
-        //copy the currentSegments to lastSegments
-        for (var j = 0; j < this.data.segments; j++) {
-          this.lastSegments[j].copy(this.currentSegments[j]);
-        }
-      }
-
-      this.lastPoint.copy(position);
-      this.lastPointSet = true;
-    };
-  })(),
-
-  rotatePointAroundAxis: (() => {
-    const calculatedDirection = new THREE.Vector3();
-    return function(out, point, axis, up, angle, radius) {
-      calculatedDirection.copy(up);
-      calculatedDirection.applyAxisAngle(axis, angle);
-      out.copy(point).add(calculatedDirection.normalize().multiplyScalar(radius));
-    };
-  })()
+  }
 });
diff --git a/src/hub.html b/src/hub.html
index bd31d164c9362fbcf4e6e98bf6d4bb66b042290d..3e6ee536d3ff75bc99c3f47a0eee2327bb24a498 100644
--- a/src/hub.html
+++ b/src/hub.html
@@ -231,7 +231,7 @@
             segments-height="9"
             segments-width="9"
             event-repeater="events: raycaster-intersection, raycaster-intersection-cleared; eventSource: #cursor-controller"
-            pen="camera: #player-camera"
+            pen="camera: #player-camera; drawing: #my-first-drawing"
         ></a-sphere>
 
         <!-- Player Rig -->
@@ -372,10 +372,10 @@
             static-body="shape: none;"
         ></a-entity>
 
-<!--         <a-entity
-            position="0 2 0"
+        <a-entity
+            id="my-first-drawing"
             networked-drawing
-        ></a-entity> -->
+        ></a-entity>
     </a-scene>
 
     <div id="ui-root"></div>
diff --git a/src/hub.js b/src/hub.js
index 4a3cf673e67524cdb3bb9ea2ab4620f63933fa56..38b26d245dd32124ac35e02d946b6b8f80d8c327 100644
--- a/src/hub.js
+++ b/src/hub.js
@@ -128,7 +128,7 @@ import { getAvailableVREntryTypes, VR_DEVICE_AVAILABILITY } from "./utils/vr-cap
 import ConcurrentLoadDetector from "./utils/concurrent-load-detector.js";
 
 import "./components/tools/pen";
-// import "./components/tools/networked-drawing";
+import "./components/tools/networked-drawing";
 
 function qsTruthy(param) {
   const val = qs[param];
diff --git a/src/network-schemas.js b/src/network-schemas.js
index 04275d491d43f9221626cd1060614e0f5c7a2d93..b23859cc3de91ef401d6629a89ccd478ad674ceb 100644
--- a/src/network-schemas.js
+++ b/src/network-schemas.js
@@ -86,7 +86,8 @@ function registerNetworkSchemas() {
         component: "rotation",
         requiresNetworkUpdate: rotationRequiresUpdate
       },
-      "scale"
+      "scale",
+      "networked-drawing"
     ]
   });
 }