diff --git a/canvas-10-feb/src/App.vue b/canvas-10-feb/src/App.vue index 2ccc72fbe7543960adaf1329d68be628bc412206..9c19e5cfdf25d742613c29bd5f61d869b8598749 100644 --- a/canvas-10-feb/src/App.vue +++ b/canvas-10-feb/src/App.vue @@ -1,7 +1,7 @@ <template> <div id="app"> <div id="nav"> - <router-link to="/">Home</router-link> | + <router-link to="/">Home</router-link>| <router-link to="/about">About</router-link> </div> <router-view /> @@ -13,8 +13,7 @@ font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; - text-align: center; - color: #2c3e50; + } #nav { diff --git a/canvas-10-feb/src/components/CanvasLayer.vue b/canvas-10-feb/src/components/CanvasLayer.vue new file mode 100644 index 0000000000000000000000000000000000000000..fb3183f035cc2f6504c15d5350ec30fa2058a00d --- /dev/null +++ b/canvas-10-feb/src/components/CanvasLayer.vue @@ -0,0 +1,42 @@ +<template> + <div class="canvas"> + <!-- canvas element draws the connection and nodes --> + <canvas ref="canvas"></canvas> + <!-- textarea is the cards/nodes --> + </div> +</template> + +<script> +import { mapState } from 'vuex' +import { draw } from './mixins/draw.js' + +var canvas = null + +export default { + name: 'CanvasLayer', + mixins: [draw], + + computed: mapState({ + configConnect: state => state.configConnect, + configHandle: state => state.configHandle + }), + + mounted() { + canvas = this.$refs.canvas + this.ctx = canvas.getContext('2d') + this.draw() + }, + methods: { + clear(ctx) { + ctx.clearRect(0, 0, canvas.width, canvas.height) + } + } +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +canvas { + border: 1px solid black; +} +</style> diff --git a/canvas-10-feb/src/components/ControlsLayer.vue b/canvas-10-feb/src/components/ControlsLayer.vue new file mode 100644 index 0000000000000000000000000000000000000000..426cbb13e4112502f5688cc1c0908cda4b27cf87 --- /dev/null +++ b/canvas-10-feb/src/components/ControlsLayer.vue @@ -0,0 +1,43 @@ +<template> + <div class="controls"> + <div class="btn-row"> + <button on:click="popups.showPane = !popups.showPane">Button</button> + </div> + <!-- + <div class="popup" v-if="popups.showPane"> + <div class="popup-title">Pane Title</div> + <label> + <input type="radio" name="color" /> + </label> + </div>--> + </div> +</template> + +<script></script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +.controls { + position: fixed; + z-index: 5; + bottom: 0; + left: 0; + width: 100%; + height: 60px; + background-color: rgb(10, 10, 10); + display: flex; + justify-content: center; + align-items: center; + user-select: none; +} + +.btn-row { + position: relative; + margin-bottom: 5px; + display: flex; + justify-content: center; + flex-wrap: wrap; + padding: 0 15px; + border-radius: 4px; +} +</style> diff --git a/canvas-10-feb/src/components/HelloWorld.vue b/canvas-10-feb/src/components/HelloWorld.vue deleted file mode 100644 index 1e88dd32a094559be004ca515cc753f1837cc1f1..0000000000000000000000000000000000000000 --- a/canvas-10-feb/src/components/HelloWorld.vue +++ /dev/null @@ -1,78 +0,0 @@ -<template> - <div class="hello"> - <h1>Welcome to Vue & Canvas testing ground</h1> - - <canvas ref="canvas"></canvas> - - <div class="controls"> - <div class="btn-row"> - <button on:click="popups.showPane = !popups.showPane">Button</button> - </div> - <!-- - <div class="popup" v-if="popups.showPane"> - <div class="popup-title">Pane Title</div> - <label> - <input type="radio" name="color" /> - </label> - </div>--> - </div> - </div> -</template> - -<script> -import { mapState } from 'vuex' -import { draw } from './mixins/draw.js' -var canvas = null - -export default { - name: 'HelloWorld', - mixins: [draw], - - computed: mapState({ - configRect: state => state.configRect, - configHandle: state => state.configHandle - }), - - mounted() { - canvas = this.$refs.canvas - this.ctx = canvas.getContext('2d') - this.draw() - }, - methods: { - clear(ctx) { - ctx.clearRect(0, 0, canvas.width, canvas.height) - } - } -} -</script> - -<!-- Add "scoped" attribute to limit CSS to this component only --> -<style scoped> -canvas { - border: 1px solid black; -} - -.controls { - position: fixed; - z-index: 5; - bottom: 0; - left: 0; - width: 100%; - height: 60px; - background-color: rgb(10, 10, 10); - display: flex; - justify-content: center; - align-items: center; - user-select: none; -} - -.btn-row { - position: relative; - margin-bottom: 5px; - display: flex; - justify-content: center; - flex-wrap: wrap; - padding: 0 15px; - border-radius: 4px; -} -</style> diff --git a/canvas-10-feb/src/components/NodesLayer.vue b/canvas-10-feb/src/components/NodesLayer.vue new file mode 100644 index 0000000000000000000000000000000000000000..6278e4da91f5d6f7f168ffa8b8c888f41579fc36 --- /dev/null +++ b/canvas-10-feb/src/components/NodesLayer.vue @@ -0,0 +1,41 @@ +<template> + <div class="node" ref="nodes"> + <form id="editForm" class="myScroll"> + <textarea></textarea> + <p>markdown supported</p> + <button>delete</button> + </form> + </div> +</template> + +<script> +import { mapState } from 'vuex' +import { drag } from './mixins/drag.js' + +export default { + name: 'NodesLayer', + mixins: [drag], + + mounted() { + var nodes = this.$refs.nodes + + this.makeDraggable(nodes) + }, + methods: { + setFocus() { + this.$refs.notetext.focus() + }, + editNodeText() {}, + deleteFlag() {} + }, + computed: mapState({}) +} +</script> + +<!-- Add "scoped" attribute to limit CSS to this component only --> +<style scoped> +.node { + background-color: aquamarine; + position: absolute; +} +</style> diff --git a/canvas-10-feb/src/components/mixins/drag.js b/canvas-10-feb/src/components/mixins/drag.js new file mode 100644 index 0000000000000000000000000000000000000000..fd36bc621275c869d85b9325db8bec7a287efbb5 --- /dev/null +++ b/canvas-10-feb/src/components/mixins/drag.js @@ -0,0 +1,65 @@ +export const drag = { + methods: { + makeDraggable(nodes) { + var active = false + var currentX + var currentY + var initialX + var initialY + var xOffset = 0 + var yOffset = 0 + + nodes.addEventListener('mousedown', startDrag) + nodes.addEventListener('mousemove', drag) + nodes.addEventListener('mouseup', endDrag) + nodes.addEventListener('mouseleave', endDrag) + nodes.addEventListener('touchstart', startDrag) + nodes.addEventListener('touchmove', drag) + nodes.addEventListener('touchend', endDrag) + nodes.addEventListener('touchleave', endDrag) + nodes.addEventListener('touchcancel', endDrag) + + function startDrag(e) { + if (e.type === 'touchstart') { + initialX = e.touches[0].clientX - xOffset + initialY = e.touches[0].clientY - yOffset + } else { + initialX = e.clientX - xOffset + initialY = e.clientY - yOffset + } + if (e.target.parentNode.classList.contains('node')) { + active = true + } + } + + function drag(e) { + if (active) { + e.preventDefault() + + if (e.type === 'touchmove') { + currentX = e.touches[0].clientX - initialX + currentY = e.touches[0].clientY - initialY + } else { + currentX = e.clientX - initialX + currentY = e.clientY - initialY + } + + xOffset = currentX + yOffset = currentY + + setTranslate(currentX, currentY, nodes) + } + } + + function endDrag() { + initialX = currentX + initialY = currentY + active = false + } + + function setTranslate(xPos, yPos, el) { + el.style.transform = 'translate3d(' + xPos + 'px, ' + yPos + 'px, 0)' + } + } + } +} diff --git a/canvas-10-feb/src/components/mixins/draw.js b/canvas-10-feb/src/components/mixins/draw.js index 5f028039657d941714af031fdddcd04cfd76469b..9bd5dc3920c911698a80b58d605f5549795cd87c 100644 --- a/canvas-10-feb/src/components/mixins/draw.js +++ b/canvas-10-feb/src/components/mixins/draw.js @@ -7,12 +7,12 @@ export const draw = { box(ctx, x, y) { ctx.setTransform(1, 0, 0, 1, x, y) - ctx.fillStyle = this.configRect.fill + ctx.fillStyle = this.configConnect.fill ctx.fillRect( - this.configRect.x, - this.configRect.y, - this.configRect.height, - this.configRect.width + this.configConnect.x, + this.configConnect.y, + this.configConnect.height, + this.configConnect.width ) ctx.fillStyle = this.configHandle.fill diff --git a/canvas-10-feb/src/store/index.js b/canvas-10-feb/src/store/index.js index badaf8c340399b01d3fb3f4b0f1163cb9022066a..353e3ec6be821fcafe56cdafb8fcead198965508 100644 --- a/canvas-10-feb/src/store/index.js +++ b/canvas-10-feb/src/store/index.js @@ -5,7 +5,8 @@ Vue.use(Vuex) export default new Vuex.Store({ state: { - configRect: { + // this will be objects containing arrays of all the handles / connections and nodes + configConnect: { x: -25, y: -25, height: 50, @@ -15,10 +16,11 @@ export default new Vuex.Store({ configHandle: { x: 25, y: 25, - height: 4, - width: 4, + height: 10, + width: 10, fill: 'black' - } + }, + configNodes: {} }, mutations: {}, actions: {}, diff --git a/canvas-10-feb/src/views/Home.vue b/canvas-10-feb/src/views/Home.vue index 540323e6284460c96767bc6f8efac7ea1b18f0d7..1591e6790794e199bed6570fd219abb0f16c4659 100644 --- a/canvas-10-feb/src/views/Home.vue +++ b/canvas-10-feb/src/views/Home.vue @@ -1,17 +1,32 @@ <template> <div class="home"> - <HelloWorld /> + <!-- The number of NodesLayers comes from store --> + <NodesLayer /> + <NodesLayer /> + <CanvasLayer /> + <ControlsLayer /> </div> </template> <script> // @ is an alias to /src -import HelloWorld from '@/components/HelloWorld.vue' +import CanvasLayer from '@/components/CanvasLayer.vue' +import NodesLayer from '@/components/NodesLayer.vue' +import ControlsLayer from '@/components/ControlsLayer.vue' + +import { mapState } from 'vuex' export default { name: 'Home', components: { - HelloWorld - } + CanvasLayer, + NodesLayer, + ControlsLayer + }, + computed: mapState({ + configNodes: state => state.configNodes + }) } </script> + +<style scoped></style>