diff --git a/web/src/components/MapViewCreateOutcome/MapViewCreateOutcome.component.tsx b/web/src/components/MapViewCreateOutcome/MapViewCreateOutcome.component.tsx index 3c26ee15..af2cb32b 100644 --- a/web/src/components/MapViewCreateOutcome/MapViewCreateOutcome.component.tsx +++ b/web/src/components/MapViewCreateOutcome/MapViewCreateOutcome.component.tsx @@ -189,7 +189,6 @@ const MapViewCreateOutcome: React.FC = ({ translate, scale ) - // set card width in pixels const cardWidth = 384 // use this hook to make sure the card is contained within the screen @@ -209,7 +208,9 @@ const MapViewCreateOutcome: React.FC = ({ const height = outerRef.current.offsetHeight setCardHeight(height) } - }, [outerRef.current]) + // this also fires when the `content` changes + // so that adjustments can be made to the height + }, [outerRef.current, content]) // focus text area // after the whole thing becomes visible diff --git a/web/src/drawing/dimensions.ts b/web/src/drawing/dimensions.ts index 4f54a87e..7e32093b 100644 --- a/web/src/drawing/dimensions.ts +++ b/web/src/drawing/dimensions.ts @@ -338,9 +338,9 @@ export function getOutcomeHeight({ const heightOfStatement = drawStatement( argsForDrawStatement({ + onlyMeasure: true, // we don't want it actually drawn on the canvas useLineLimit, noStatementPlaceholder, - onlyMeasure: true, // we don't want it actually drawn on the canvas outcome, outcomeLeftX: 0, // this number doesn't matter for measuring outcomeTopY: 0, // this number doesn't matter for measuring diff --git a/web/src/drawing/drawCreateOutcomeConnection.ts b/web/src/drawing/drawCreateOutcomeConnection.ts index da39f97e..2c5b9018 100644 --- a/web/src/drawing/drawCreateOutcomeConnection.ts +++ b/web/src/drawing/drawCreateOutcomeConnection.ts @@ -1,4 +1,5 @@ import { RenderProps } from '../routes/ProjectView/MapView/selectRenderProps' +import { coordsCanvasToPage, coordsPageToCanvas } from './coordinateSystems' import { getOutcomeWidth, getOutcomeHeight } from './dimensions' import drawConnection, { calculateConnectionCoordsByOutcomeCoords, @@ -14,59 +15,61 @@ export default function drawCreateOutcomeConnection({ ctx, coordinates, allOutcomeDimensions, - projectTags, zoomLevel, + translate, outcomeFormMaybeLinkedOutcome, - outcomeFormContent, outcomeFormLeftConnectionX, outcomeFormTopConnectionY, }: { ctx: CanvasRenderingContext2D coordinates: RenderProps['coordinates'] allOutcomeDimensions: RenderProps['dimensions'] - projectTags: RenderProps['projectTags'] zoomLevel: RenderProps['zoomLevel'] + translate: RenderProps['translate'] outcomeFormMaybeLinkedOutcome: RenderProps['outcomeFormMaybeLinkedOutcome'] - outcomeFormContent: RenderProps['outcomeFormContent'] outcomeFormLeftConnectionX: RenderProps['outcomeFormLeftConnectionX'] outcomeFormTopConnectionY: RenderProps['outcomeFormTopConnectionY'] }) { - /* - establish width and height for the card for a - new Outcome in the process of being created - */ - const placeholderOutcomeWithText = getPlaceholderOutcome(outcomeFormContent) - const newOutcomeWidth = getOutcomeWidth({ - outcome: placeholderOutcomeWithText, - zoomLevel, - }) - const newOutcomeHeight = getOutcomeHeight({ - ctx, - outcome: placeholderOutcomeWithText, - projectTags, - width: newOutcomeWidth, - zoomLevel, - // we set this because in the case of creating a new outcome - // it should use the full text at the proper text scaling - noStatementPlaceholder: true, - useLineLimit: false, - }) const outcomeFormFromActionHash = outcomeFormMaybeLinkedOutcome.outcomeActionHash const outcomeFormRelation = outcomeFormMaybeLinkedOutcome.relation + const sourceCoordinates = coordinates[outcomeFormFromActionHash] + const sourceDimensions = allOutcomeDimensions[outcomeFormFromActionHash] + const destinationCoordinates = { + x: outcomeFormLeftConnectionX, + y: outcomeFormTopConnectionY, + } + const pixelWidth = 384 + const pixelHeight = 205 + const destinationPageCoords = coordsCanvasToPage(destinationCoordinates, translate, zoomLevel) + // overflowX situation + if (destinationPageCoords.x + pixelWidth > window.innerWidth) { + const adjustBy = destinationPageCoords.x + pixelWidth - window.innerWidth + destinationCoordinates.x -= coordsPageToCanvas({ x: adjustBy, y: 0 }, { x: 0, y: 0 }, zoomLevel).x + } + // overflowY situation + if (destinationPageCoords.y + pixelHeight > window.innerHeight) { + const adjustBy = destinationPageCoords.y + pixelHeight - window.innerHeight + destinationCoordinates.y -= coordsPageToCanvas({ x: 0, y: adjustBy }, { x: 0, y: 0 }, zoomLevel).y + } + // convert the height of the card which is measured in pixels into + // the height of the card measured in canvas units + const createOutcomeCardCanvasWidthAndHeight = coordsPageToCanvas({ x: pixelWidth, y: pixelHeight }, { x: 0, y: 0 }, zoomLevel) + const destinationDimensions = { + width: createOutcomeCardCanvasWidthAndHeight.x, + height: createOutcomeCardCanvasWidthAndHeight.y, + } const [ connection1port, connection2port, ] = calculateConnectionCoordsByOutcomeCoords( - coordinates[outcomeFormFromActionHash], - allOutcomeDimensions[outcomeFormFromActionHash], - { - x: outcomeFormLeftConnectionX, - y: outcomeFormTopConnectionY, - }, - { width: newOutcomeWidth, height: newOutcomeHeight }, + sourceCoordinates, + sourceDimensions, + destinationCoordinates, + destinationDimensions, outcomeFormRelation ) + drawConnection({ connection1port, connection2port, diff --git a/web/src/drawing/graphCoordinates.ts b/web/src/drawing/graphCoordinates.ts index 0415c1c2..71896f11 100644 --- a/web/src/drawing/graphCoordinates.ts +++ b/web/src/drawing/graphCoordinates.ts @@ -89,9 +89,9 @@ export default function layoutForGraph( .nodeSize((node: any) => { // width and height, plus some extra padding const width = - node === undefined ? 0 : allOutcomeDimensions[node.data.id].width + 200 + node === undefined || allOutcomeDimensions[node.data.id] === undefined ? 0 : allOutcomeDimensions[node.data.id].width + 200 const height = - node === undefined ? 0 : allOutcomeDimensions[node.data.id].height + 200 + node === undefined || allOutcomeDimensions[node.data.id] === undefined ? 0 : allOutcomeDimensions[node.data.id].height + 200 return [width, height] }) @@ -102,6 +102,8 @@ export default function layoutForGraph( // define the coordinates of each node const coordinates = {} for (const node of dag) { + const dimensions = allOutcomeDimensions[node.data.id] + if (dimensions === undefined) continue const width = allOutcomeDimensions[node.data.id].width const height = allOutcomeDimensions[node.data.id].height coordinates[node.data.id] = { diff --git a/web/src/drawing/index.ts b/web/src/drawing/index.ts index f000dc77..84fa8d6d 100644 --- a/web/src/drawing/index.ts +++ b/web/src/drawing/index.ts @@ -178,10 +178,9 @@ export default function render( ctx, coordinates, allOutcomeDimensions, - projectTags, zoomLevel, + translate, outcomeFormMaybeLinkedOutcome, - outcomeFormContent, outcomeFormLeftConnectionX, outcomeFormTopConnectionY, }) diff --git a/web/src/hooks/useContainWithinScreen.ts b/web/src/hooks/useContainWithinScreen.ts index 48560536..5747175d 100644 --- a/web/src/hooks/useContainWithinScreen.ts +++ b/web/src/hooks/useContainWithinScreen.ts @@ -32,33 +32,15 @@ export default function useContainWithinScreen({ return } // if both x and y are off the screen, move the item up and left - if ( - cursorCoordinate.y + itemHeight > window.innerHeight && - cursorCoordinate.x + itemWidth > window.innerWidth - ) { - setInitialized(true) - setRenderCoordinate({ - x: cursorCoordinate.x - itemWidth, - y: cursorCoordinate.y - itemHeight, - }) - } - // if the item will go off the screen at the bottom edge, move it up so that it is fully visible - else if (cursorCoordinate.y + itemHeight > window.innerHeight) { - setInitialized(true) - setRenderCoordinate({ - x: cursorCoordinate.x, - y: cursorCoordinate.y - itemHeight, - }) - // if the item will go off the screen at the right edge, move it left so that it is fully visible - } else if (cursorCoordinate.x + itemWidth > window.innerWidth) { - setInitialized(true) - setRenderCoordinate({ - x: cursorCoordinate.x - itemWidth, - y: cursorCoordinate.y, - }) - } else { - setInitialized(true) - } + setInitialized(true) + // the amount that it (maybe) exceeds the screen width + const overflowX = window.innerWidth - (cursorCoordinate.x + itemWidth) + // the amount that it (maybe) exceeds the screen height + const overflowY = window.innerHeight - (cursorCoordinate.y + itemHeight) + setRenderCoordinate({ + x: cursorCoordinate.x + Math.min(overflowX, 0), + y: cursorCoordinate.y + Math.min(overflowY, 0), + }) }, [itemWidth, itemHeight, cursorCoordinate.x, cursorCoordinate.y]) return {