@blokkli/editor 2.0.0-alpha.15 → 2.0.0-alpha.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +66 -11
- package/dist/runtime/components/Edit/Dialog/index.vue +3 -0
- package/dist/runtime/components/Edit/Dialog/index.vue.d.ts +2 -0
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/fragment.glsl +7 -1
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/index.vue +22 -3
- package/dist/runtime/components/Edit/Features/DraggingOverlay/DropTargets/vertex.glsl +1 -0
- package/dist/runtime/components/Edit/Features/Publish/Dialog/Summary.vue +2 -2
- package/dist/runtime/components/Edit/Features/Publish/Dialog/index.vue +17 -7
- package/dist/runtime/components/Edit/Features/Selection/index.vue +21 -7
- package/dist/runtime/composables/defineBlokkli.js +1 -1
- package/dist/runtime/css/output.css +1 -1
- package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.d.ts +1 -1
- package/dist/runtime/helpers/composables/useDelayedIntersectionObserver.js +3 -2
- package/dist/runtime/helpers/domProvider.js +6 -1
- package/dist/runtime/helpers/webgl/index.d.ts +11 -2
- package/dist/runtime/helpers/webgl/index.js +162 -7
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export default function (callback: (entries: IntersectionObserverEntry[]) => void): {
|
|
1
|
+
export default function (callback: (entries: IntersectionObserverEntry[]) => void, options?: IntersectionObserverInit): {
|
|
2
2
|
observe: (el: HTMLElement) => void;
|
|
3
3
|
unobserve: (el: HTMLElement) => void;
|
|
4
4
|
init: () => void;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export default function(callback) {
|
|
1
|
+
export default function(callback, options = {}) {
|
|
2
2
|
let observer = null;
|
|
3
3
|
let collected = [];
|
|
4
4
|
function init() {
|
|
5
5
|
observer = new IntersectionObserver(callback, {
|
|
6
|
-
threshold: 0
|
|
6
|
+
threshold: 0,
|
|
7
|
+
...options
|
|
7
8
|
});
|
|
8
9
|
for (const el of collected) {
|
|
9
10
|
observer.observe(el);
|
|
@@ -139,7 +139,12 @@ export default function(ui, debug, definitions) {
|
|
|
139
139
|
}
|
|
140
140
|
}
|
|
141
141
|
}
|
|
142
|
-
const intersectionObserver = useDelayedIntersectionObserver(
|
|
142
|
+
const intersectionObserver = useDelayedIntersectionObserver(
|
|
143
|
+
intersectionCallback,
|
|
144
|
+
{
|
|
145
|
+
rootMargin: "400px 0px 400px 0px"
|
|
146
|
+
}
|
|
147
|
+
);
|
|
143
148
|
const registeredFieldTypes = computed(() => {
|
|
144
149
|
const fields = Object.values(registeredFields);
|
|
145
150
|
const found = /* @__PURE__ */ new Set();
|
|
@@ -8,10 +8,16 @@ type RectangleBufferRect = Rectangle & {
|
|
|
8
8
|
};
|
|
9
9
|
type RectangleBufferCollectorOptions = {
|
|
10
10
|
padding?: number;
|
|
11
|
+
deferredMode?: boolean;
|
|
11
12
|
};
|
|
12
13
|
type PlacedRectangle = Rectangle & {
|
|
13
14
|
originalY: number;
|
|
14
15
|
};
|
|
16
|
+
type PendingRect<T> = {
|
|
17
|
+
rect: Omit<T, 'index'>;
|
|
18
|
+
type: number;
|
|
19
|
+
checkOverlap: boolean;
|
|
20
|
+
};
|
|
15
21
|
export declare class RectangleBufferCollector<T extends RectangleBufferRect> {
|
|
16
22
|
gl?: WebGLRenderingContext;
|
|
17
23
|
added: Set<string>;
|
|
@@ -26,10 +32,13 @@ export declare class RectangleBufferCollector<T extends RectangleBufferRect> {
|
|
|
26
32
|
index: number;
|
|
27
33
|
bufferInfo: BufferInfo | null;
|
|
28
34
|
placedRects: PlacedRectangle[];
|
|
29
|
-
|
|
35
|
+
deferredMode: boolean;
|
|
36
|
+
pendingRects: PendingRect<T>[];
|
|
37
|
+
constructor(gl?: WebGLRenderingContext, options?: RectangleBufferCollectorOptions);
|
|
30
38
|
reset(): void;
|
|
31
|
-
getIdealPosition(x: number, y: number, width: number, height: number): Rectangle;
|
|
39
|
+
getIdealPosition(x: number, y: number, width: number, height: number, isEmptyField?: boolean): Rectangle;
|
|
32
40
|
addRectangle(rect: Omit<T, 'index'>, type: number, checkOverlap?: boolean): void;
|
|
41
|
+
processPendingRects(): void;
|
|
33
42
|
getIndex(id: string): number | undefined;
|
|
34
43
|
updateRectangle(): void;
|
|
35
44
|
createBufferInfo(): BufferInfo | null;
|
|
@@ -14,12 +14,18 @@ export class RectangleBufferCollector {
|
|
|
14
14
|
index = 0;
|
|
15
15
|
bufferInfo = null;
|
|
16
16
|
placedRects = [];
|
|
17
|
-
|
|
17
|
+
deferredMode = false;
|
|
18
|
+
pendingRects = [];
|
|
19
|
+
constructor(gl, options) {
|
|
18
20
|
this.gl = gl;
|
|
21
|
+
this.deferredMode = options?.deferredMode || false;
|
|
19
22
|
}
|
|
20
23
|
reset() {
|
|
21
24
|
this.added = /* @__PURE__ */ new Set();
|
|
22
|
-
this.
|
|
25
|
+
if (!this.deferredMode) {
|
|
26
|
+
this.rects = {};
|
|
27
|
+
}
|
|
28
|
+
this.placedRects = [];
|
|
23
29
|
this.positions = [];
|
|
24
30
|
this.indices = [];
|
|
25
31
|
this.rectId = [];
|
|
@@ -29,8 +35,10 @@ export class RectangleBufferCollector {
|
|
|
29
35
|
this.radius = [];
|
|
30
36
|
this.index = 0;
|
|
31
37
|
this.bufferInfo = null;
|
|
38
|
+
this.pendingRects = [];
|
|
32
39
|
}
|
|
33
|
-
getIdealPosition(x, y, width, height) {
|
|
40
|
+
getIdealPosition(x, y, width, height, isEmptyField = false) {
|
|
41
|
+
const MIN_HEIGHT = 5;
|
|
34
42
|
const rect = {
|
|
35
43
|
x,
|
|
36
44
|
y,
|
|
@@ -40,19 +48,63 @@ export class RectangleBufferCollector {
|
|
|
40
48
|
};
|
|
41
49
|
const intersections = [];
|
|
42
50
|
for (let i = 0; i < this.placedRects.length; i++) {
|
|
43
|
-
|
|
44
|
-
|
|
51
|
+
const placed = this.placedRects[i];
|
|
52
|
+
const testRect = { ...rect, height: Math.max(height, MIN_HEIGHT) };
|
|
53
|
+
const testPlaced = {
|
|
54
|
+
...placed,
|
|
55
|
+
height: Math.max(placed.height, MIN_HEIGHT)
|
|
56
|
+
};
|
|
57
|
+
if (intersects(testRect, testPlaced)) {
|
|
58
|
+
intersections.push(placed);
|
|
45
59
|
}
|
|
46
60
|
}
|
|
47
61
|
if (intersections.length === 0) {
|
|
48
62
|
this.placedRects.push(rect);
|
|
49
63
|
return rect;
|
|
50
64
|
}
|
|
51
|
-
intersections.sort((a, b) =>
|
|
65
|
+
intersections.sort((a, b) => a.originalY - b.originalY);
|
|
66
|
+
if (isEmptyField) {
|
|
67
|
+
for (let i = 0; i < intersections.length; i++) {
|
|
68
|
+
const existingRect = intersections[i];
|
|
69
|
+
const rectsAbove = this.placedRects.filter(
|
|
70
|
+
(r) => r.y + r.height <= existingRect.y && r.x < x + width && r.x + r.width > x
|
|
71
|
+
);
|
|
72
|
+
let prevBottom = 0;
|
|
73
|
+
if (rectsAbove.length > 0) {
|
|
74
|
+
prevBottom = Math.max(...rectsAbove.map((r) => r.y + r.height));
|
|
75
|
+
}
|
|
76
|
+
const nextTop = existingRect.y;
|
|
77
|
+
const availableSpace = nextTop - prevBottom;
|
|
78
|
+
if (availableSpace >= height) {
|
|
79
|
+
const centeredY = prevBottom + (availableSpace - height) / 2;
|
|
80
|
+
const centeredRect = { ...rect, y: centeredY };
|
|
81
|
+
let hasIntersection = false;
|
|
82
|
+
for (const placed of this.placedRects) {
|
|
83
|
+
const testCentered = {
|
|
84
|
+
...centeredRect,
|
|
85
|
+
height: Math.max(height, MIN_HEIGHT)
|
|
86
|
+
};
|
|
87
|
+
const testPlaced = {
|
|
88
|
+
...placed,
|
|
89
|
+
height: Math.max(placed.height, MIN_HEIGHT)
|
|
90
|
+
};
|
|
91
|
+
if (intersects(testCentered, testPlaced)) {
|
|
92
|
+
hasIntersection = true;
|
|
93
|
+
break;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!hasIntersection) {
|
|
97
|
+
rect.y = centeredY;
|
|
98
|
+
this.placedRects.push(rect);
|
|
99
|
+
return rect;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
52
104
|
for (let i = 0; i < intersections.length; i++) {
|
|
53
105
|
const existingRect = intersections[i];
|
|
54
106
|
let iterations = 0;
|
|
55
|
-
const direction = y
|
|
107
|
+
const direction = y < existingRect.originalY ? -1 : 1;
|
|
56
108
|
while (intersects(rect, existingRect) && iterations < 10) {
|
|
57
109
|
rect.y = y + direction * (10 * (iterations + 1));
|
|
58
110
|
iterations++;
|
|
@@ -65,6 +117,10 @@ export class RectangleBufferCollector {
|
|
|
65
117
|
return rect;
|
|
66
118
|
}
|
|
67
119
|
addRectangle(rect, type, checkOverlap = false) {
|
|
120
|
+
if (this.deferredMode) {
|
|
121
|
+
this.pendingRects.push({ rect, type, checkOverlap });
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
68
124
|
const { x, y, width, height } = checkOverlap ? this.getIdealPosition(rect.x, rect.y, rect.width, rect.height) : rect;
|
|
69
125
|
this.positions.push(
|
|
70
126
|
x,
|
|
@@ -119,6 +175,105 @@ export class RectangleBufferCollector {
|
|
|
119
175
|
this.added.add(rect.id);
|
|
120
176
|
this.index++;
|
|
121
177
|
}
|
|
178
|
+
processPendingRects() {
|
|
179
|
+
if (!this.deferredMode) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
if (!this.pendingRects.length) {
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
const sortedPending = [...this.pendingRects].sort(
|
|
186
|
+
(a, b) => a.rect.y - b.rect.y
|
|
187
|
+
);
|
|
188
|
+
const passes = [
|
|
189
|
+
sortedPending.filter((p) => !p.rect.id.includes(":empty:")),
|
|
190
|
+
// Non-empty rects
|
|
191
|
+
sortedPending.filter((p) => p.rect.id.includes(":empty:"))
|
|
192
|
+
// Empty rects
|
|
193
|
+
];
|
|
194
|
+
for (const pass of passes) {
|
|
195
|
+
for (const { rect, type, checkOverlap } of pass) {
|
|
196
|
+
if (this.added.has(rect.id)) {
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
let finalPosition;
|
|
200
|
+
const existing = this.rects[rect.id];
|
|
201
|
+
if (existing) {
|
|
202
|
+
finalPosition = {
|
|
203
|
+
x: existing.x,
|
|
204
|
+
y: existing.y,
|
|
205
|
+
width: existing.width,
|
|
206
|
+
height: existing.height
|
|
207
|
+
};
|
|
208
|
+
} else if (checkOverlap) {
|
|
209
|
+
const isEmptyField = rect.id.includes(":empty:");
|
|
210
|
+
finalPosition = this.getIdealPosition(
|
|
211
|
+
rect.x,
|
|
212
|
+
rect.y,
|
|
213
|
+
rect.width,
|
|
214
|
+
rect.height,
|
|
215
|
+
isEmptyField
|
|
216
|
+
);
|
|
217
|
+
} else {
|
|
218
|
+
finalPosition = {
|
|
219
|
+
x: rect.x,
|
|
220
|
+
y: rect.y,
|
|
221
|
+
width: rect.width,
|
|
222
|
+
height: rect.height
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const { x, y, width, height } = finalPosition;
|
|
226
|
+
this.positions.push(
|
|
227
|
+
x,
|
|
228
|
+
y,
|
|
229
|
+
// Lower left corner
|
|
230
|
+
0,
|
|
231
|
+
x + width,
|
|
232
|
+
y,
|
|
233
|
+
// Lower right corner
|
|
234
|
+
1,
|
|
235
|
+
x + width,
|
|
236
|
+
y + height,
|
|
237
|
+
// Upper right corner
|
|
238
|
+
2,
|
|
239
|
+
x,
|
|
240
|
+
y + height,
|
|
241
|
+
// Upper left corner
|
|
242
|
+
3
|
|
243
|
+
);
|
|
244
|
+
const baseIndex = 4 * this.index;
|
|
245
|
+
this.indices.push(
|
|
246
|
+
baseIndex,
|
|
247
|
+
baseIndex + 1,
|
|
248
|
+
baseIndex + 2,
|
|
249
|
+
baseIndex,
|
|
250
|
+
baseIndex + 2,
|
|
251
|
+
baseIndex + 3
|
|
252
|
+
);
|
|
253
|
+
const r = rect.radius || [4, 4, 4, 4];
|
|
254
|
+
this.radius.push(...r, ...r, ...r, ...r);
|
|
255
|
+
this.rectId.push(this.index, this.index, this.index, this.index);
|
|
256
|
+
this.types.push(type, type, type, type);
|
|
257
|
+
this.quad.push(x, y, width, height);
|
|
258
|
+
this.quad.push(x, y, width, height);
|
|
259
|
+
this.quad.push(x, y, width, height);
|
|
260
|
+
this.quad.push(x, y, width, height);
|
|
261
|
+
const state = rect.state || 0;
|
|
262
|
+
this.state.push(state, state, state, state);
|
|
263
|
+
this.rects[rect.id] = {
|
|
264
|
+
...rect,
|
|
265
|
+
index: this.index,
|
|
266
|
+
x,
|
|
267
|
+
y,
|
|
268
|
+
width,
|
|
269
|
+
height
|
|
270
|
+
};
|
|
271
|
+
this.added.add(rect.id);
|
|
272
|
+
this.index++;
|
|
273
|
+
}
|
|
274
|
+
this.pendingRects = [];
|
|
275
|
+
}
|
|
276
|
+
}
|
|
122
277
|
getIndex(id) {
|
|
123
278
|
return this.rects[id]?.index;
|
|
124
279
|
}
|