diff --git a/app/src/components/NodesLayer.vue b/app/src/components/NodesLayer.vue
index fd84448926d29a8ba04b306cbb45899524c1d37f..df45f628aa6838b65b57dfa1e3c0432b395490c9 100644
--- a/app/src/components/NodesLayer.vue
+++ b/app/src/components/NodesLayer.vue
@@ -308,6 +308,7 @@ export default {
 <!-- Add "scoped" attribute to limit CSS to this component only -->
 <style scoped>
 .node {
+
   position: relative;
 }
 
diff --git a/app/src/components/ScribbleLayer.vue b/app/src/components/ScribbleLayer.vue
index 8ff4683a052a547622810d3233092e70461bfc00..2af7562c4993549ed61fcc70f8895eecc75cd79a 100644
--- a/app/src/components/ScribbleLayer.vue
+++ b/app/src/components/ScribbleLayer.vue
@@ -10,14 +10,19 @@
 </template>
 
 <script>
+//FIXME: touch / mouse is not under cursor
+var ongoingTouches = []
+
 export default {
   name: 'ScribbleLayer',
 
-  props: {},
+  props: {
+    drawready: Boolean,
+  },
 
   data() {
     return {
-      painting: false,
+      painting: this.drawready,
       canvas: null,
       ctx: null,
     }
@@ -25,13 +30,15 @@ export default {
 
   methods: {
     startPainting(e) {
-      this.painting = true
-     // console.log(this.painting)
-      this.draw(e)
+      this.painting = this.drawready
+      if (this.painting == true) {
+        // console.log(this.painting)
+        this.draw(e)
+      }
     },
     finishedPainting() {
       this.painting = false
-    //  console.log(this.painting)
+      //  console.log(this.painting)
       this.ctx.beginPath()
     },
     draw(e) {
@@ -46,6 +53,115 @@ export default {
       this.ctx.beginPath()
       this.ctx.moveTo(e.clientX, e.clientY)
     },
+
+    // touch methods
+
+    handleStart(evt) {
+      evt.preventDefault()
+      console.log('touchstart.')
+      var el = document.getElementById('canvas')
+      var ctx = el.getContext('2d')
+      var touches = evt.changedTouches
+
+      for (var i = 0; i < touches.length; i++) {
+        console.log('touchstart:' + i + '...')
+        ongoingTouches.push(this.copyTouch(touches[i]))
+        var color = this.colorForTouch(touches[i])
+        ctx.beginPath()
+        ctx.arc(touches[i].pageX, touches[i].pageY, 4, 0, 2 * Math.PI, false) // a circle at the start
+        ctx.fillStyle = color
+        ctx.fill()
+        console.log('touchstart:' + i + '.')
+      }
+    },
+
+    handleMove(evt) {
+      evt.preventDefault()
+      var el = document.getElementById('canvas')
+      var ctx = el.getContext('2d')
+      var touches = evt.changedTouches
+
+      for (var i = 0; i < touches.length; i++) {
+        var color = this.colorForTouch(touches[i])
+        var idx = this.ongoingTouchIndexById(touches[i].identifier)
+
+        if (idx >= 0) {
+          console.log('continuing touch ' + idx)
+          ctx.beginPath()
+          console.log(
+            'ctx.moveTo(' +
+              ongoingTouches[idx].pageX +
+              ', ' +
+              ongoingTouches[idx].pageY +
+              ');'
+          )
+          ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY)
+          console.log(
+            'ctx.lineTo(' + touches[i].pageX + ', ' + touches[i].pageY + ');'
+          )
+          ctx.lineTo(touches[i].pageX, touches[i].pageY)
+          ctx.lineWidth = 4
+          ctx.strokeStyle = color
+          ctx.stroke()
+
+          ongoingTouches.splice(idx, 1, this.copyTouch(touches[i])) // swap in the new touch record
+          console.log('.')
+        } else {
+          console.log("can't figure out which touch to continue")
+        }
+      }
+    },
+    handleEnd(evt) {
+      evt.preventDefault()
+      // log('touchend')
+      var el = document.getElementById('canvas')
+      var ctx = el.getContext('2d')
+      var touches = evt.changedTouches
+
+      for (var i = 0; i < touches.length; i++) {
+        var color = this.colorForTouch(touches[i])
+        var idx = this.ongoingTouchIndexById(touches[i].identifier)
+
+        if (idx >= 0) {
+          ctx.lineWidth = 4
+          ctx.fillStyle = color
+          ctx.beginPath()
+          ctx.moveTo(ongoingTouches[idx].pageX, ongoingTouches[idx].pageY)
+          ctx.lineTo(touches[i].pageX, touches[i].pageY)
+          ctx.fillRect(touches[i].pageX - 4, touches[i].pageY - 4, 8, 8) // and a square at the end
+          ongoingTouches.splice(idx, 1) // remove it; we're done
+        } else {
+          console.log("can't figure out which touch to end")
+        }
+      }
+    },
+    colorForTouch(touch) {
+      var r = touch.identifier % 16
+      var g = Math.floor(touch.identifier / 3) % 16
+      var b = Math.floor(touch.identifier / 7) % 16
+      r = r.toString(16) // make it a hex digit
+      g = g.toString(16) // make it a hex digit
+      b = b.toString(16) // make it a hex digit
+      var color = '#' + r + g + b
+      console.log(
+        'color for touch with identifier ' + touch.identifier + ' = ' + color
+      )
+      return color
+    },
+
+    copyTouch({ identifier, pageX, pageY }) {
+      return { identifier, pageX, pageY }
+    },
+    ongoingTouchIndexById(idToFind) {
+      for (var i = 0; i < ongoingTouches.length; i++) {
+        var id = ongoingTouches[i].identifier
+
+        if (id == idToFind) {
+          return i
+        }
+      }
+      return -1 // not found
+    },
   },
 
   mounted() {
@@ -55,6 +171,11 @@ export default {
     // Resize canvas
     this.canvas.height = window.innerHeight
     this.canvas.width = window.innerWidth
+
+    this.canvas.addEventListener('touchstart', this.handleStart, false)
+    this.canvas.addEventListener('touchend', this.handleEnd, false)
+    this.canvas.addEventListener('touchcancel', this.handleCancel, false)
+    this.canvas.addEventListener('touchmove', this.handleMove, false)
   },
 }
 </script>
diff --git a/app/src/experimental/ModeToolbar.vue b/app/src/experimental/ModeToolbar.vue
index 17a14621d937cf89e6028029689d7ee097168fe4..b2df402957b9beb9b2b660a05ed547e7364d028c 100644
--- a/app/src/experimental/ModeToolbar.vue
+++ b/app/src/experimental/ModeToolbar.vue
@@ -50,9 +50,10 @@ export default {
       }
       if (mode == 'copy') {
         this.$emit('copyDone')
-        //  onFileSelected(event) {
-        // this.selectedFile = event.target.files[0]
-        //  }
+      }
+      if (mode == 'draw') {
+        this.$emit('drawOn')
+        // console.log(mode)
       }
     },
 
diff --git a/app/src/views/Home.vue b/app/src/views/Home.vue
index 522dd1f1bf3038e19b713b3507dfc2b40bdf0982..ea9d754b6f18665b03750fdb9c4ae0df105b35b8 100644
--- a/app/src/views/Home.vue
+++ b/app/src/views/Home.vue
@@ -75,7 +75,7 @@
               @editTrue="(e) => editTrue(e)"
             />
           </div>
-          <ScribbleLayer></ScribbleLayer>
+          <ScribbleLayer v-bind:drawready="drawready"></ScribbleLayer>
         </PanZoomContainer>
 
         <ModeToolbar
@@ -83,6 +83,7 @@
           @onlineTriggered="onlineTriggered()"
           @uploadAdded="uploadAdded()"
           @copyDone="copyDone()"
+          @drawOn="drawOn()"
         />
         <ViewToolbar />
         <UploadLayer
@@ -125,6 +126,7 @@ export default {
       offline: false,
       uploadready: false,
       copyready: false,
+      drawready: false,
     }
   },
   computed: {
@@ -188,6 +190,11 @@ export default {
       this.$store.dispatch('shortcutState', e)
     },
 
+    drawOn() {
+      this.drawready = !this.drawready
+      console.log(this.drawready)
+    },
+
     // This is here to support the shortcuts
     addNode() {
       this.$store.dispatch('addNode')