@sequent-org/moodboard 1.0.24 → 1.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/package.json +2 -2
- package/src/assets/emodji//320/226/320/265/320/275/321/201/320/272/320/270/320/265 /321/215/320/274/320/276/321/206/320/270/320/270/1f645.png +0 -0
- package/src/assets/emodji//320/226/320/265/320/275/321/201/320/272/320/270/320/265 /321/215/320/274/320/276/321/206/320/270/320/270/1f646.png +0 -0
- package/src/assets/emodji//320/226/320/265/320/275/321/201/320/272/320/270/320/265 /321/215/320/274/320/276/321/206/320/270/320/270/1f64b.png +0 -0
- package/src/assets/emodji//320/226/320/265/320/275/321/201/320/272/320/270/320/265 /321/215/320/274/320/276/321/206/320/270/320/270/1f64d.png +0 -0
- package/src/assets/emodji//320/226/320/265/320/275/321/201/320/272/320/270/320/265 /321/215/320/274/320/276/321/206/320/270/320/270/1f64e.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f446.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f447.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f448.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f449.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44a.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44b.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44c.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f450.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f4aa.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f590.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f596.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f64c.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f64f.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/261d.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270a.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270b.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270c.png +0 -0
- package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270d.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f638.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f639.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63a.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63b.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63c.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63d.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63e.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63f.png +0 -0
- package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f640.png +0 -0
- package/src/assets/emodji//320/236/320/261/320/265/320/267/321/214/321/217/320/275/320/272/320/260/1f435.png +0 -0
- package/src/assets/emodji//320/236/320/261/320/265/320/267/321/214/321/217/320/275/320/272/320/260/1f648.png +0 -0
- package/src/assets/emodji//320/236/320/261/320/265/320/267/321/214/321/217/320/275/320/272/320/260/1f649.png +0 -0
- package/src/assets/emodji//320/236/320/261/320/265/320/267/321/214/321/217/320/275/320/272/320/260/1f64a.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f440.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f441.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f499.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a1.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a3.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a9.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4ac.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4af.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/203c.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/26d4.png +0 -0
- package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/2764.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f600.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f601.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f602.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f603.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f604.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f605.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f606.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f607.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f609.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60a.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60b.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60c.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60d.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60e.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60f.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f610.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f611.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f612.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f613.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f614.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f615.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f616.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f617.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f618.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f619.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61a.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61b.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61c.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61d.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61e.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61f.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f620.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f621.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f622.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f623.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f624.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f625.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f626.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f627.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f628.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f629.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62a.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62b.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62c.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62d.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62e.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62f.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f630.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f631.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f632.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f633.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f635.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f636.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f641.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f642.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/2639.png +0 -0
- package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/263a.png +0 -0
- package/src/assets/fonts/amatic-sc/AmaticSC-Bold.ttf +0 -0
- package/src/assets/fonts/amatic-sc/AmaticSC-Regular.ttf +0 -0
- package/src/assets/fonts/caveat/Caveat-Bold.ttf +0 -0
- package/src/assets/fonts/caveat/Caveat-Medium.ttf +0 -0
- package/src/assets/fonts/caveat/Caveat-Regular.ttf +0 -0
- package/src/assets/fonts/caveat/Caveat-SemiBold.ttf +0 -0
- package/src/assets/fonts/caveat/Caveat-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/great-vibes/GreatVibes-Regular.ttf +0 -0
- package/src/assets/fonts/lobster/Lobster-Regular.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Black.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-BlackItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Bold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-BoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-ExtraBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-ExtraLight.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Italic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Light.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-LightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Medium.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-MediumItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Regular.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-SemiBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-Thin.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-ThinItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif-VariableFont_wdth,wght.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Black.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-BlackItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Bold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-BoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraLight.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Italic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Light.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-LightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Medium.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-MediumItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Regular.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-SemiBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Thin.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ThinItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Black.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-BlackItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Bold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-BoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraLight.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Italic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Light.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-LightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Medium.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-MediumItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Regular.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-SemiBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Thin.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ThinItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Black.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-BlackItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Bold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-BoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraLight.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Italic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Light.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-LightItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Medium.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-MediumItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Regular.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-SemiBold.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Thin.ttf +0 -0
- package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ThinItalic.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-Bold.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-ExtraLight.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-Light.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-Medium.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-Regular.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-SemiBold.ttf +0 -0
- package/src/assets/fonts/oswald/Oswald-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/pacifico/Pacifico-Regular.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Black.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-BlackItalic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Bold.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-BoldItalic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-ExtraBold.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Italic-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Italic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Medium.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-MediumItalic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-Regular.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-SemiBold.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/playfair/PlayfairDisplay-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/poiret-one/PoiretOne-Regular.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Black.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-BlackItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-BoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-ExtraBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-ExtraLight.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Italic-VariableFont_wdth,wght.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Italic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Light.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-LightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-MediumItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-SemiBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-ThinItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto-VariableFont_wdth,wght.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Black.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-BlackItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Bold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-BoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-ExtraBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-ExtraLight.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Italic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Light.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-LightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Medium.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-MediumItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Regular.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-SemiBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-Thin.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_Condensed-ThinItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Black.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-BlackItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Bold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-BoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraLight.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraLightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Italic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Light.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-LightItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Medium.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-MediumItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Regular.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-SemiBold.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-SemiBoldItalic.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-Thin.ttf +0 -0
- package/src/assets/fonts/roboto/Roboto_SemiCondensed-ThinItalic.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Black.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Bold.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-ExtraBold.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-ExtraLight.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Light.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Medium.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Regular.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-SemiBold.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-Thin.ttf +0 -0
- package/src/assets/fonts/roboto-slab/RobotoSlab-VariableFont_wght.ttf +0 -0
- package/src/assets/fonts/rubik-mono-one/RubikMonoOne-Regular.ttf +0 -0
- package/src/assets/icons/arrows-up-down-left-right.svg +1 -0
- package/src/assets/icons/arrows-up-down.svg +1 -0
- package/src/assets/icons/attachments.svg +1 -3
- package/src/assets/icons/attachments2.svg +3 -0
- package/src/assets/icons/clear.svg +1 -5
- package/src/assets/icons/cursor-default-custom.svg +10 -0
- package/src/assets/icons/cursor-default.svg +1 -0
- package/src/assets/icons/cursor-default2.svg +1 -0
- package/src/assets/icons/emoji.svg +1 -6
- package/src/assets/icons/emoji2.svg +6 -0
- package/src/assets/icons/frame.svg +1 -3
- package/src/assets/icons/frame2.svg +3 -0
- package/src/assets/icons/i-cursor.svg +1 -0
- package/src/assets/icons/image.svg +1 -3
- package/src/assets/icons/image2.svg +3 -0
- package/src/assets/icons/note.svg +1 -3
- package/src/assets/icons/note2.svg +3 -0
- package/src/assets/icons/pencil.svg +1 -3
- package/src/assets/icons/pencil2.svg +3 -0
- package/src/assets/icons/rotate-icon.svg +3 -0
- package/src/assets/icons/select.svg +1 -1
- package/src/assets/icons/shapes.svg +1 -3
- package/src/assets/icons/shapes2.svg +3 -0
- package/src/assets/icons/text-add.svg +1 -3
- package/src/assets/icons/text-add2.svg +3 -0
- package/src/assets/icons/trash.svg +1 -0
- package/src/core/PixiEngine.js +32 -0
- package/src/core/commands/CopyObjectCommand.js +20 -9
- package/src/core/commands/GroupMoveCommand.js +49 -13
- package/src/core/commands/MoveObjectCommand.js +4 -24
- package/src/core/commands/PasteObjectCommand.js +26 -15
- package/src/core/events/Events.js +2 -0
- package/src/core/index.js +575 -47
- package/src/grid/GridFactory.js +3 -3
- package/src/grid/LineGrid.js +42 -20
- package/src/moodboard/MoodBoard.js +11 -0
- package/src/objects/DrawingObject.js +16 -7
- package/src/objects/FileObject.js +25 -11
- package/src/objects/FrameObject.js +38 -9
- package/src/objects/ImageObject.js +24 -5
- package/src/objects/NoteObject.js +227 -39
- package/src/objects/ShapeObject.js +9 -8
- package/src/objects/TextObject.js +2 -20
- package/src/services/BoardService.js +3 -3
- package/src/services/FrameService.js +95 -17
- package/src/services/ZoomPanController.js +14 -3
- package/src/tools/BaseTool.js +6 -1
- package/src/tools/ToolManager.js +24 -1
- package/src/tools/object-tools/DrawingTool.js +3 -1
- package/src/tools/object-tools/PlacementTool.js +366 -105
- package/src/tools/object-tools/SelectTool.js +508 -153
- package/src/tools/object-tools/TextTool.js +23 -2
- package/src/tools/object-tools/selection/BoxSelectController.js +5 -0
- package/src/ui/FilePropertiesPanel.js +9 -2
- package/src/ui/FramePropertiesPanel.js +239 -91
- package/src/ui/HtmlHandlesLayer.js +383 -126
- package/src/ui/HtmlTextLayer.js +122 -26
- package/src/ui/NotePropertiesPanel.js +128 -44
- package/src/ui/TextPropertiesPanel.js +100 -118
- package/src/ui/Toolbar.js +254 -65
- package/src/ui/Topbar.js +112 -10
- package/src/ui/ZoomPanel.js +8 -2
- package/src/ui/styles/index.css +5 -0
- package/src/ui/styles/panels.css +232 -0
- package/src/ui/styles/toolbar.css +77 -0
- package/src/ui/styles/topbar.css +113 -0
- package/src/ui/styles/workspace.css +481 -263
- package/src/utils/emojiResolver.js +121 -0
|
@@ -14,13 +14,15 @@ export class NoteObject {
|
|
|
14
14
|
this.objectData = objectData;
|
|
15
15
|
|
|
16
16
|
// Размеры записки
|
|
17
|
-
|
|
18
|
-
this.
|
|
17
|
+
const defaultSide = 250; // квадрат 250x250
|
|
18
|
+
this.width = objectData.width || objectData.properties?.width || defaultSide;
|
|
19
|
+
this.height = objectData.height || objectData.properties?.height || defaultSide;
|
|
19
20
|
|
|
20
21
|
// Свойства записки
|
|
21
22
|
const props = objectData.properties || {};
|
|
22
23
|
this.content = props.content || '';
|
|
23
|
-
this.fontSize = props.fontSize ||
|
|
24
|
+
this.fontSize = props.fontSize || 32;
|
|
25
|
+
const fontFamily = props.fontFamily || 'Caveat, Arial, cursive';
|
|
24
26
|
this.backgroundColor = (typeof props.backgroundColor === 'number') ? props.backgroundColor : 0xFFF9C4; // Светло-желтый
|
|
25
27
|
this.borderColor = (typeof props.borderColor === 'number') ? props.borderColor : 0xF9A825; // Золотистый
|
|
26
28
|
this.textColor = (typeof props.textColor === 'number') ? props.textColor : 0x1A1A1A; // Почти черный для лучшей контрастности
|
|
@@ -32,25 +34,74 @@ export class NoteObject {
|
|
|
32
34
|
this.container.eventMode = 'static';
|
|
33
35
|
this.container.interactiveChildren = true;
|
|
34
36
|
|
|
37
|
+
// Тени по бокам (как у .box::before / .box::after)
|
|
38
|
+
this.shadowLayer = new PIXI.Container();
|
|
39
|
+
this.shadowLeft = new PIXI.Graphics();
|
|
40
|
+
this.shadowRight = new PIXI.Graphics();
|
|
41
|
+
this.shadowLayer.addChild(this.shadowLeft);
|
|
42
|
+
this.shadowLayer.addChild(this.shadowRight);
|
|
43
|
+
try {
|
|
44
|
+
// Мягкая тень (чуть сильнее)
|
|
45
|
+
this.shadowLayer.filters = [new PIXI.filters.BlurFilter(12)];
|
|
46
|
+
} catch (_) {}
|
|
47
|
+
this.container.addChild(this.shadowLayer);
|
|
48
|
+
|
|
35
49
|
// Графика фона
|
|
36
50
|
this.graphics = new PIXI.Graphics();
|
|
37
51
|
this.container.addChild(this.graphics);
|
|
38
52
|
|
|
53
|
+
// Функция согласованной высоты строки (как в HtmlTextLayer)
|
|
54
|
+
this._computeLineHeightPx = (fs) => {
|
|
55
|
+
if (fs <= 12) return Math.round(fs * 1.40);
|
|
56
|
+
if (fs <= 18) return Math.round(fs * 1.34);
|
|
57
|
+
if (fs <= 36) return Math.round(fs * 1.26);
|
|
58
|
+
if (fs <= 48) return Math.round(fs * 1.24);
|
|
59
|
+
if (fs <= 72) return Math.round(fs * 1.22);
|
|
60
|
+
if (fs <= 96) return Math.round(fs * 1.20);
|
|
61
|
+
return Math.round(fs * 1.18);
|
|
62
|
+
};
|
|
63
|
+
|
|
39
64
|
// Текст записки
|
|
40
65
|
this.textField = new PIXI.Text(this.content, {
|
|
41
|
-
fontFamily:
|
|
66
|
+
fontFamily: fontFamily,
|
|
42
67
|
fontSize: this.fontSize,
|
|
43
68
|
fill: this.textColor,
|
|
44
69
|
align: 'center',
|
|
70
|
+
letterSpacing: 0,
|
|
45
71
|
wordWrap: true,
|
|
46
|
-
|
|
47
|
-
|
|
72
|
+
breakWords: true,
|
|
73
|
+
wordWrapWidth: Math.max(1, Math.min(360, (this.width - 32))),
|
|
74
|
+
lineHeight: this._computeLineHeightPx(this.fontSize),
|
|
75
|
+
padding: 3,
|
|
76
|
+
trim: false,
|
|
48
77
|
resolution: (typeof window !== 'undefined' && window.devicePixelRatio) ? window.devicePixelRatio : 1
|
|
49
78
|
});
|
|
50
79
|
|
|
80
|
+
// Маска для обрезки текста по границам записки
|
|
81
|
+
this.textMask = new PIXI.Graphics();
|
|
82
|
+
this.container.addChild(this.textMask);
|
|
83
|
+
this.textField.mask = this.textMask;
|
|
84
|
+
|
|
51
85
|
this._redraw(); // Сначала рисуем фон
|
|
86
|
+
// Прячем текст до загрузки шрифта Caveat, чтобы не показывать системный
|
|
87
|
+
this.textField.visible = false;
|
|
52
88
|
this.container.addChild(this.textField); // Затем добавляем текст поверх
|
|
53
89
|
this._updateTextPosition();
|
|
90
|
+
// Если шрифт уже загружен — показываем сразу, иначе подождём загрузки
|
|
91
|
+
if (this._isFontLoaded(fontFamily, this.fontSize)) {
|
|
92
|
+
this.textField.visible = true;
|
|
93
|
+
} else {
|
|
94
|
+
this._ensureWebFontApplied(fontFamily, this.fontSize);
|
|
95
|
+
// Фолбэк на случай отсутствия Font Loading API — короткая задержка
|
|
96
|
+
try {
|
|
97
|
+
if (!(typeof document !== 'undefined' && document.fonts && typeof document.fonts.load === 'function')) {
|
|
98
|
+
setTimeout(() => { try { this.textField.visible = true; } catch (_) {} }, 300);
|
|
99
|
+
}
|
|
100
|
+
} catch (_) {}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Гарантируем применение web-font (например, Caveat) при первом создании
|
|
104
|
+
this._ensureWebFontApplied(fontFamily, this.fontSize);
|
|
54
105
|
|
|
55
106
|
// Отладочная информация
|
|
56
107
|
console.log('NoteObject created with content:', this.content);
|
|
@@ -63,6 +114,7 @@ export class NoteObject {
|
|
|
63
114
|
properties: {
|
|
64
115
|
content: this.content,
|
|
65
116
|
fontSize: this.fontSize,
|
|
117
|
+
fontFamily: fontFamily,
|
|
66
118
|
backgroundColor: this.backgroundColor,
|
|
67
119
|
borderColor: this.borderColor,
|
|
68
120
|
textColor: this.textColor,
|
|
@@ -73,14 +125,71 @@ export class NoteObject {
|
|
|
73
125
|
this._redraw();
|
|
74
126
|
}
|
|
75
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Возвращает видимую ширину текстового блока, согласованную с режимом редактирования
|
|
130
|
+
*/
|
|
131
|
+
_getVisibleTextWidth() {
|
|
132
|
+
const horizontalPadding = 16;
|
|
133
|
+
const contentWidth = Math.max(1, this.width - (horizontalPadding * 2));
|
|
134
|
+
return Math.max(1, Math.min(360, contentWidth));
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Проверяет, загружен ли указанный web-шрифт */
|
|
138
|
+
_isFontLoaded(fontFamily, fontSizePx) {
|
|
139
|
+
try {
|
|
140
|
+
if (typeof document === 'undefined' || !document.fonts || typeof document.fonts.check !== 'function') return false;
|
|
141
|
+
const primary = String(fontFamily || '').split(',')[0].trim().replace(/^['"]|['"]$/g, '') || 'Caveat';
|
|
142
|
+
const size = Math.max(1, Number(fontSizePx) || 32);
|
|
143
|
+
const spec = `normal ${size}px ${primary}`;
|
|
144
|
+
return document.fonts.check(spec);
|
|
145
|
+
} catch (_) {
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* Подгоняет размер шрифта так, чтобы текст умещался внутри записки
|
|
152
|
+
*/
|
|
153
|
+
_fitTextToBounds() {
|
|
154
|
+
if (!this.textField) return;
|
|
155
|
+
const maxWidth = this._getVisibleTextWidth();
|
|
156
|
+
const verticalPadding = 16;
|
|
157
|
+
const maxHeight = Math.max(1, this.height - (verticalPadding * 2));
|
|
158
|
+
|
|
159
|
+
// Базовые установки стиля перед измерением
|
|
160
|
+
this.textField.style.wordWrap = true;
|
|
161
|
+
this.textField.style.breakWords = true;
|
|
162
|
+
this.textField.style.wordWrapWidth = maxWidth;
|
|
163
|
+
|
|
164
|
+
// Начинаем с желаемого размера шрифта
|
|
165
|
+
let displayFontSize = Math.max(1, Number(this.fontSize) || 32);
|
|
166
|
+
const minFontSize = 8;
|
|
167
|
+
let safety = 0;
|
|
168
|
+
const maxIterations = 64;
|
|
169
|
+
|
|
170
|
+
while (safety < maxIterations) {
|
|
171
|
+
this.textField.style.fontSize = displayFontSize;
|
|
172
|
+
this.textField.style.lineHeight = this._computeLineHeightPx(displayFontSize);
|
|
173
|
+
this.textField.updateText();
|
|
174
|
+
const needsShrink = this.textField.height > maxHeight;
|
|
175
|
+
if (!needsShrink || displayFontSize <= minFontSize) break;
|
|
176
|
+
displayFontSize = Math.max(minFontSize, displayFontSize - 1);
|
|
177
|
+
safety++;
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
76
181
|
getPixi() {
|
|
77
182
|
return this.container;
|
|
78
183
|
}
|
|
79
184
|
|
|
80
185
|
updateSize(size) {
|
|
81
186
|
if (!size) return;
|
|
82
|
-
|
|
83
|
-
|
|
187
|
+
let w = Math.max(80, size.width || this.width);
|
|
188
|
+
let h = Math.max(60, size.height || this.height);
|
|
189
|
+
// Держим квадрат
|
|
190
|
+
const side = Math.max(w, h);
|
|
191
|
+
this.width = side;
|
|
192
|
+
this.height = side;
|
|
84
193
|
|
|
85
194
|
this._redraw();
|
|
86
195
|
this._updateTextPosition();
|
|
@@ -98,8 +207,10 @@ export class NoteObject {
|
|
|
98
207
|
|
|
99
208
|
setContent(content) {
|
|
100
209
|
this.content = content || '';
|
|
210
|
+
if (this.textField) this.textField.visible = false;
|
|
101
211
|
this.textField.text = this.content;
|
|
102
212
|
this._updateTextPosition();
|
|
213
|
+
if (this.textField) this.textField.visible = true;
|
|
103
214
|
if (this.container && this.container._mb) {
|
|
104
215
|
this.container._mb.properties = {
|
|
105
216
|
...(this.container._mb.properties || {}),
|
|
@@ -139,7 +250,22 @@ export class NoteObject {
|
|
|
139
250
|
if (typeof fontSize === 'number') {
|
|
140
251
|
this.fontSize = fontSize;
|
|
141
252
|
this.textField.style.fontSize = fontSize;
|
|
142
|
-
|
|
253
|
+
// Согласуем с HTML-слоем
|
|
254
|
+
this.textField.style.lineHeight = this._computeLineHeightPx(fontSize);
|
|
255
|
+
this.textField.style.padding = 3;
|
|
256
|
+
this.textField.style.trim = false;
|
|
257
|
+
this.textField.style.letterSpacing = 0;
|
|
258
|
+
}
|
|
259
|
+
if (typeof arguments[0]?.fontFamily === 'string') {
|
|
260
|
+
const ff = arguments[0].fontFamily;
|
|
261
|
+
this.textField.style.fontFamily = ff;
|
|
262
|
+
if (this.container && this.container._mb) {
|
|
263
|
+
this.container._mb.properties = {
|
|
264
|
+
...(this.container._mb.properties || {}),
|
|
265
|
+
fontFamily: ff
|
|
266
|
+
};
|
|
267
|
+
}
|
|
268
|
+
this._ensureWebFontApplied(ff, this.fontSize);
|
|
143
269
|
}
|
|
144
270
|
if (typeof backgroundColor === 'number') this.backgroundColor = backgroundColor;
|
|
145
271
|
if (typeof borderColor === 'number') this.borderColor = borderColor;
|
|
@@ -162,6 +288,27 @@ export class NoteObject {
|
|
|
162
288
|
this._updateTextPosition();
|
|
163
289
|
}
|
|
164
290
|
|
|
291
|
+
/**
|
|
292
|
+
* Дожидается загрузки веб-шрифта и обновляет PIXI.Text, чтобы применились корректные метрики
|
|
293
|
+
*/
|
|
294
|
+
_ensureWebFontApplied(fontFamily, fontSizePx) {
|
|
295
|
+
try {
|
|
296
|
+
if (typeof document === 'undefined' || !document.fonts || !document.fonts.load) return;
|
|
297
|
+
const primary = String(fontFamily || '').split(',')[0].trim().replace(/^['"]|['"]$/g, '') || 'Caveat';
|
|
298
|
+
const size = Math.max(1, Number(fontSizePx) || 32);
|
|
299
|
+
const spec = `normal ${size}px ${primary}`;
|
|
300
|
+
document.fonts.load(spec).then(() => {
|
|
301
|
+
// Обновляем текст после загрузки шрифта и сразу подгоняем без мерцания
|
|
302
|
+
try {
|
|
303
|
+
if (this.textField) this.textField.visible = false;
|
|
304
|
+
this.textField.style.fontFamily = fontFamily;
|
|
305
|
+
this._updateTextPosition();
|
|
306
|
+
if (this.textField) this.textField.visible = true;
|
|
307
|
+
} catch (_) {}
|
|
308
|
+
}).catch(() => {});
|
|
309
|
+
} catch (_) {}
|
|
310
|
+
}
|
|
311
|
+
|
|
165
312
|
_redraw() {
|
|
166
313
|
const g = this.graphics;
|
|
167
314
|
const w = this.width;
|
|
@@ -169,29 +316,50 @@ export class NoteObject {
|
|
|
169
316
|
|
|
170
317
|
g.clear();
|
|
171
318
|
|
|
172
|
-
//
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
319
|
+
// Левая и правая тень (узкие полосы снизу)
|
|
320
|
+
const shH = Math.max(8, Math.round(h * 0.05)); // толще тень (~5% высоты)
|
|
321
|
+
const shW = Math.max(24, Math.round(w * 0.45)); // шире тень (~45% ширины)
|
|
322
|
+
const bottom = Math.max(8, Math.round(h * 0.03)) + 10; // отступ снизу ~10
|
|
323
|
+
|
|
324
|
+
const drawShadow = (g) => {
|
|
325
|
+
g.clear();
|
|
326
|
+
g.beginFill(0x000000, 1);
|
|
327
|
+
g.drawRoundedRect(0, 0, shW, shH, shH / 2);
|
|
328
|
+
g.endFill();
|
|
329
|
+
};
|
|
330
|
+
drawShadow(this.shadowLeft);
|
|
331
|
+
drawShadow(this.shadowRight);
|
|
332
|
+
|
|
333
|
+
// Обновляем маску текста под новые размеры
|
|
334
|
+
const pad = 16;
|
|
335
|
+
this.textMask.clear();
|
|
336
|
+
this.textMask.beginFill(0x000000, 1);
|
|
337
|
+
this.textMask.drawRect(pad, pad, Math.max(1, w - pad * 2), Math.max(1, h - pad * 2));
|
|
338
|
+
this.textMask.endFill();
|
|
339
|
+
|
|
340
|
+
// Базовые позиции как в CSS: left:15px и right:15px; bottom:10px
|
|
341
|
+
this.shadowLeft.x = 15;
|
|
342
|
+
this.shadowLeft.y = h - shH - 10;
|
|
343
|
+
this.shadowLeft.skew = new PIXI.ObservablePoint(() => {}, null, -5 * Math.PI / 180, 0);
|
|
344
|
+
this.shadowLeft.rotation = -5 * Math.PI / 180;
|
|
345
|
+
|
|
346
|
+
this.shadowRight.x = w - shW - 15;
|
|
347
|
+
this.shadowRight.y = h - shH - 10;
|
|
348
|
+
this.shadowRight.skew = new PIXI.ObservablePoint(() => {}, null, 5 * Math.PI / 180, 0);
|
|
349
|
+
this.shadowRight.rotation = 5 * Math.PI / 180;
|
|
350
|
+
|
|
351
|
+
this.shadowLayer.alpha = 0.7; // темнее
|
|
182
352
|
|
|
183
|
-
//
|
|
184
|
-
|
|
185
|
-
g.
|
|
353
|
+
// Основной фон записки — как .box: белый с небольшим радиусом
|
|
354
|
+
const boxBg = (typeof this.backgroundColor === 'number') ? this.backgroundColor : 0xFFFFFF;
|
|
355
|
+
g.beginFill(boxBg, 1);
|
|
356
|
+
g.drawRoundedRect(0, 0, w, h, 2);
|
|
186
357
|
g.endFill();
|
|
187
358
|
|
|
188
|
-
// Линии
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
g.moveTo(8, y);
|
|
193
|
-
g.lineTo(w - 8, y);
|
|
194
|
-
}
|
|
359
|
+
// Линии внутри записки убраны по требованию дизайна
|
|
360
|
+
|
|
361
|
+
// pivot контейнера строго по центру, чтобы ядро корректно вычисляло левый-верх
|
|
362
|
+
this.container.pivot.set(w / 2, h / 2);
|
|
195
363
|
|
|
196
364
|
// Устанавливаем hit area для контейнера
|
|
197
365
|
this.container.hitArea = new PIXI.Rectangle(0, 0, w, h);
|
|
@@ -204,24 +372,44 @@ export class NoteObject {
|
|
|
204
372
|
point.y >= bounds.y &&
|
|
205
373
|
point.y <= bounds.y + bounds.height;
|
|
206
374
|
};
|
|
375
|
+
|
|
376
|
+
// Hover-эффект: ослабляем короб тени и сдвигаем ближе к центру (как в CSS)
|
|
377
|
+
this.container.eventMode = 'static';
|
|
378
|
+
this.container.on('pointerover', () => {
|
|
379
|
+
this.shadowLayer.alpha = 0.55;
|
|
380
|
+
this.shadowLeft.x = 5;
|
|
381
|
+
this.shadowRight.x = w - shW - 5;
|
|
382
|
+
this.shadowLeft.rotation = 0;
|
|
383
|
+
this.shadowRight.rotation = 0;
|
|
384
|
+
});
|
|
385
|
+
this.container.on('pointerout', () => {
|
|
386
|
+
this.shadowLayer.alpha = 0.7;
|
|
387
|
+
this.shadowLeft.x = 15;
|
|
388
|
+
this.shadowRight.x = w - shW - 15;
|
|
389
|
+
this.shadowLeft.rotation = -5 * Math.PI / 180;
|
|
390
|
+
this.shadowRight.rotation = 5 * Math.PI / 180;
|
|
391
|
+
});
|
|
207
392
|
}
|
|
208
393
|
|
|
209
394
|
_updateTextPosition() {
|
|
210
395
|
if (!this.textField) return;
|
|
211
396
|
|
|
212
|
-
// Обновляем стиль текста
|
|
213
|
-
this.textField.style.wordWrapWidth = this.
|
|
214
|
-
|
|
215
|
-
|
|
397
|
+
// Обновляем стиль текста согласно ограничениям редактора
|
|
398
|
+
this.textField.style.wordWrapWidth = this._getVisibleTextWidth();
|
|
399
|
+
this.textField.style.wordWrap = true;
|
|
400
|
+
this.textField.style.breakWords = true;
|
|
401
|
+
|
|
402
|
+
// Подгоняем размер шрифта под доступные границы
|
|
403
|
+
this._fitTextToBounds();
|
|
404
|
+
|
|
405
|
+
// Обновляем текст после подгонки
|
|
216
406
|
this.textField.updateText();
|
|
217
407
|
|
|
218
|
-
// Центрируем текст по
|
|
408
|
+
// Центрируем текст по центру заметки
|
|
219
409
|
const centerX = this.width / 2;
|
|
220
|
-
const
|
|
221
|
-
|
|
222
|
-
// Используем anchor для центрирования
|
|
223
|
-
this.textField.anchor.set(0.5, 0);
|
|
410
|
+
const centerY = this.height / 2;
|
|
411
|
+
this.textField.anchor.set(0.5, 0.5);
|
|
224
412
|
this.textField.x = centerX;
|
|
225
|
-
this.textField.y =
|
|
413
|
+
this.textField.y = centerY;
|
|
226
414
|
}
|
|
227
415
|
}
|
|
@@ -58,17 +58,18 @@ export class ShapeObject {
|
|
|
58
58
|
/** Перерисовать с сохранением трансформаций */
|
|
59
59
|
_redrawPreserveTransform(width, height, color, kind, cornerRadius) {
|
|
60
60
|
const g = this.graphics;
|
|
61
|
-
|
|
62
|
-
const
|
|
61
|
+
// Сохраняем текущий центр и поворот
|
|
62
|
+
const centerX = g.x;
|
|
63
|
+
const centerY = g.y;
|
|
63
64
|
const rot = g.rotation || 0;
|
|
64
|
-
const pivotX = g.pivot?.x || 0;
|
|
65
|
-
const pivotY = g.pivot?.y || 0;
|
|
66
65
|
|
|
67
66
|
this._draw(width, height, color, kind, cornerRadius);
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
g.
|
|
71
|
-
|
|
67
|
+
// ВАЖНО: для согласованности с ядром (позиция — левый-верх, PIXI — центр)
|
|
68
|
+
// pivot должен всегда быть в центре объекта (w/2, h/2)
|
|
69
|
+
g.pivot.set(width / 2, height / 2);
|
|
70
|
+
// Восстанавливаем центр
|
|
71
|
+
g.x = centerX;
|
|
72
|
+
g.y = centerY;
|
|
72
73
|
g.rotation = rot;
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -91,16 +91,7 @@ export class TextObject {
|
|
|
91
91
|
* Для TextObject фактическая логика скрытия/показа обрабатывается в HtmlTextLayer
|
|
92
92
|
*/
|
|
93
93
|
hideText() {
|
|
94
|
-
//
|
|
95
|
-
// Эмитим событие для скрытия текста
|
|
96
|
-
if (this.rect && this.rect._mb && this.rect._mb.objectId) {
|
|
97
|
-
// Используем EventBus через core, если доступен
|
|
98
|
-
if (typeof window !== 'undefined' && window.moodboardEventBus) {
|
|
99
|
-
window.moodboardEventBus.emit('tool:hide:object:text', {
|
|
100
|
-
objectId: this.rect._mb.objectId
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
}
|
|
94
|
+
// Ничего не делаем: скрытие текста обрабатывается HtmlTextLayer по событию
|
|
104
95
|
}
|
|
105
96
|
|
|
106
97
|
/**
|
|
@@ -108,16 +99,7 @@ export class TextObject {
|
|
|
108
99
|
* Для TextObject фактическая логика скрытия/показа обрабатывается в HtmlTextLayer
|
|
109
100
|
*/
|
|
110
101
|
showText() {
|
|
111
|
-
//
|
|
112
|
-
// Эмитим событие для показа текста
|
|
113
|
-
if (this.rect && this.rect._mb && this.rect._mb.objectId) {
|
|
114
|
-
// Используем EventBus через core, если доступен
|
|
115
|
-
if (typeof window !== 'undefined' && window.moodboardEventBus) {
|
|
116
|
-
window.moodboardEventBus.emit('tool:show:object:text', {
|
|
117
|
-
objectId: this.rect._mb.objectId
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
}
|
|
102
|
+
// Ничего не делаем: показ текста обрабатывается HtmlTextLayer по событию
|
|
121
103
|
}
|
|
122
104
|
}
|
|
123
105
|
|
|
@@ -15,11 +15,11 @@ export class BoardService {
|
|
|
15
15
|
const canvasSize = (this._getCanvasSize?.() || {});
|
|
16
16
|
this.grid = GridFactory.createGrid('line', {
|
|
17
17
|
enabled: true,
|
|
18
|
-
size:
|
|
18
|
+
size: 32,
|
|
19
19
|
width: canvasSize.width || 800,
|
|
20
20
|
height: canvasSize.height || 600,
|
|
21
|
-
color:
|
|
22
|
-
opacity: 0.
|
|
21
|
+
color: 0x6a6aff,
|
|
22
|
+
opacity: 0.4
|
|
23
23
|
});
|
|
24
24
|
this.grid.updateVisual();
|
|
25
25
|
this.pixi.setGrid(this.grid);
|
|
@@ -7,15 +7,76 @@ export class FrameService {
|
|
|
7
7
|
this.state = state;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
+
_forceFramesBelow() {
|
|
11
|
+
const world = this.pixi?.worldLayer || this.pixi?.app?.stage;
|
|
12
|
+
if (world) world.sortableChildren = true;
|
|
13
|
+
let z = 0;
|
|
14
|
+
for (const o of this.state.state.objects || []) {
|
|
15
|
+
const pix = this.pixi.objects.get(o.id);
|
|
16
|
+
if (!pix) continue;
|
|
17
|
+
if (o.type === 'frame') {
|
|
18
|
+
pix.zIndex = -100000;
|
|
19
|
+
} else {
|
|
20
|
+
pix.zIndex = z++;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
_attachIntersectingObjectsToFrame(frameId) {
|
|
26
|
+
const framePixi = this.pixi.objects.get(frameId);
|
|
27
|
+
if (!framePixi || !framePixi.getBounds) return false;
|
|
28
|
+
const fb = framePixi.getBounds();
|
|
29
|
+
const frameRect = { x: fb.x, y: fb.y, w: fb.width, h: fb.height };
|
|
30
|
+
let changed = false;
|
|
31
|
+
for (const obj of this.state.state.objects || []) {
|
|
32
|
+
if (!obj || obj.id === frameId) continue;
|
|
33
|
+
if (obj.type === 'frame') continue;
|
|
34
|
+
const pix = this.pixi.objects.get(obj.id);
|
|
35
|
+
if (!pix || !pix.getBounds) continue;
|
|
36
|
+
const ob = pix.getBounds();
|
|
37
|
+
const objRect = { x: ob.x, y: ob.y, w: ob.width, h: ob.height };
|
|
38
|
+
// Пересечение прямоугольников (экраные координаты PIXI)
|
|
39
|
+
const intersects = !(objRect.x > frameRect.x + frameRect.w ||
|
|
40
|
+
(objRect.x + objRect.w) < frameRect.x ||
|
|
41
|
+
objRect.y > frameRect.y + frameRect.h ||
|
|
42
|
+
(objRect.y + objRect.h) < frameRect.y);
|
|
43
|
+
if (intersects) {
|
|
44
|
+
obj.properties = obj.properties || {};
|
|
45
|
+
obj.properties.frameId = frameId;
|
|
46
|
+
changed = true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return changed;
|
|
50
|
+
}
|
|
51
|
+
|
|
10
52
|
attach() {
|
|
53
|
+
// Автоприкрепление объектов при создании произвольного фрейма
|
|
54
|
+
this.eventBus.on(Events.Object.Created, ({ objectId, objectData }) => {
|
|
55
|
+
try {
|
|
56
|
+
if (!objectData || objectData.type !== 'frame') return;
|
|
57
|
+
const isArbitrary = (objectData.properties && objectData.properties.lockedAspect === false)
|
|
58
|
+
|| (objectData.properties && objectData.properties.title === 'Произвольный')
|
|
59
|
+
|| (objectData.properties && objectData.properties.isArbitrary === true);
|
|
60
|
+
if (!isArbitrary) return;
|
|
61
|
+
// Используем фактические bounds PIXI для надёжной проверки попадания
|
|
62
|
+
const changed = this._attachIntersectingObjectsToFrame(objectId);
|
|
63
|
+
if (changed) this.state.markDirty();
|
|
64
|
+
// Принудительно держим фреймы под объектами
|
|
65
|
+
this._forceFramesBelow();
|
|
66
|
+
// И оповестим общий менеджер на всякий случай
|
|
67
|
+
this.eventBus.emit(Events.Object.Reordered, { reason: 'attach_arbitrary_frame_children' });
|
|
68
|
+
} catch (_) { /* no-op */ }
|
|
69
|
+
});
|
|
70
|
+
|
|
11
71
|
// Визуал подсветки при drag над фреймом и перенос детей на drag
|
|
12
72
|
this.eventBus.on(Events.Tool.DragStart, (data) => {
|
|
13
73
|
const moved = this.state.state.objects.find(o => o.id === data.object);
|
|
14
74
|
if (moved && moved.type === 'frame') {
|
|
15
75
|
// Серый фон
|
|
16
76
|
this.pixi.setFrameFill(moved.id, moved.width, moved.height, 0xEEEEEE);
|
|
17
|
-
// Cнимок стартовых позиций
|
|
18
|
-
|
|
77
|
+
// Cнимок стартовых позиций по центру PIXI
|
|
78
|
+
const fp = this.pixi.objects.get(moved.id);
|
|
79
|
+
this._frameDragFrameStart = { x: fp?.x || 0, y: fp?.y || 0 };
|
|
19
80
|
const attachments = this._getFrameChildren(moved.id);
|
|
20
81
|
this._frameDragChildStart = new Map();
|
|
21
82
|
for (const childId of attachments) {
|
|
@@ -30,17 +91,37 @@ export class FrameService {
|
|
|
30
91
|
if (!moved) return;
|
|
31
92
|
if (moved.type === 'frame') {
|
|
32
93
|
const attachments = this._getFrameChildren(moved.id);
|
|
33
|
-
|
|
34
|
-
const
|
|
35
|
-
const
|
|
94
|
+
// ВАЖНО: считаем сдвиг по центру PIXI, чтобы не смешивать центр и левый-верх
|
|
95
|
+
const p = this.pixi.objects.get(moved.id);
|
|
96
|
+
const start = this._frameDragFrameStart || { x: p?.x || 0, y: p?.y || 0 };
|
|
97
|
+
const dx = (p?.x || 0) - start.x;
|
|
98
|
+
const dy = (p?.y || 0) - start.y;
|
|
36
99
|
for (const childId of attachments) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
100
|
+
let startPos = this._frameDragChildStart?.get(childId);
|
|
101
|
+
const childPixi = this.pixi.objects.get(childId);
|
|
102
|
+
if (!startPos) {
|
|
103
|
+
// Ребёнок мог появиться после начала drag
|
|
104
|
+
if (childPixi) {
|
|
105
|
+
startPos = { x: childPixi.x - dx, y: childPixi.y - dy };
|
|
106
|
+
this._frameDragChildStart = this._frameDragChildStart || new Map();
|
|
107
|
+
this._frameDragChildStart.set(childId, startPos);
|
|
108
|
+
} else {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
const newCenterX = startPos.x + dx;
|
|
113
|
+
const newCenterY = startPos.y + dy;
|
|
114
|
+
if (childPixi) { childPixi.x = newCenterX; childPixi.y = newCenterY; }
|
|
41
115
|
const stObj = this.state.state.objects.find(o => o.id === childId);
|
|
42
|
-
if (stObj) {
|
|
116
|
+
if (stObj) {
|
|
117
|
+
const halfW = childPixi ? (childPixi.width || 0) / 2 : 0;
|
|
118
|
+
const halfH = childPixi ? (childPixi.height || 0) / 2 : 0;
|
|
119
|
+
stObj.position.x = newCenterX - halfW;
|
|
120
|
+
stObj.position.y = newCenterY - halfH;
|
|
121
|
+
}
|
|
43
122
|
}
|
|
123
|
+
// Во время перетаскивания тоже гарантируем порядок
|
|
124
|
+
this._forceFramesBelow();
|
|
44
125
|
} else {
|
|
45
126
|
// Hover-эффект: подсветка фрейма, если центр объекта внутри
|
|
46
127
|
const centerX = moved.position.x + (moved.width || 0) / 2;
|
|
@@ -59,12 +140,10 @@ export class FrameService {
|
|
|
59
140
|
}
|
|
60
141
|
}
|
|
61
142
|
if (hoverId !== this._frameHoverId) {
|
|
62
|
-
// Снять подсветку с предыдущего
|
|
63
143
|
if (this._frameHoverId) {
|
|
64
144
|
const prev = frames.find(fr => fr.id === this._frameHoverId);
|
|
65
145
|
if (prev) this.pixi.setFrameFill(prev.id, prev.width, prev.height, 0xFFFFFF);
|
|
66
146
|
}
|
|
67
|
-
// Включить подсветку нового
|
|
68
147
|
if (hoverId) {
|
|
69
148
|
const cur = frames.find(fr => fr.id === hoverId);
|
|
70
149
|
if (cur) this.pixi.setFrameFill(cur.id, cur.width, cur.height, 0xEEEEEE);
|
|
@@ -77,14 +156,11 @@ export class FrameService {
|
|
|
77
156
|
this.eventBus.on(Events.Tool.DragEnd, (data) => {
|
|
78
157
|
const movedObj = this.state.state.objects.find(o => o.id === data.object);
|
|
79
158
|
if (!movedObj) return;
|
|
80
|
-
// Сброс заливки
|
|
81
159
|
if (movedObj.type === 'frame') {
|
|
82
160
|
this.pixi.setFrameFill(movedObj.id, movedObj.width, movedObj.height, 0xFFFFFF);
|
|
83
161
|
}
|
|
84
|
-
|
|
85
|
-
// Автопривязка/отвязка объекта к фрейму после перемещения
|
|
86
162
|
this._recomputeFrameAttachment(movedObj.id);
|
|
87
|
-
|
|
163
|
+
this._forceFramesBelow();
|
|
88
164
|
this._frameDragFrameStart = null;
|
|
89
165
|
this._frameDragChildStart = null;
|
|
90
166
|
if (this._frameHoverId) {
|
|
@@ -108,7 +184,7 @@ export class FrameService {
|
|
|
108
184
|
_recomputeFrameAttachment(objectId) {
|
|
109
185
|
const obj = (this.state.state.objects || []).find(o => o.id === objectId);
|
|
110
186
|
if (!obj) return;
|
|
111
|
-
if (obj.type === 'frame') return;
|
|
187
|
+
if (obj.type === 'frame') return;
|
|
112
188
|
const center = {
|
|
113
189
|
x: obj.position.x + (obj.width || 0) / 2,
|
|
114
190
|
y: obj.position.y + (obj.height || 0) / 2
|
|
@@ -131,6 +207,8 @@ export class FrameService {
|
|
|
131
207
|
obj.properties = obj.properties || {};
|
|
132
208
|
obj.properties.frameId = newFrameId || undefined;
|
|
133
209
|
this.state.markDirty();
|
|
210
|
+
this._forceFramesBelow();
|
|
211
|
+
this.eventBus.emit(Events.Object.Reordered, { reason: 'recompute_frame_attachment' });
|
|
134
212
|
}
|
|
135
213
|
}
|
|
136
214
|
}
|
|
@@ -9,11 +9,22 @@ export class ZoomPanController {
|
|
|
9
9
|
attach() {
|
|
10
10
|
// Масштабирование колесом — глобально отрабатываем Ctrl+Wheel
|
|
11
11
|
this.eventBus.on(Events.Tool.WheelZoom, ({ x, y, delta }) => {
|
|
12
|
-
|
|
12
|
+
// Дискретный шаг зума 10%
|
|
13
13
|
const world = this.pixi.worldLayer || this.pixi.app.stage;
|
|
14
14
|
const oldScale = world.scale.x || 1;
|
|
15
|
-
const
|
|
16
|
-
|
|
15
|
+
const oldPercent = Math.round(oldScale * 100);
|
|
16
|
+
let targetPercent;
|
|
17
|
+
if (delta < 0) {
|
|
18
|
+
// Zoom in: к ближайшему следующему кратному 10 плюс шаг
|
|
19
|
+
targetPercent = Math.min(500, Math.floor(oldPercent / 10) * 10 + 10);
|
|
20
|
+
} else if (delta > 0) {
|
|
21
|
+
// Zoom out: к ближайшему предыдущему кратному 10 минус шаг
|
|
22
|
+
targetPercent = Math.max(10, Math.ceil(oldPercent / 10) * 10 - 10);
|
|
23
|
+
} else {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const newScale = Math.max(0.1, Math.min(5, targetPercent / 100));
|
|
27
|
+
if (Math.abs(newScale - oldScale) < 0.0001) return;
|
|
17
28
|
// Вычисляем мировые координаты точки под курсором до изменения скейла
|
|
18
29
|
const worldX = (x - world.x) / oldScale;
|
|
19
30
|
const worldY = (y - world.y) / oldScale;
|
package/src/tools/BaseTool.js
CHANGED
|
@@ -44,7 +44,12 @@ export class BaseTool {
|
|
|
44
44
|
*/
|
|
45
45
|
setCursor() {
|
|
46
46
|
if (typeof document !== 'undefined' && document.body) {
|
|
47
|
-
|
|
47
|
+
// Для 'default' не ставим инлайн-стиль, чтобы сработал глобальный CSS-курсор
|
|
48
|
+
if (!this.cursor || this.cursor === 'default') {
|
|
49
|
+
document.body.style.cursor = '';
|
|
50
|
+
} else {
|
|
51
|
+
document.body.style.cursor = this.cursor;
|
|
52
|
+
}
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
55
|
|