Track corner intersaction

This commit is contained in:
rijkvanzanten
2021-05-28 18:42:32 -04:00
parent 8025bc8796
commit 5877b82be3
3 changed files with 98 additions and 8 deletions

View File

@@ -2,7 +2,14 @@
<div
class="panel"
:style="positioning"
:class="{ editing: editMode, dragging }"
:class="{
editing: editMode,
dragging,
'br-tl': dragging || panel.borderRadius[0],
'br-tr': dragging || panel.borderRadius[1],
'br-br': dragging || panel.borderRadius[2],
'br-bl': dragging || panel.borderRadius[3],
}"
data-move
@pointerdown="onPointerDown('move', $event)"
>
@@ -219,7 +226,6 @@ export default defineComponent({
grid-column: var(--pos-x) / span var(--width);
background-color: var(--background-page);
border: 1px solid var(--border-subdued);
border-radius: var(--border-radius-outline);
box-shadow: 0 0 0 1px var(--border-subdued);
}
@@ -371,4 +377,20 @@ export default defineComponent({
height: 12px;
cursor: nesw-resize;
}
.br-tl {
border-top-left-radius: var(--border-radius-outline);
}
.br-tr {
border-top-right-radius: var(--border-radius-outline);
}
.br-br {
border-bottom-right-radius: var(--border-radius-outline);
}
.br-bl {
border-bottom-left-radius: var(--border-radius-outline);
}
</style>

View File

@@ -82,6 +82,7 @@ import { omit } from 'lodash';
import { unexpectedError } from '@/utils/unexpected-error';
import api from '@/api';
import InsightsPanel from '../components/panel.vue';
import { pointOnLine } from '@/utils/point-on-line';
export default defineComponent({
name: 'InsightsDashboard',
@@ -107,12 +108,12 @@ export default defineComponent({
insightsStore.state.dashboards.find((dashboard) => dashboard.id === props.primaryKey)
);
const stagedPanels = ref<Partial<Panel>[]>([]);
const stagedPanels = ref<Partial<Panel & { borderRadius: [boolean, boolean, boolean, boolean] }>[]>([]);
const panels = computed(() => {
const savedPanels = currentDashboard.value?.panels || [];
return [
const raw = [
...savedPanels.map((panel) => {
const updates = stagedPanels.value.find((updatedPanel) => updatedPanel.id === panel.id);
@@ -124,14 +125,58 @@ export default defineComponent({
}),
...stagedPanels.value.filter((panel) => panel.id?.startsWith('_')),
];
const withCoords = raw.map((panel) => ({
...panel,
_coordinates: [
[panel.position_x!, panel.position_y!],
[panel.position_x! + panel.width!, panel.position_y!],
[panel.position_x! + panel.width!, panel.position_y! + panel.height!],
[panel.position_x!, panel.position_y! + panel.height!],
] as [number, number][],
}));
const withBorderRadii = withCoords.map((panel) => {
let topLeftIntersects = false;
let topRightIntersects = false;
let bottomRightIntersects = false;
let bottomLeftIntersects = false;
for (const otherPanel of withCoords) {
if (otherPanel.id === panel.id) continue;
const borders = [
[otherPanel._coordinates[0], otherPanel._coordinates[1]],
[otherPanel._coordinates[1], otherPanel._coordinates[2]],
[otherPanel._coordinates[2], otherPanel._coordinates[3]],
[otherPanel._coordinates[3], otherPanel._coordinates[0]],
];
if (topLeftIntersects === false)
topLeftIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[0], p1, p2));
if (topRightIntersects === false)
topRightIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[1], p1, p2));
if (bottomRightIntersects === false)
bottomRightIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[2], p1, p2));
if (bottomLeftIntersects === false)
bottomLeftIntersects = borders.some(([p1, p2]) => pointOnLine(panel._coordinates[3], p1, p2));
}
return {
...panel,
borderRadius: [!topLeftIntersects, !topRightIntersects, !bottomRightIntersects, !bottomLeftIntersects],
};
});
return withBorderRadii;
});
const workspaceSize = computed(() => {
const furthestPanelX = panels.value.reduce(
(aggr, panel) => {
if (panel.position_x! > aggr.position_x!) {
aggr.position_x = panel.position_x;
aggr.width = panel.width;
aggr.position_x = panel.position_x!;
aggr.width = panel.width!;
}
return aggr;
@@ -142,8 +187,8 @@ export default defineComponent({
const furthestPanelY = panels.value.reduce(
(aggr, panel) => {
if (panel.position_y! > aggr.position_y!) {
aggr.position_y = panel.position_y;
aggr.height = panel.height;
aggr.position_y = panel.position_y!;
aggr.height = panel.height!;
}
return aggr;

View File

@@ -0,0 +1,23 @@
type Point = [number, number];
/**
* Check if a given X, Y coordinate is on the line between two other points
*/
export function pointOnLine(current: Point, point1: Point, point2: Point) {
const [curX, curY] = current;
const [p1X, p1Y] = point1;
const [p2X, p2Y] = point2;
const dxc = curX - p1X;
const dyc = curY - p1Y;
const dxl = p2X - p1X;
const dyl = p2Y - p1Y;
const cross = dxc * dyl - dyc * dxl;
if (cross !== 0) return false;
if (Math.abs(dxl) >= Math.abs(dyl)) return dxl > 0 ? p1X <= curX && curX <= p2X : p2X <= curX && curX <= p1X;
else return dyl > 0 ? p1Y <= curY && curY <= p2Y : p2Y <= curY && curY <= p1Y;
}