@pictor-sdk/ui 0.1.0 → 0.2.0
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/README.md +12 -1
- package/dist/index.d.mts +34 -2
- package/dist/index.d.ts +34 -2
- package/dist/index.js +76 -34
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -34
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -5
- package/src/index.ts +1 -0
- package/src/panels/LayoutPanel.tsx +11 -5
- package/src/panels/layoutMath.ts +86 -32
package/dist/index.mjs
CHANGED
|
@@ -2795,38 +2795,70 @@ import { Pressable as Pressable7, ScrollView as ScrollView6, Text as Text10 } fr
|
|
|
2795
2795
|
|
|
2796
2796
|
// src/panels/layoutMath.ts
|
|
2797
2797
|
function layoutCells(preset, _doc) {
|
|
2798
|
-
|
|
2799
|
-
|
|
2800
|
-
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
return [{ x: 0.5, y: 0.5, scale: 1 }];
|
|
2798
|
+
return layoutCellBounds(preset).map((cell) => ({
|
|
2799
|
+
x: (cell.x / cell.width + 0.5) * cell.width,
|
|
2800
|
+
y: (cell.y / cell.height + 0.5) * cell.height,
|
|
2801
|
+
scale: cell.width
|
|
2802
|
+
}));
|
|
2803
|
+
}
|
|
2804
|
+
function layoutCellBounds(preset) {
|
|
2805
|
+
const dimensions = {
|
|
2806
|
+
"1": [1, 1],
|
|
2807
|
+
"2v": [1, 2],
|
|
2808
|
+
"2h": [2, 1],
|
|
2809
|
+
"3v": [1, 3],
|
|
2810
|
+
"4grid": [2, 2],
|
|
2811
|
+
"6grid": [2, 3]
|
|
2812
|
+
};
|
|
2813
|
+
const grid = dimensions[preset];
|
|
2814
|
+
if (!grid) throw new RangeError("Unknown layout preset");
|
|
2815
|
+
const [columns, rows] = grid;
|
|
2816
|
+
return Array.from({ length: columns * rows }, (_, index) => ({
|
|
2817
|
+
x: index % columns / columns,
|
|
2818
|
+
y: Math.floor(index / columns) / rows,
|
|
2819
|
+
width: 1 / columns,
|
|
2820
|
+
height: 1 / rows
|
|
2821
|
+
}));
|
|
2822
|
+
}
|
|
2823
|
+
function fitImageToLayoutCell(cell, documentSize, intrinsic, options = {}) {
|
|
2824
|
+
for (const size of [documentSize, intrinsic]) {
|
|
2825
|
+
if (![size.width, size.height].every((v) => Number.isFinite(v) && v > 0)) {
|
|
2826
|
+
throw new RangeError("Layout sizes must be finite and positive");
|
|
2828
2827
|
}
|
|
2829
2828
|
}
|
|
2829
|
+
if (![cell.x, cell.y, cell.width, cell.height].every(Number.isFinite) || cell.x < 0 || cell.y < 0 || cell.width <= 0 || cell.height <= 0 || cell.x + cell.width > 1 + 1e-12 || cell.y + cell.height > 1 + 1e-12) {
|
|
2830
|
+
throw new RangeError("Layout cell must lie inside the document");
|
|
2831
|
+
}
|
|
2832
|
+
const zoom = options.zoom ?? 1;
|
|
2833
|
+
const center = options.center ?? { x: 0.5, y: 0.5 };
|
|
2834
|
+
if (![zoom, center.x, center.y].every(Number.isFinite)) {
|
|
2835
|
+
throw new RangeError("Layout controls must be finite");
|
|
2836
|
+
}
|
|
2837
|
+
const base = centeredCropForAspect(
|
|
2838
|
+
intrinsic,
|
|
2839
|
+
cell.width * documentSize.width / (cell.height * documentSize.height)
|
|
2840
|
+
);
|
|
2841
|
+
const factor = Math.max(1, Math.min(32, zoom));
|
|
2842
|
+
const width = base.width / factor;
|
|
2843
|
+
const height = base.height / factor;
|
|
2844
|
+
return {
|
|
2845
|
+
pixelSnap: true,
|
|
2846
|
+
crop: {
|
|
2847
|
+
x: Math.max(0, Math.min(1 - width, center.x - width / 2)),
|
|
2848
|
+
y: Math.max(0, Math.min(1 - height, center.y - height / 2)),
|
|
2849
|
+
width,
|
|
2850
|
+
height
|
|
2851
|
+
},
|
|
2852
|
+
transform: {
|
|
2853
|
+
x: cell.x + cell.width / 2,
|
|
2854
|
+
y: cell.y + cell.height / 2,
|
|
2855
|
+
scale: cell.width,
|
|
2856
|
+
rotation: 0,
|
|
2857
|
+
anchor: { x: 0.5, y: 0.5 },
|
|
2858
|
+
flipX: false,
|
|
2859
|
+
flipY: false
|
|
2860
|
+
}
|
|
2861
|
+
};
|
|
2830
2862
|
}
|
|
2831
2863
|
function cellToTransformPatch(cell) {
|
|
2832
2864
|
return { x: cell.x, y: cell.y, scale: cell.scale, rotation: 0 };
|
|
@@ -2839,17 +2871,23 @@ var PRESETS = [
|
|
|
2839
2871
|
{ id: "2v", label: "2 rows" },
|
|
2840
2872
|
{ id: "2h", label: "2 cols" },
|
|
2841
2873
|
{ id: "3v", label: "3 rows" },
|
|
2842
|
-
{ id: "4grid", label: "Grid" }
|
|
2874
|
+
{ id: "4grid", label: "Grid" },
|
|
2875
|
+
{ id: "6grid", label: "6 grid" }
|
|
2843
2876
|
];
|
|
2844
2877
|
function LayoutPanel() {
|
|
2845
2878
|
const { document, dispatch } = useEditor13();
|
|
2846
2879
|
const theme = useTheme();
|
|
2847
2880
|
const apply = (preset) => {
|
|
2848
|
-
const cells =
|
|
2881
|
+
const cells = layoutCellBounds(preset);
|
|
2849
2882
|
const images = document.layers.filter((l) => l.type === "image");
|
|
2883
|
+
const fits = images.slice(0, cells.length).map((layer, i) => ({
|
|
2884
|
+
layer,
|
|
2885
|
+
fit: fitImageToLayoutCell(cells[i], document.size, layer.data.intrinsic)
|
|
2886
|
+
}));
|
|
2850
2887
|
dispatch({ type: "history/beginBatch", label: "layout" });
|
|
2851
|
-
|
|
2852
|
-
dispatch({ type: "layer/transform", id: layer.id, patch:
|
|
2888
|
+
fits.forEach(({ layer, fit }) => {
|
|
2889
|
+
dispatch({ type: "layer/transform", id: layer.id, patch: fit.transform });
|
|
2890
|
+
dispatch({ type: "layer/patchData", id: layer.id, patch: { crop: fit.crop, pixelSnap: fit.pixelSnap } });
|
|
2853
2891
|
});
|
|
2854
2892
|
dispatch({ type: "history/endBatch" });
|
|
2855
2893
|
};
|
|
@@ -4624,6 +4662,8 @@ export {
|
|
|
4624
4662
|
createGestureController,
|
|
4625
4663
|
createUiStateStore,
|
|
4626
4664
|
defaultTheme,
|
|
4665
|
+
fitImageToLayoutCell,
|
|
4666
|
+
layoutCellBounds,
|
|
4627
4667
|
layoutCells,
|
|
4628
4668
|
mergeSlots,
|
|
4629
4669
|
mergeTheme,
|