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')