diff options
Diffstat (limited to 'src/client/views')
4 files changed, 59 insertions, 30 deletions
diff --git a/src/client/views/GestureOverlay.tsx b/src/client/views/GestureOverlay.tsx index 2f26bdaef..dc6edf81d 100644 --- a/src/client/views/GestureOverlay.tsx +++ b/src/client/views/GestureOverlay.tsx @@ -242,15 +242,15 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil this._points.length = 0; switch (shape) { case Gestures.Rectangle: - this._points.push({ X: left, Y: top }); - this._points.push({ X: left, Y: top }); - this._points.push({ X: right, Y: top }); - this._points.push({ X: right, Y: top }); + this._points.push({ X: left, Y: top }); // curr pt + this._points.push({ X: left, Y: top }); // curr first ctrl pt + this._points.push({ X: right, Y: top }); // next ctrl pt + this._points.push({ X: right, Y: top }); // next pt - this._points.push({ X: right, Y: top }); - this._points.push({ X: right, Y: top }); - this._points.push({ X: right, Y: bottom }); - this._points.push({ X: right, Y: bottom }); + this._points.push({ X: right, Y: top }); // next pt + this._points.push({ X: right, Y: top }); // next first ctrl pt + this._points.push({ X: right, Y: bottom }); // next next ctrl pt + this._points.push({ X: right, Y: bottom }); // next next pt this._points.push({ X: right, Y: bottom }); this._points.push({ X: right, Y: bottom }); @@ -293,13 +293,13 @@ export class GestureOverlay extends ObservableReactComponent<React.PropsWithChil const radius = Math.max(centerX - Math.min(left, right), centerY - Math.min(top, bottom)); // Dividing the circle into four equal sections, and fitting each section to a cubic Bézier curve. - this._points.push({ X: centerX, Y: centerY + radius }); - this._points.push({ X: centerX + c * radius, Y: centerY + radius }); - this._points.push({ X: centerX + radius, Y: centerY + c * radius }); - this._points.push({ X: centerX + radius, Y: centerY }); + this._points.push({ X: centerX, Y: centerY + radius }); // curr pt + this._points.push({ X: centerX + c * radius, Y: centerY + radius }); // curr first ctrl pt + this._points.push({ X: centerX + radius, Y: centerY + c * radius }); // next pt ctrl pt + this._points.push({ X: centerX + radius, Y: centerY }); // next pt - this._points.push({ X: centerX + radius, Y: centerY }); - this._points.push({ X: centerX + radius, Y: centerY - c * radius }); + this._points.push({ X: centerX + radius, Y: centerY }); // next pt + this._points.push({ X: centerX + radius, Y: centerY - c * radius }); // next first ctrl pt this._points.push({ X: centerX + c * radius, Y: centerY - radius }); this._points.push({ X: centerX, Y: centerY - radius }); diff --git a/src/client/views/MainView.tsx b/src/client/views/MainView.tsx index 44e00396e..cbc337860 100644 --- a/src/client/views/MainView.tsx +++ b/src/client/views/MainView.tsx @@ -76,6 +76,7 @@ import { PresBox } from './nodes/trails'; import { AnchorMenu } from './pdf/AnchorMenu'; import { GPTPopup } from './pdf/GPTPopup/GPTPopup'; import { TopBar } from './topbar/TopBar'; +import { SmartDrawHandler } from './collections/collectionFreeForm/SmartDrawHandler'; const { LEFT_MENU_WIDTH, TOPBAR_HEIGHT } = require('./global/globalCssVariables.module.scss'); // prettier-ignore const _global = (window /* browser */ || global) /* node */ as any; @@ -1091,6 +1092,7 @@ export class MainView extends ObservableReactComponent<{}> { <TaskCompletionBox /> <ContextMenu /> <ImageLabelHandler /> + <SmartDrawHandler /> <AnchorMenu /> <MapAnchorMenu /> <DirectionsAnchorMenu /> diff --git a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx index a27ac2a0c..93b63ac4c 100644 --- a/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx +++ b/src/client/views/collections/collectionFreeForm/CollectionFreeFormView.tsx @@ -1267,17 +1267,17 @@ export class CollectionFreeFormView extends CollectionSubView<Partial<collection SmartDrawHandler.Instance.displaySmartDrawHandler(e.pageX, e.pageY, this.createInkStrokes); }; - @action + @undoBatch createInkStrokes = (strokeList: InkData[], alpha?: number) => { console.log(strokeList.length); strokeList.forEach(inkData => { // const points: InkData = FitCurve(inkData, 20) as InkData; - const allPts = GenerateControlPoints(inkData, alpha); - const bounds = InkField.getBounds(allPts); + // const allPts = GenerateControlPoints(inkData, alpha); + const bounds = InkField.getBounds(inkData); const B = this.screenToFreeformContentsXf.transformBounds(bounds.left, bounds.top, bounds.width, bounds.height); const inkWidth = ActiveInkWidth() * this.ScreenToLocalBoxXf().Scale; const inkDoc = Docs.Create.InkDocument( - allPts, + inkData, { title: 'stroke', x: B.x - inkWidth / 2, y: B.y - inkWidth / 2, diff --git a/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx b/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx index 4c2e78e31..956a8d7e9 100644 --- a/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx +++ b/src/client/views/collections/collectionFreeForm/SmartDrawHandler.tsx @@ -12,6 +12,8 @@ import './ImageLabelHandler.scss'; import { gptAPICall, GPTCallType } from '../../../apis/gpt/GPT'; import { InkData } from '../../../../fields/InkField'; import { ButtonType } from '../../nodes/FontIconBox/FontIconBox'; +import { SVGToBezier } from '../../../util/bezierFit'; +const { parse, stringify } = require('svgson'); @observer export class SmartDrawHandler extends ObservableReactComponent<{}> { @@ -69,19 +71,44 @@ export class SmartDrawHandler extends ObservableReactComponent<{}> { return; } console.log('GPT response:', res); - const simplifiedRes: string = res.replace(/[^\d\[\],]/g, ''); - try { - const parsedPts = JSON.parse(simplifiedRes); - if (parsedPts[0][0][0]) { - const controlPts = (parsedPts as [number, number][][]).map((stroke: [number, number][]) => stroke.map(([X, Y]) => ({ X: X + startPoint.X - 100, Y: Y + startPoint.Y - 100 }))); - this._addToDocFunc(controlPts, this._alpha); - } else { - const controlPts = (parsedPts as [number, number][]).map(([X, Y]) => ({ X: X + startPoint.X - 100, Y: Y + startPoint.Y - 100 })); - this._addToDocFunc([controlPts], this._alpha); - } - } catch (err) { - console.error('Error likely from bad GPT output type'); + const svg = res.match(/<svg[^>]*>([\s\S]*?)<\/svg>/g); + console.log('svg', svg); + if (svg) { + const svgObject = await parse(svg[0]); + console.log('svg object', svgObject); + const svgStrokes: any = svgObject.children; + const beziers: InkData[] = []; + svgStrokes.forEach((stroke: any) => { + const convertedBezier: InkData = SVGToBezier(stroke.name, stroke.attributes); + beziers.push( + convertedBezier.map(point => { + return { X: point.X + startPoint.X, Y: point.Y + startPoint.Y }; + }) + ); + }); + this._addToDocFunc(beziers); } + + // const strokes = res.trim().split(/\s*(?=\s*M)/); // prettier-ignore + // const parsedSegments: InkData[] = []; + // console.log('strokes', strokes); + // strokes.forEach(stroke => { + // stroke = stroke.replace(/C\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)\s*\((\d+,\d+)\)/g, (c, p1, p2, p3) => { + // return `C (${p1}) (${p2}) (${p3}) (${p3})`; + // }); + // const coordStrings = stroke.match(/(\d+,\d+)/g); + // const coords: InkData = []; + // if (coordStrings) { + // coordStrings.forEach(coord => { + // const xy = coord.split(','); + // coords.push({ X: parseInt(xy[0]), Y: parseInt(xy[1]) }); + // }); + // coords.pop(); + // parsedSegments.push(coords); + // } + // console.log('coords', coords); + // }); + // this._addToDocFunc(parsedSegments); } catch (err) { console.error('GPT call failed', err); } |
