From 0e7b797a9de3d4dda7ebf80d970d0c9c3069e0a3 Mon Sep 17 00:00:00 2001 From: tdgmdev <tdgmdev@gmail.com> Date: Tue, 28 Feb 2023 18:09:11 -0500 Subject: [PATCH] Refactored tool system --- src/lib/ide/Env.svelte | 434 -------------------------- src/lib/{ide => vector}/Color.svelte | 0 src/lib/vector/Env.svelte | 266 ++++++++++++++++ src/lib/{ide => vector}/Slider.svelte | 0 src/lib/vector/tools/deleter.js | 10 + src/lib/vector/tools/down.js | 10 + src/lib/vector/tools/edit.js | 38 +++ src/lib/vector/tools/export.js | 13 + src/lib/vector/tools/group.js | 12 + src/lib/vector/tools/import.js | 7 + src/lib/vector/tools/node.js | 45 +++ src/lib/vector/tools/pan.js | 7 + src/lib/vector/tools/resize.js | 64 ++++ src/lib/vector/tools/rotate.js | 16 + src/lib/vector/tools/select.js | 16 + src/lib/vector/tools/ungroup.js | 14 + src/lib/vector/tools/up.js | 10 + src/routes/editor/+page.svelte | 2 +- 18 files changed, 529 insertions(+), 435 deletions(-) delete mode 100644 src/lib/ide/Env.svelte rename src/lib/{ide => vector}/Color.svelte (100%) create mode 100644 src/lib/vector/Env.svelte rename src/lib/{ide => vector}/Slider.svelte (100%) create mode 100644 src/lib/vector/tools/deleter.js create mode 100644 src/lib/vector/tools/down.js create mode 100644 src/lib/vector/tools/edit.js create mode 100644 src/lib/vector/tools/export.js create mode 100644 src/lib/vector/tools/group.js create mode 100644 src/lib/vector/tools/import.js create mode 100644 src/lib/vector/tools/node.js create mode 100644 src/lib/vector/tools/pan.js create mode 100644 src/lib/vector/tools/resize.js create mode 100644 src/lib/vector/tools/rotate.js create mode 100644 src/lib/vector/tools/select.js create mode 100644 src/lib/vector/tools/ungroup.js create mode 100644 src/lib/vector/tools/up.js diff --git a/src/lib/ide/Env.svelte b/src/lib/ide/Env.svelte deleted file mode 100644 index 306089d..0000000 --- a/src/lib/ide/Env.svelte +++ /dev/null @@ -1,434 +0,0 @@ -<style> - .ide { - width: 100vw; - height: calc(100vh - 50px); - display: grid; - grid-template-columns: 300px 1fr 300px; - } - - .ide-left, .ide-mid, .ide-right { - height: 100%; - } - - .ide-left { - border-right: var(--border-1); - } - - .ide-right { - border-left: var(--border-1); - } - - .ide-mid { - display: flex; - align-items: center; - justify-content: center; - overflow: none; - } - - canvas { - width: 100%; - height: 100%; - } -</style> - -<script> - - - import pkg from 'paper'; - const { paper } = pkg; - - import { onMount } from 'svelte'; - - import EditButton from '$lib/page/EditButton.svelte'; - import Color from './Color.svelte'; - import { Group } from "paper/dist/paper-core"; - import { group_outros } from "svelte/internal"; - - let tools = [ - 'edit', - 'pan', - 'select', - 'group', - 'ungroup', - 'resize', - 'rotate', - 'deleter', - 'node', - 'up', - 'down', - 'import', - 'export', - ] - - let mode = 'edit'; - let colorType = 'stroke'; - - let fillColor = '#446699ff'; - let strokeColor = '#000000ff'; - - let darkStroke = '#d8d8d8'; - let white = 'white'; - - let nodeDist = 25; - let grabDist = 15; - - let color = strokeColor; - let stroke = 12; - - let origin = new paper.Point([0,0]); - - let viewGroup, innerGroup, canvas, mainPath, lastPoint, file, files, download; - - let importFile = () => { - file.click(); - } - - let getBase64 = (filee) => { - const reader = new FileReader(); - reader.readAsDataURL(filee); - reader.onload = e => { - let preview = e.target.result; - paper.project.importSVG(preview, function (item) { - innerGroup.addChild(item); - recurseChild(innerGroup); - }); - }; - } - - let exportFile = () => { - var data = new Blob(['<svg>' + innerGroup.exportSVG({asString: true}) + '</svg>'], {type: 'image/svg'}); - - var url = window.URL.createObjectURL(data); - - download.href = url; - download.click(); - } - - let setMode = (modeSet) => { - if (modeSet) - mode = modeSet; - - if (mode == 'group') { - group(); - } else if (mode == 'ungroup') { - ungroup(); - } else if (mode == 'import') { - importFile(); - } else if (mode == 'export') { - exportFile(); - } else if (mode == 'deleter') { - deleter(); - } else if (mode == 'up') { - layerUp(); - } else if (mode == 'down') { - layerDown(); - } - - return mode; - } - - let setColorMode = (modeSet) => { - if (modeSet) - colorType = modeSet; - - color = (modeSet == 'stroke') ? strokeColor : fillColor; - - return colorType; - } - - let setColor = ([colorIn, strokeIn]) => { - color = colorIn; - stroke = strokeIn / 5; - - if (colorType == 'stroke') { - strokeColor = color - } else { - fillColor = color; - } - - if (!paper.project || !paper.project.selectedItems) return; - - paper.project.selectedItems.forEach(item => { - if (colorType == 'stroke') { - item.strokeColor = color - } else { - item.fillColor = color; - } - }) - } - - let initPath = () => { - mainPath = new paper.Path(); - - mainPath.strokeColor = strokeColor; - mainPath.fillColor = fillColor; - mainPath.strokeWidth = stroke; - mainPath.strokeCap = 'butt'; - mainPath.strokeJoin = 'bevel'; - - innerGroup.addChild(mainPath); - - recurseChild(innerGroup); - - } - - let mouseDown = (event) => { - if (mode == 'edit') { - initPath(); - } - } - - let layerDown = () => { - paper.project.selectedItems.reverse().forEach(item => { - item.sendToBack(); - }) - }; - - let layerUp = () => { - paper.project.selectedItems.forEach(item => { - item.bringToFront(); - }) - }; - - let group = () => { - var group = new paper.Group(paper.project.selectedItems); - innerGroup.addChild(group); - }; - - let ungroup = () => { - paper.project.selectedItems.forEach(item => { - if (!item.children || item.className != 'Group' || item == innerGroup) return; - item.selected = false; - item.children.forEach(child => { - innerGroup.addChild(child); - }) - }) - } - - let deleter = () => { - paper.project.selectedItems.forEach(item => { - console.log(item); - item.remove(); - }) - } - - let mouseDownInner = (event) => { - event.stopPropagation(); - - console.log(event.target); - - var target = event.target; - - while (target.parent != innerGroup) { - target = target.parent; - } - - console.log(target); - - if (mode == 'select') { - target.selected = !target.selected; - } else if (mode == 'node') { - var nearestPoint = target.getNearestPoint(event.point); - - if (nearestPoint.getDistance(event.point) > nodeDist) return; - - target.segments.forEach(segment => { - segment.selected = false; - }); - - let closestPoint = target.segments[0]; - let closestDist = 10000; - - target.segments.forEach(segment => { - let dist = segment.point.getDistance(nearestPoint); - if (dist < closestDist) { - closestDist = dist; - closestPoint = segment.point; - } - }); - - let newPoint; - - if (nearestPoint.getDistance(closestPoint) > grabDist) { - newPoint = target.divideAt(target.getLocationOf(nearestPoint)); - } else { - newPoint = closestPoint; - } - - newPoint.selected = true; - } else if (mode == 'resize' || mode == 'rotate') { - target.selected = !target.selected; - target.bounds.selected = target.selected; - } - } - - let mouseDrag = (event) => { - if (mode == 'pan') { - viewGroup.position = viewGroup.position.add(event.delta); - } else if (mode == 'edit') { - lastPoint = event.point; - - mainPath.add(event.point); - } else if (mode == 'select' || mode == 'node') { - paper.project.selectedItems.forEach(item => { - if ((mode == 'select' && item.parent != innerGroup)) return; - - if (mode == 'node') { - if (item.className == 'Path') { - item.segments.forEach(segment => { - if (segment.selected) - segment.point = segment.point.add(event.delta) - }) - } - } else { - item.position = item.position.add(event.delta) - } - - - }); - } else if (mode == 'resize') { - paper.project.selectedItems.forEach(item => { - var nearestPoint = event.point; - - if (!item.bounds.selected) return; - - let seg = [ - item.bounds.topLeft, - item.bounds.topRight, - item.bounds.bottomLeft, - item.bounds.bottomRight, - item.bounds.topCenter, - item.bounds.bottomCenter, - item.bounds.leftCenter, - item.bounds.rightCenter - ]; - - let segOpp = [ - item.bounds.bottomRight, - item.bounds.bottomLeft, - item.bounds.topRight, - item.bounds.topLeft, - item.bounds.bottomCenter, - item.bounds.topCenter, - item.bounds.rightCenter, - item.bounds.leftCenter - ] - - let closestPoint = seg[0]; - let closestDist = 10000; - let i = -1; - - seg.forEach((segment,index) => { - let dist = segment.getDistance(nearestPoint); - if (dist < closestDist) { - closestDist = dist; - closestPoint = segOpp[index]; - i = index; - } - }); - - if (closestDist < nodeDist) { - var signX = (i == 1 || i == 3 || i == 7) ? 1 : -1; - var signY = (i == 1 || i == 0 || i == 4) ? -1 : 1; - if (i > 5) { - item.scale(1 + signX * event.delta.x / item.bounds.width, 1, closestPoint); - } else if (i > 3) { - item.scale(1, 1 + signY * event.delta.y / item.bounds.height, closestPoint); - } else { - item.scale(1 + signX * event.delta.x / item.bounds.width, 1 + signY * event.delta.y / item.bounds.height, closestPoint); - } - } - }); - } else if (mode == 'rotate') { - paper.project.selectedItems.forEach(item => { - if (!item.bounds.selected) return; - var rotAngle = event.point.subtract(item.bounds.center).angle - event.point.add(event.delta).subtract(item.bounds.center).angle; - item.rotate(-rotAngle); - }); - } - } - - let mouseUp = (event) => { - if (mode == 'edit') { - if (mainPath.lastSegment.point.getDistance(mainPath.firstSegment.point) < nodeDist) { - mainPath.closePath(); - } - } - } - - let mouseDragInner = (event) => { - - } - - let recurseChild = (parent) => { - if (!parent.children || parent.children.length == 0) { - parent.onMouseDrag = mouseDragInner; - parent.onDoubleClick = mouseDownInner; - return; - } else { - parent.onMouseDrag = () => {}; - parent.onDoubleClick = () => {}; - } - - parent.children.forEach(child => { - if (child == parent) return; - recurseChild(child); - }) - } - - let initView = () => { - let rect = new paper.Rectangle(0,0,480,360); - - let path = new paper.Path.Rectangle(rect); - path.fillColor = 'white'; - - let pathOut = new paper.Path.Rectangle(rect); - - pathOut.strokeColor = darkStroke; - pathOut.strokeWidth = '3'; - - innerGroup = new paper.Group([]); - - viewGroup = new paper.Group([path,innerGroup,pathOut]); - - /*paper.project.importSVG("/logo.svg", function (item) { - innerGroup.addChild(item); - recurseChild(innerGroup); - })*/ - - viewGroup.onMouseDrag = mouseDrag; - viewGroup.onMouseDown = mouseDown; - viewGroup.onMouseUp = mouseUp; - } - - - onMount(() => { - if (!canvas) return; - - paper.setup(canvas); - - initView(); - initPath(); - - console.log(paper.view); - }); - -</script> - -<div class='ide'> - <div class='ide-left'> - {#each tools as tool} - <EditButton bindMode={setMode} modeIn={mode} mode={tool} /> - {/each} - </div> - <div class='ide-mid'> - <canvas class='canvas' resize bind:this={canvas}></canvas> - </div> - <div class='ide-right'> - <EditButton bindMode={setColorMode} modeIn={colorType} mode={'stroke'} /> - <EditButton bindMode={setColorMode} modeIn={colorType} mode={'fill'} /> - <Color bindColor={setColor} color={color} /> - <input type="file" style="display:none" bind:files on:change={() => getBase64(files[0])} bind:this={file}> - <a download="export.svg" bind:this={download} hidden></a> - </div> -</div> \ No newline at end of file diff --git a/src/lib/ide/Color.svelte b/src/lib/vector/Color.svelte similarity index 100% rename from src/lib/ide/Color.svelte rename to src/lib/vector/Color.svelte diff --git a/src/lib/vector/Env.svelte b/src/lib/vector/Env.svelte new file mode 100644 index 0000000..fc72cc7 --- /dev/null +++ b/src/lib/vector/Env.svelte @@ -0,0 +1,266 @@ +<style> + .ide { + width: 100vw; + height: calc(100vh - 50px); + display: grid; + grid-template-columns: 300px 1fr 300px; + } + + .ide-left, .ide-mid, .ide-right { + height: 100%; + } + + .ide-left { + border-right: var(--border-1); + } + + .ide-right { + border-left: var(--border-1); + } + + .ide-mid { + display: flex; + align-items: center; + justify-content: center; + overflow: none; + } + + canvas { + width: 100%; + height: 100%; + } +</style> + +<script> + + + import pkg from 'paper'; + const { paper } = pkg; + + import { onMount } from 'svelte'; + + import EditButton from '$lib/page/EditButton.svelte'; + import Color from './Color.svelte'; + import { Group } from "paper/dist/paper-core"; + import { group_outros } from "svelte/internal"; + + let tools = [ + 'edit', + 'pan', + 'select', + 'group', + 'ungroup', + 'resize', + 'rotate', + 'deleter', + 'node', + 'up', + 'down', + 'import', + 'export', + ] + + let toolData = {}; + + tools.forEach(async tool => { + toolData[tool] = await import(`./tools/${tool}.js`); + }) + + + let viewGroup, canvas, mainPath, lastPoint, file, files, download, settings; + + let darkStroke = '#000000'; + + let mode = 'edit'; + + settings = { + colorType: 'stroke', + + fill: { + color: '#446699ff', + stroke: '#000000ff' + }, + + color: '#000000ff', + + stroke: 12, + + innerGroup: null, + + viewGroup: null, + + mainPath: null, + + nodeDist: 45, + + grabDist: 15, + + doc: { + + } + + }; + + let getBase64 = (filee) => { + const reader = new FileReader(); + reader.readAsDataURL(filee); + reader.onload = e => { + let preview = e.target.result; + paper.project.importSVG(preview, function (item) { + settings.innerGroup.addChild(item); + recurseChild(settings.innerGroup); + }); + }; + } + + let execFunc = (obj, val, args) => { + obj = obj.toolData; + if (obj[val]) { + let result = obj[val]({ + ...args, + ...settings, + delta: args.delta, + point: args.point, + target: args.target, + selectedItems: paper.project.selectedItems + }); + settings = result || settings; + recurseChild(settings.innerGroup); + } + } + + let origin = new paper.Point([0,0]); + + + let setMode = (modeSet) => { + if (modeSet) + mode = modeSet; + + execFunc(toolData[mode],'run',[]) + + return mode; + } + + let setColorMode = (modeSet) => { + if (modeSet) + settings.colorType = modeSet; + + color = (modeSet == 'stroke') ? settings.fill.stroke : settings.fill.color; + + return settings.colorType; + } + + let setColor = ([colorIn, strokeIn]) => { + settings.color = colorIn; + settings.stroke = strokeIn / 5; + + if (settings.colorType == 'stroke') { + settings.fill.stroke = settings.color + } else { + settings.fill.color = settings.color; + } + + if (!paper.project || !paper.project.selectedItems) return; + + paper.project.selectedItems.forEach(item => { + if (settings.colorType == 'stroke') { + item.strokeColor = settings.color + } else { + item.fillColor = settings.color; + } + }) + } + + let mouseEvent = (type) => { + return (event) => { + execFunc(toolData[mode],type,event); + } + } + + let mouseEventInner = (type) => { + return (event) => { + event.stopPropagation(); + + var target = event.target; + + while (target.parent != settings.innerGroup && target.parent != settings.viewGroup && target.parent) { + target = target.parent; + } + + event.target = target; + + execFunc(toolData[mode],type,event); + } + } + + let recurseChild = (parent) => { + if (!parent.children || parent.children.length == 0) { + parent.onMouseDrag = mouseEventInner('mouseDragInner'); + parent.onDoubleClick = mouseEventInner('doubleClickInner'); + return; + } else { + parent.onMouseDrag = () => {}; + parent.onDoubleClick = () => {}; + } + + parent.children.forEach(child => { + if (child == parent) return; + recurseChild(child); + }) + } + + let initView = () => { + let rect = new paper.Rectangle(0,0,480,360); + + let path = new paper.Path.Rectangle(rect); + path.fillColor = 'white'; + + let pathOut = new paper.Path.Rectangle(rect); + + pathOut.strokeColor = darkStroke; + pathOut.strokeWidth = '3'; + + settings.innerGroup = new paper.Group([]); + + settings.viewGroup = new paper.Group([path,settings.innerGroup,pathOut]); + + /*paper.project.importSVG("/logo.svg", function (item) { + innerGroup.addChild(item); + recurseChild(innerGroup); + })*/ + + settings.viewGroup.onMouseDrag = mouseEvent('mouseDrag'); + settings.viewGroup.onMouseDown = mouseEvent('mouseDown'); + settings.viewGroup.onMouseUp = mouseEvent('mouseUp'); + } + + + onMount(() => { + if (!canvas) return; + + paper.setup(canvas); + + initView(); + + console.log(paper.view); + }); + +</script> + +<div class='ide'> + <div class='ide-left'> + {#each tools as tool} + <EditButton bindMode={setMode} modeIn={mode} mode={tool} /> + {/each} + </div> + <div class='ide-mid'> + <canvas class='canvas' resize bind:this={canvas}></canvas> + </div> + <div class='ide-right'> + <EditButton bindMode={setColorMode} modeIn={settings.colorType} mode={'stroke'} /> + <EditButton bindMode={setColorMode} modeIn={settings.colorType} mode={'fill'} /> + <Color bindColor={setColor} color={settings.color} /> + <input type="file" style="display:none" bind:files on:change={() => getBase64(files[0])} bind:this={settings.doc.file}> + <a download="export.svg" bind:this={settings.doc.download} hidden></a> + </div> +</div> \ No newline at end of file diff --git a/src/lib/ide/Slider.svelte b/src/lib/vector/Slider.svelte similarity index 100% rename from src/lib/ide/Slider.svelte rename to src/lib/vector/Slider.svelte diff --git a/src/lib/vector/tools/deleter.js b/src/lib/vector/tools/deleter.js new file mode 100644 index 0000000..606104f --- /dev/null +++ b/src/lib/vector/tools/deleter.js @@ -0,0 +1,10 @@ + +let toolData = { + run: ({ selectedItems }) => { + selectedItems.forEach(item => { + item.remove(); + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/down.js b/src/lib/vector/tools/down.js new file mode 100644 index 0000000..885f15d --- /dev/null +++ b/src/lib/vector/tools/down.js @@ -0,0 +1,10 @@ + +let toolData = { + run: ({ selectedItems }) => { + selectedItems.reverse().forEach(item => { + item.sendToBack(); + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/edit.js b/src/lib/vector/tools/edit.js new file mode 100644 index 0000000..2edc4a0 --- /dev/null +++ b/src/lib/vector/tools/edit.js @@ -0,0 +1,38 @@ +import pkg from 'paper'; +const { paper } = pkg; + +let lastPoint; + +let toolData = { + mouseDown: (settings) => { + let { innerGroup, mainPath, fill, stroke } = settings; + mainPath = new paper.Path(); + + mainPath.strokeColor = fill.stroke; + mainPath.fillColor = fill.color; + + mainPath.strokeWidth = stroke; + mainPath.strokeCap = 'butt'; + mainPath.strokeJoin = 'bevel'; + + innerGroup.addChild(mainPath); + + settings.mainPath = mainPath; + return settings; + + }, + + mouseDrag: ( {mainPath, point}) => { + lastPoint = point; + + mainPath.add(point); + }, + + mouseUp: ( {mainPath, nodeDist }) => { + if (mainPath.lastSegment.point.getDistance(mainPath.firstSegment.point) < nodeDist) { + mainPath.closePath(); + } + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/export.js b/src/lib/vector/tools/export.js new file mode 100644 index 0000000..bb2d9f8 --- /dev/null +++ b/src/lib/vector/tools/export.js @@ -0,0 +1,13 @@ + +let toolData = { + run: ({ innerGroup, doc }) => { + var data = new Blob(['<svg>' + innerGroup.exportSVG({asString: true}) + '</svg>'], {type: 'image/svg'}); + + var url = window.URL.createObjectURL(data); + + doc.download.href = url; + doc.download.click(); + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/group.js b/src/lib/vector/tools/group.js new file mode 100644 index 0000000..2e3301e --- /dev/null +++ b/src/lib/vector/tools/group.js @@ -0,0 +1,12 @@ + +import pkg from 'paper'; +const { paper } = pkg; + +let toolData = { + run: ({ selectedItems, innerGroup }) => { + var group = new paper.Group(selectedItems); + innerGroup.addChild(group); + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/import.js b/src/lib/vector/tools/import.js new file mode 100644 index 0000000..a6b3bf9 --- /dev/null +++ b/src/lib/vector/tools/import.js @@ -0,0 +1,7 @@ +let toolData = { + run: ({ doc }) => { + doc.file.click(); + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/node.js b/src/lib/vector/tools/node.js new file mode 100644 index 0000000..6c01642 --- /dev/null +++ b/src/lib/vector/tools/node.js @@ -0,0 +1,45 @@ +let toolData = { + doubleClickInner: (event) => { + var nearestPoint = event.target.getNearestPoint(event.point); + + if (nearestPoint.getDistance(event.point) > event.nodeDist) return; + + event.target.segments.forEach(segment => { + segment.selected = false; + }); + + let closestPoint = event.target.segments[0]; + let closestDist = 10000; + + event.target.segments.forEach(segment => { + let dist = segment.point.getDistance(nearestPoint); + if (dist < closestDist) { + closestDist = dist; + closestPoint = segment.point; + } + }); + + let newPoint; + + if (nearestPoint.getDistance(closestPoint) > event.grabDist) { + newPoint = event.target.divideAt(event.target.getLocationOf(nearestPoint)); + } else { + newPoint = closestPoint; + } + + newPoint.selected = true; + }, + + mouseDrag : ( {selectedItems, delta} ) => { + selectedItems.forEach(item => { + if (item.className == 'Path') { + item.segments.forEach(segment => { + if (segment.selected) + segment.point = segment.point.add(delta) + }) + } + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/pan.js b/src/lib/vector/tools/pan.js new file mode 100644 index 0000000..a872ce5 --- /dev/null +++ b/src/lib/vector/tools/pan.js @@ -0,0 +1,7 @@ +let toolData = { + mouseDrag: ( { viewGroup, delta } ) => { + viewGroup.position = viewGroup.position.add(delta); + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/resize.js b/src/lib/vector/tools/resize.js new file mode 100644 index 0000000..2358e76 --- /dev/null +++ b/src/lib/vector/tools/resize.js @@ -0,0 +1,64 @@ +let toolData = { + doubleClickInner: ({ target }) => { + target.selected = !target.selected; + target.bounds.selected = target.selected; + }, + + mouseDrag: ( {selectedItems, point, delta, nodeDist} ) => { + selectedItems.forEach(item => { + var nearestPoint = point; + + if (!item.bounds.selected) return; + + + let seg = [ + item.bounds.topLeft, + item.bounds.topRight, + item.bounds.bottomLeft, + item.bounds.bottomRight, + item.bounds.topCenter, + item.bounds.bottomCenter, + item.bounds.leftCenter, + item.bounds.rightCenter + ]; + + let segOpp = [ + item.bounds.bottomRight, + item.bounds.bottomLeft, + item.bounds.topRight, + item.bounds.topLeft, + item.bounds.bottomCenter, + item.bounds.topCenter, + item.bounds.rightCenter, + item.bounds.leftCenter + ] + + let closestPoint = seg[0]; + let closestDist = 10000; + let i = -1; + + seg.forEach((segment,index) => { + let dist = segment.getDistance(nearestPoint); + if (dist < closestDist) { + closestDist = dist; + closestPoint = segOpp[index]; + i = index; + } + }); + + if (closestDist < nodeDist) { + var signX = (i == 1 || i == 3 || i == 7) ? 1 : -1; + var signY = (i == 1 || i == 0 || i == 4) ? -1 : 1; + if (i > 5) { + item.scale(1 + signX * delta.x / item.bounds.width, 1, closestPoint); + } else if (i > 3) { + item.scale(1, 1 + signY * delta.y / item.bounds.height, closestPoint); + } else { + item.scale(1 + signX * delta.x / item.bounds.width, 1 + signY * delta.y / item.bounds.height, closestPoint); + } + } + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/rotate.js b/src/lib/vector/tools/rotate.js new file mode 100644 index 0000000..dce4ba9 --- /dev/null +++ b/src/lib/vector/tools/rotate.js @@ -0,0 +1,16 @@ +let toolData = { + doubleClickInner: ({ target }) => { + target.selected = !target.selected; + target.bounds.selected = target.selected; + }, + + mouseDrag: ( {selectedItems, point, delta} ) => { + selectedItems.forEach(item => { + if (!item.bounds.selected) return; + var rotAngle = point.subtract(item.bounds.center).angle - point.add(delta).subtract(item.bounds.center).angle; + item.rotate(-rotAngle); + }); + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/select.js b/src/lib/vector/tools/select.js new file mode 100644 index 0000000..8ea16d7 --- /dev/null +++ b/src/lib/vector/tools/select.js @@ -0,0 +1,16 @@ +let toolData = { + doubleClickInner: ({ target }) => { + target.selected = !target.selected; + }, + + mouseDragInner: ( {selectedItems, delta, innerGroup} ) => { + selectedItems.forEach(item => { + if ((item.parent != innerGroup)) return; + + item.position = item.position.add(delta) + }) + + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/ungroup.js b/src/lib/vector/tools/ungroup.js new file mode 100644 index 0000000..d8fbb35 --- /dev/null +++ b/src/lib/vector/tools/ungroup.js @@ -0,0 +1,14 @@ + +let toolData = { + run: ({ selectedItems, innerGroup }) => { + selectedItems.forEach(item => { + if (!item.children || item.className != 'Group' || item == innerGroup) return; + item.selected = false; + item.children.forEach(child => { + innerGroup.addChild(child); + }) + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/lib/vector/tools/up.js b/src/lib/vector/tools/up.js new file mode 100644 index 0000000..a23c93a --- /dev/null +++ b/src/lib/vector/tools/up.js @@ -0,0 +1,10 @@ + +let toolData = { + run: ({ selectedItems }) => { + selectedItems.forEach(item => { + item.bringToFront(); + }) + } +} + +export { toolData }; \ No newline at end of file diff --git a/src/routes/editor/+page.svelte b/src/routes/editor/+page.svelte index 07397d2..1fa5c06 100644 --- a/src/routes/editor/+page.svelte +++ b/src/routes/editor/+page.svelte @@ -1,5 +1,5 @@ <script> - import Env from '$lib/ide/Env.svelte' + import Env from '$lib/vector/Env.svelte' </script> <Env /> \ No newline at end of file