@infinite-canvas-tutorial/webcomponents
Version:
WebComponents UI implementation
311 lines (304 loc) • 16.3 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.InfiniteCanvas = exports.TOP_NAVBAR_HEIGHT = void 0;
const lit_1 = require("lit");
const task_1 = require("@lit/task");
const context_1 = require("@lit/context");
const decorators_js_1 = require("lit/decorators.js");
const ecs_1 = require("@infinite-canvas-tutorial/ecs");
const context_2 = require("../context");
const API_1 = require("../API");
require("@spectrum-web-components/theme/sp-theme.js");
require("@spectrum-web-components/theme/src/themes.js");
require("@spectrum-web-components/accordion/sp-accordion.js");
require("@spectrum-web-components/accordion/sp-accordion-item.js");
require("@spectrum-web-components/action-group/sp-action-group.js");
require("@spectrum-web-components/action-menu/sp-action-menu.js");
require("@spectrum-web-components/alert-banner/sp-alert-banner.js");
require("@spectrum-web-components/color-slider/sp-color-slider.js");
require("@spectrum-web-components/color-area/sp-color-area.js");
require("@spectrum-web-components/color-field/sp-color-field.js");
require("@spectrum-web-components/color-wheel/sp-color-wheel.js");
require("@spectrum-web-components/menu/sp-menu-item.js");
require("@spectrum-web-components/menu/sp-menu-divider.js");
require("@spectrum-web-components/menu/sp-menu-group.js");
require("@spectrum-web-components/number-field/sp-number-field.js");
require("@spectrum-web-components/slider/sp-slider.js");
require("@spectrum-web-components/swatch/sp-swatch.js");
require("@spectrum-web-components/swatch/sp-swatch-group.js");
require("@spectrum-web-components/switch/sp-switch.js");
require("@spectrum-web-components/overlay/sp-overlay.js");
require("@spectrum-web-components/progress-circle/sp-progress-circle.js");
require("@spectrum-web-components/textfield/sp-textfield.js");
require("@spectrum-web-components/thumbnail/sp-thumbnail.js");
require("@spectrum-web-components/tooltip/sp-tooltip.js");
require("@spectrum-web-components/picker/sp-picker.js");
require("@spectrum-web-components/popover/sp-popover.js");
require("@spectrum-web-components/overlay/overlay-trigger.js");
require("@spectrum-web-components/divider/sp-divider.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-add.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-add-to.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-delete.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-remove.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-visibility.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-visibility-off.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-properties.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-close.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-down.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-chevron-right.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-layers.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-properties.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-show-menu.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-stroke-width.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-hand.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-select.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-settings.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-shapes.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-undo.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-redo.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-lock-closed.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-lock-open.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-bold.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-italic.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-underline.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-align-left.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-align-center.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-text-align-right.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-layers-backward.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-layers-forward.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-layers-bring-to-front.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-layers-send-to-back.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-show-all-layers.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-copy.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-cut.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-paste.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-rectangle.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-ellipse.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-line.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-annotate-pen.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-code.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-brush.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-rect-select.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-image.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-arrow-up-right.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-send.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-find-and-replace.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-polygon-select.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-comment.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-image-auto-mode.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-vector-draw.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-region-select.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-crop.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-checkmark.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-cancel.js");
require("@spectrum-web-components/icons-workflow/icons/sp-icon-group.js");
exports.TOP_NAVBAR_HEIGHT = 48;
let InfiniteCanvas = class InfiniteCanvas extends lit_1.LitElement {
constructor() {
super(...arguments);
this.renderer = 'webgl';
this.shaderCompilerPath = 'https://unpkg.com/@antv/g-device-api@1.6.8/dist/pkg/glsl_wgsl_compiler_bg.wasm';
this.theme = 'light';
this.nodes = [];
this.appStateProvider = new context_1.ContextProvider(this, { context: context_2.appStateContext });
this.nodesProvider = new context_1.ContextProvider(this, { context: context_2.nodesContext });
this.apiProvider = new context_1.ContextProvider(this, { context: context_2.apiContext });
this.initCanvas = new task_1.Task(this, {
task: ([renderer, shaderCompilerPath]) => {
// if (renderer === 'webgpu') {
// await checkWebGPUSupport();
// }
this.appStateProvider.value = Object.assign(Object.assign({}, (0, ecs_1.getDefaultAppState)()), this.appState);
this.nodesProvider.value = this.nodes;
const { topbarVisible, cameraZoom, cameraX, cameraY, cameraRotation } = this.appStateProvider.value;
const $canvas = document.createElement('canvas');
$canvas.style.width = '100%';
$canvas.style.height = topbarVisible
? `calc(100% - ${exports.TOP_NAVBAR_HEIGHT}px)`
: '100%';
$canvas.tabIndex = 0; // Make canvas focusable
const $htmlLayer = document.createElement('div');
$htmlLayer.style.position = 'absolute';
$htmlLayer.style.top = topbarVisible ? `${exports.TOP_NAVBAR_HEIGHT}px` : '0px';
$htmlLayer.style.left = '0px';
$htmlLayer.style.height = '1px';
$htmlLayer.style.width = '1px';
$htmlLayer.style.contain = 'layout style size';
$htmlLayer.style.userSelect = 'none';
$htmlLayer.style.outline = 'none';
$htmlLayer.style.transform = `scale(${(0, ecs_1.toDomPrecision)(cameraZoom)}) translate(${(0, ecs_1.toDomPrecision)(-cameraX)}px, ${(0, ecs_1.toDomPrecision)(-cameraY)}px)`;
const $svgLayer = document.createElement('div');
$svgLayer.style.position = 'absolute';
$svgLayer.style.top = topbarVisible ? `${exports.TOP_NAVBAR_HEIGHT}px` : '0px';
$svgLayer.style.left = '0px';
$svgLayer.style.height = '100%';
$svgLayer.style.width = '100%';
$svgLayer.style.contain = 'layout style size';
$svgLayer.style.userSelect = 'none';
$svgLayer.style.outline = 'none';
$svgLayer.style.pointerEvents = 'none';
const { width, height } = this.getBoundingClientRect();
API_1.pendingCanvases.push({
container: this,
canvas: {
element: $canvas,
htmlLayer: $htmlLayer,
svgLayer: $svgLayer,
width,
height: topbarVisible ? height - exports.TOP_NAVBAR_HEIGHT : height,
devicePixelRatio: window.devicePixelRatio,
renderer,
shaderCompilerPath,
},
camera: {
zoom: cameraZoom,
x: cameraX,
y: cameraY,
rotation: cameraRotation,
},
});
return [$canvas, $htmlLayer, $svgLayer];
},
args: () => [this.renderer, this.shaderCompilerPath],
});
}
connectedCallback() {
super.connectedCallback();
this.resizeObserver = new ResizeObserver((entries) => this.handleResize(entries));
this.updateComplete.then(() => this.resizeObserver.observe(this));
this.addEventListener('theme-change', (e) => {
this.theme = e.detail.themeMode;
});
}
disconnectedCallback() {
var _a, _b;
super.disconnectedCallback();
(_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.unobserve(this);
(_b = this.apiProvider.value) === null || _b === void 0 ? void 0 : _b.destroy();
}
handleResize(entries) {
var _a, _b;
const { topbarVisible } = this.appStateProvider.value;
const { width, height } = entries[0].contentRect;
const dpr = window.devicePixelRatio;
if (width && height) {
const $canvas = (_a = this.shadowRoot) === null || _a === void 0 ? void 0 : _a.querySelector('canvas');
$canvas.width = Math.floor(width * dpr);
$canvas.height = Math.floor((height - (topbarVisible ? exports.TOP_NAVBAR_HEIGHT : 0)) * dpr);
(_b = this.apiProvider.value) === null || _b === void 0 ? void 0 : _b.resizeCanvas($canvas.width / dpr, $canvas.height / dpr);
}
}
render() {
const { topbarVisible } = this.appStateProvider.value;
const themeWrapper = (content) => (0, lit_1.html) `<sp-theme system="spectrum" color="${this.theme}" scale="medium"
>${typeof content === 'string' ? (0, lit_1.html) `${content}` : content}</sp-theme
>`;
return this.initCanvas.render({
pending: () => themeWrapper((0, lit_1.html) `<sp-progress-circle
label="A small representation of an unclear amount of work"
indeterminate
size="s"
></sp-progress-circle>`),
complete: ([$canvas, $htmlLayer, $svgLayer]) => themeWrapper((0, lit_1.html) `${$svgLayer}${$htmlLayer}<ic-spectrum-top-navbar
></ic-spectrum-top-navbar>${$canvas}
<ic-spectrum-penbar
style=${`top: ${topbarVisible ? exports.TOP_NAVBAR_HEIGHT : 0}px; left: 0;`}
>
<slot name="penbar-item" slot="penbar-item"></slot>
</ic-spectrum-penbar>
<ic-spectrum-penbar-crop></ic-spectrum-penbar-crop>
<ic-spectrum-taskbar
style=${`top: ${topbarVisible ? exports.TOP_NAVBAR_HEIGHT : 0}px; right: 0;`}
>
<slot name="taskbar-item" slot="taskbar-item"></slot>
<slot name="taskbar-panel" slot="taskbar-panel"></slot>
</ic-spectrum-taskbar>
<ic-spectrum-context-bar></ic-spectrum-context-bar>
<ic-spectrum-context-menu></ic-spectrum-context-menu>
<ic-spectrum-text-editor
style=${`top: ${topbarVisible ? exports.TOP_NAVBAR_HEIGHT : 0}px; left: 0;`}
></ic-spectrum-text-editor>
<ic-spectrum-comments
style=${`top: ${topbarVisible ? exports.TOP_NAVBAR_HEIGHT : 0}px; left: 0;`}
></ic-spectrum-comments>
<ic-spectrum-mask></ic-spectrum-mask>`),
error: (e) => {
console.error(e);
return themeWrapper((0, lit_1.html) `<sp-alert-banner open variant="negative">
Initialize canvas failed<br />
<strong></strong><br />
${e.message}
</sp-alert-banner>`);
},
});
}
};
exports.InfiniteCanvas = InfiniteCanvas;
InfiniteCanvas.styles = (0, lit_1.css) `
:host {
display: block;
position: relative;
overflow: clip;
content-visibility: auto;
touch-action: none;
contain: strict;
--mod-popover-content-area-spacing-vertical: 0;
--spectrum-popover-content-area-spacing-vertical: 0;
}
ic-spectrum-penbar {
position: absolute;
top: 0;
left: 0;
}
ic-spectrum-penbar-crop {
position: absolute;
bottom: 0;
left: 50%;
}
ic-spectrum-taskbar {
position: absolute;
top: 0;
right: 0;
}
ic-spectrum-text-editor {
position: absolute;
top: 0;
left: 0;
}
canvas {
width: 100%;
height: 100%;
outline: none;
padding: 0;
margin: 0;
touch-action: none;
}
`;
__decorate([
(0, decorators_js_1.property)()
], InfiniteCanvas.prototype, "renderer", void 0);
__decorate([
(0, decorators_js_1.property)({
attribute: 'shader-compiler-path',
})
], InfiniteCanvas.prototype, "shaderCompilerPath", void 0);
__decorate([
(0, decorators_js_1.property)()
], InfiniteCanvas.prototype, "theme", void 0);
__decorate([
(0, decorators_js_1.property)({ type: Object, attribute: 'app-state' })
], InfiniteCanvas.prototype, "appState", void 0);
__decorate([
(0, decorators_js_1.property)({ type: Array })
], InfiniteCanvas.prototype, "nodes", void 0);
exports.InfiniteCanvas = InfiniteCanvas = __decorate([
(0, decorators_js_1.customElement)('ic-spectrum-canvas')
], InfiniteCanvas);
//# sourceMappingURL=infinite-canvas.js.map