@pmndrs/uikit
Version:
Build performant 3D user interfaces with Three.js and yoga.
67 lines (66 loc) • 3.02 kB
JavaScript
import { signal } from '@preact/signals-core';
import { setupInstancedPanel } from './panel/instanced-panel.js';
import { computedOrderInfo, ElementType } from './order.js';
import { abortableEffect, computedBorderInset } from './utils.js';
import { createPanelMaterialConfig, } from './panel/index.js';
const selectionBorderKeys = [
'selectionBorderRightWidth',
'selectionBorderTopWidth',
'selectionBorderLeftWidth',
'selectionBorderBottomWidth',
];
let selectionMaterialConfig;
function getSelectionMaterialConfig() {
selectionMaterialConfig ??= createPanelMaterialConfig({
backgroundColor: 'selectionColor',
backgroundOpacity: 'selectionOpacity',
borderBend: 'selectionBorderBend',
borderBottomLeftRadius: 'selectionBorderBottomLeftRadius',
borderBottomRightRadius: 'selectionBorderBottomRightRadius',
borderColor: 'selectionBorderColor',
borderOpacity: 'selectionBorderOpacity',
borderTopLeftRadius: 'selectionBorderTopLeftRadius',
borderTopRightRadius: 'selectionBorderTopRightRadius',
}, {
backgroundColor: 0xb4d7ff,
backgroundOpacity: 1,
});
return selectionMaterialConfig;
}
export function createSelection(propertiesSignal, matrix, selectionTransformations, isVisible, prevOrderInfo, prevPanelDeps, parentClippingRect, panelGroupManager, abortSignal) {
const panels = [];
const orderInfo = computedOrderInfo(undefined, 'zIndexOffset', ElementType.Panel, prevPanelDeps, prevOrderInfo);
const borderInset = computedBorderInset(propertiesSignal, selectionBorderKeys);
abortableEffect(() => {
const selections = selectionTransformations.value;
const selectionsLength = selections.length;
for (let i = 0; i < selectionsLength; i++) {
let panelData = panels[i];
if (panelData == null) {
const size = signal([0, 0]);
const offset = signal([0, 0]);
const abortController = new AbortController();
setupInstancedPanel(propertiesSignal, orderInfo, prevPanelDeps, panelGroupManager, matrix, size, offset, borderInset, parentClippingRect, isVisible, getSelectionMaterialConfig(), abortController.signal);
panels[i] = panelData = {
abortController,
offset,
size,
};
}
const selection = selections[i];
panelData.size.value = selection.size;
panelData.offset.value = selection.position;
}
const panelsLength = panels.length;
for (let i = selectionsLength; i < panelsLength; i++) {
panels[i].abortController.abort();
}
panels.length = selectionsLength;
}, abortSignal);
abortSignal.addEventListener('abort', () => {
const panelsLength = panels.length;
for (let i = 0; i < panelsLength; i++) {
panels[i].abortController.abort();
}
});
}