@sequent-org/moodboard 1.1.0 → 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.
Files changed (336) hide show
  1. package/package.json +2 -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
  3. 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
  4. 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
  5. 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
  6. 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
  7. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f446.png +0 -0
  8. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f447.png +0 -0
  9. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f448.png +0 -0
  10. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f449.png +0 -0
  11. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44a.png +0 -0
  12. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44b.png +0 -0
  13. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f44c.png +0 -0
  14. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f450.png +0 -0
  15. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f4aa.png +0 -0
  16. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f590.png +0 -0
  17. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f596.png +0 -0
  18. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f64c.png +0 -0
  19. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/1f64f.png +0 -0
  20. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/261d.png +0 -0
  21. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270a.png +0 -0
  22. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270b.png +0 -0
  23. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270c.png +0 -0
  24. package/src/assets/emodji//320/226/320/265/321/201/321/202/321/213/270d.png +0 -0
  25. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f638.png +0 -0
  26. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f639.png +0 -0
  27. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63a.png +0 -0
  28. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63b.png +0 -0
  29. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63c.png +0 -0
  30. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63d.png +0 -0
  31. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63e.png +0 -0
  32. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f63f.png +0 -0
  33. package/src/assets/emodji//320/232/320/276/321/202/320/270/320/272/320/270/1f640.png +0 -0
  34. 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
  35. 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
  36. 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
  37. 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
  38. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f440.png +0 -0
  39. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f441.png +0 -0
  40. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f499.png +0 -0
  41. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a1.png +0 -0
  42. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a3.png +0 -0
  43. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4a9.png +0 -0
  44. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4ac.png +0 -0
  45. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/1f4af.png +0 -0
  46. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/203c.png +0 -0
  47. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/26d4.png +0 -0
  48. package/src/assets/emodji//320/240/320/260/320/267/320/275/320/276/320/265/2764.png +0 -0
  49. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f600.png +0 -0
  50. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f601.png +0 -0
  51. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f602.png +0 -0
  52. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f603.png +0 -0
  53. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f604.png +0 -0
  54. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f605.png +0 -0
  55. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f606.png +0 -0
  56. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f607.png +0 -0
  57. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f609.png +0 -0
  58. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60a.png +0 -0
  59. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60b.png +0 -0
  60. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60c.png +0 -0
  61. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60d.png +0 -0
  62. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60e.png +0 -0
  63. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f60f.png +0 -0
  64. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f610.png +0 -0
  65. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f611.png +0 -0
  66. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f612.png +0 -0
  67. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f613.png +0 -0
  68. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f614.png +0 -0
  69. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f615.png +0 -0
  70. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f616.png +0 -0
  71. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f617.png +0 -0
  72. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f618.png +0 -0
  73. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f619.png +0 -0
  74. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61a.png +0 -0
  75. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61b.png +0 -0
  76. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61c.png +0 -0
  77. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61d.png +0 -0
  78. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61e.png +0 -0
  79. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f61f.png +0 -0
  80. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f620.png +0 -0
  81. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f621.png +0 -0
  82. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f622.png +0 -0
  83. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f623.png +0 -0
  84. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f624.png +0 -0
  85. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f625.png +0 -0
  86. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f626.png +0 -0
  87. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f627.png +0 -0
  88. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f628.png +0 -0
  89. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f629.png +0 -0
  90. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62a.png +0 -0
  91. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62b.png +0 -0
  92. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62c.png +0 -0
  93. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62d.png +0 -0
  94. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62e.png +0 -0
  95. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f62f.png +0 -0
  96. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f630.png +0 -0
  97. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f631.png +0 -0
  98. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f632.png +0 -0
  99. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f633.png +0 -0
  100. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f635.png +0 -0
  101. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f636.png +0 -0
  102. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f641.png +0 -0
  103. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/1f642.png +0 -0
  104. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/2639.png +0 -0
  105. package/src/assets/emodji//320/241/320/274/320/260/320/271/320/273/320/270/320/272/320/270/263a.png +0 -0
  106. package/src/assets/fonts/amatic-sc/AmaticSC-Bold.ttf +0 -0
  107. package/src/assets/fonts/amatic-sc/AmaticSC-Regular.ttf +0 -0
  108. package/src/assets/fonts/caveat/Caveat-Bold.ttf +0 -0
  109. package/src/assets/fonts/caveat/Caveat-Medium.ttf +0 -0
  110. package/src/assets/fonts/caveat/Caveat-Regular.ttf +0 -0
  111. package/src/assets/fonts/caveat/Caveat-SemiBold.ttf +0 -0
  112. package/src/assets/fonts/caveat/Caveat-VariableFont_wght.ttf +0 -0
  113. package/src/assets/fonts/great-vibes/GreatVibes-Regular.ttf +0 -0
  114. package/src/assets/fonts/lobster/Lobster-Regular.ttf +0 -0
  115. package/src/assets/fonts/noto-serif/NotoSerif-Black.ttf +0 -0
  116. package/src/assets/fonts/noto-serif/NotoSerif-BlackItalic.ttf +0 -0
  117. package/src/assets/fonts/noto-serif/NotoSerif-Bold.ttf +0 -0
  118. package/src/assets/fonts/noto-serif/NotoSerif-BoldItalic.ttf +0 -0
  119. package/src/assets/fonts/noto-serif/NotoSerif-ExtraBold.ttf +0 -0
  120. package/src/assets/fonts/noto-serif/NotoSerif-ExtraBoldItalic.ttf +0 -0
  121. package/src/assets/fonts/noto-serif/NotoSerif-ExtraLight.ttf +0 -0
  122. package/src/assets/fonts/noto-serif/NotoSerif-ExtraLightItalic.ttf +0 -0
  123. package/src/assets/fonts/noto-serif/NotoSerif-Italic-VariableFont_wdth,wght.ttf +0 -0
  124. package/src/assets/fonts/noto-serif/NotoSerif-Italic.ttf +0 -0
  125. package/src/assets/fonts/noto-serif/NotoSerif-Light.ttf +0 -0
  126. package/src/assets/fonts/noto-serif/NotoSerif-LightItalic.ttf +0 -0
  127. package/src/assets/fonts/noto-serif/NotoSerif-Medium.ttf +0 -0
  128. package/src/assets/fonts/noto-serif/NotoSerif-MediumItalic.ttf +0 -0
  129. package/src/assets/fonts/noto-serif/NotoSerif-Regular.ttf +0 -0
  130. package/src/assets/fonts/noto-serif/NotoSerif-SemiBold.ttf +0 -0
  131. package/src/assets/fonts/noto-serif/NotoSerif-SemiBoldItalic.ttf +0 -0
  132. package/src/assets/fonts/noto-serif/NotoSerif-Thin.ttf +0 -0
  133. package/src/assets/fonts/noto-serif/NotoSerif-ThinItalic.ttf +0 -0
  134. package/src/assets/fonts/noto-serif/NotoSerif-VariableFont_wdth,wght.ttf +0 -0
  135. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Black.ttf +0 -0
  136. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-BlackItalic.ttf +0 -0
  137. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Bold.ttf +0 -0
  138. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-BoldItalic.ttf +0 -0
  139. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraBold.ttf +0 -0
  140. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraBoldItalic.ttf +0 -0
  141. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraLight.ttf +0 -0
  142. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ExtraLightItalic.ttf +0 -0
  143. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Italic.ttf +0 -0
  144. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Light.ttf +0 -0
  145. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-LightItalic.ttf +0 -0
  146. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Medium.ttf +0 -0
  147. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-MediumItalic.ttf +0 -0
  148. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Regular.ttf +0 -0
  149. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-SemiBold.ttf +0 -0
  150. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-SemiBoldItalic.ttf +0 -0
  151. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-Thin.ttf +0 -0
  152. package/src/assets/fonts/noto-serif/NotoSerif_Condensed-ThinItalic.ttf +0 -0
  153. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Black.ttf +0 -0
  154. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-BlackItalic.ttf +0 -0
  155. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Bold.ttf +0 -0
  156. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-BoldItalic.ttf +0 -0
  157. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraBold.ttf +0 -0
  158. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraBoldItalic.ttf +0 -0
  159. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraLight.ttf +0 -0
  160. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ExtraLightItalic.ttf +0 -0
  161. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Italic.ttf +0 -0
  162. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Light.ttf +0 -0
  163. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-LightItalic.ttf +0 -0
  164. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Medium.ttf +0 -0
  165. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-MediumItalic.ttf +0 -0
  166. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Regular.ttf +0 -0
  167. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-SemiBold.ttf +0 -0
  168. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-SemiBoldItalic.ttf +0 -0
  169. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-Thin.ttf +0 -0
  170. package/src/assets/fonts/noto-serif/NotoSerif_ExtraCondensed-ThinItalic.ttf +0 -0
  171. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Black.ttf +0 -0
  172. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-BlackItalic.ttf +0 -0
  173. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Bold.ttf +0 -0
  174. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-BoldItalic.ttf +0 -0
  175. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraBold.ttf +0 -0
  176. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  177. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraLight.ttf +0 -0
  178. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ExtraLightItalic.ttf +0 -0
  179. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Italic.ttf +0 -0
  180. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Light.ttf +0 -0
  181. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-LightItalic.ttf +0 -0
  182. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Medium.ttf +0 -0
  183. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-MediumItalic.ttf +0 -0
  184. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Regular.ttf +0 -0
  185. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-SemiBold.ttf +0 -0
  186. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-SemiBoldItalic.ttf +0 -0
  187. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-Thin.ttf +0 -0
  188. package/src/assets/fonts/noto-serif/NotoSerif_SemiCondensed-ThinItalic.ttf +0 -0
  189. package/src/assets/fonts/oswald/Oswald-Bold.ttf +0 -0
  190. package/src/assets/fonts/oswald/Oswald-ExtraLight.ttf +0 -0
  191. package/src/assets/fonts/oswald/Oswald-Light.ttf +0 -0
  192. package/src/assets/fonts/oswald/Oswald-Medium.ttf +0 -0
  193. package/src/assets/fonts/oswald/Oswald-Regular.ttf +0 -0
  194. package/src/assets/fonts/oswald/Oswald-SemiBold.ttf +0 -0
  195. package/src/assets/fonts/oswald/Oswald-VariableFont_wght.ttf +0 -0
  196. package/src/assets/fonts/pacifico/Pacifico-Regular.ttf +0 -0
  197. package/src/assets/fonts/playfair/PlayfairDisplay-Black.ttf +0 -0
  198. package/src/assets/fonts/playfair/PlayfairDisplay-BlackItalic.ttf +0 -0
  199. package/src/assets/fonts/playfair/PlayfairDisplay-Bold.ttf +0 -0
  200. package/src/assets/fonts/playfair/PlayfairDisplay-BoldItalic.ttf +0 -0
  201. package/src/assets/fonts/playfair/PlayfairDisplay-ExtraBold.ttf +0 -0
  202. package/src/assets/fonts/playfair/PlayfairDisplay-ExtraBoldItalic.ttf +0 -0
  203. package/src/assets/fonts/playfair/PlayfairDisplay-Italic-VariableFont_wght.ttf +0 -0
  204. package/src/assets/fonts/playfair/PlayfairDisplay-Italic.ttf +0 -0
  205. package/src/assets/fonts/playfair/PlayfairDisplay-Medium.ttf +0 -0
  206. package/src/assets/fonts/playfair/PlayfairDisplay-MediumItalic.ttf +0 -0
  207. package/src/assets/fonts/playfair/PlayfairDisplay-Regular.ttf +0 -0
  208. package/src/assets/fonts/playfair/PlayfairDisplay-SemiBold.ttf +0 -0
  209. package/src/assets/fonts/playfair/PlayfairDisplay-SemiBoldItalic.ttf +0 -0
  210. package/src/assets/fonts/playfair/PlayfairDisplay-VariableFont_wght.ttf +0 -0
  211. package/src/assets/fonts/poiret-one/PoiretOne-Regular.ttf +0 -0
  212. package/src/assets/fonts/roboto/Roboto-Black.ttf +0 -0
  213. package/src/assets/fonts/roboto/Roboto-BlackItalic.ttf +0 -0
  214. package/src/assets/fonts/roboto/Roboto-Bold.ttf +0 -0
  215. package/src/assets/fonts/roboto/Roboto-BoldItalic.ttf +0 -0
  216. package/src/assets/fonts/roboto/Roboto-ExtraBold.ttf +0 -0
  217. package/src/assets/fonts/roboto/Roboto-ExtraBoldItalic.ttf +0 -0
  218. package/src/assets/fonts/roboto/Roboto-ExtraLight.ttf +0 -0
  219. package/src/assets/fonts/roboto/Roboto-ExtraLightItalic.ttf +0 -0
  220. package/src/assets/fonts/roboto/Roboto-Italic-VariableFont_wdth,wght.ttf +0 -0
  221. package/src/assets/fonts/roboto/Roboto-Italic.ttf +0 -0
  222. package/src/assets/fonts/roboto/Roboto-Light.ttf +0 -0
  223. package/src/assets/fonts/roboto/Roboto-LightItalic.ttf +0 -0
  224. package/src/assets/fonts/roboto/Roboto-Medium.ttf +0 -0
  225. package/src/assets/fonts/roboto/Roboto-MediumItalic.ttf +0 -0
  226. package/src/assets/fonts/roboto/Roboto-Regular.ttf +0 -0
  227. package/src/assets/fonts/roboto/Roboto-SemiBold.ttf +0 -0
  228. package/src/assets/fonts/roboto/Roboto-SemiBoldItalic.ttf +0 -0
  229. package/src/assets/fonts/roboto/Roboto-Thin.ttf +0 -0
  230. package/src/assets/fonts/roboto/Roboto-ThinItalic.ttf +0 -0
  231. package/src/assets/fonts/roboto/Roboto-VariableFont_wdth,wght.ttf +0 -0
  232. package/src/assets/fonts/roboto/Roboto_Condensed-Black.ttf +0 -0
  233. package/src/assets/fonts/roboto/Roboto_Condensed-BlackItalic.ttf +0 -0
  234. package/src/assets/fonts/roboto/Roboto_Condensed-Bold.ttf +0 -0
  235. package/src/assets/fonts/roboto/Roboto_Condensed-BoldItalic.ttf +0 -0
  236. package/src/assets/fonts/roboto/Roboto_Condensed-ExtraBold.ttf +0 -0
  237. package/src/assets/fonts/roboto/Roboto_Condensed-ExtraBoldItalic.ttf +0 -0
  238. package/src/assets/fonts/roboto/Roboto_Condensed-ExtraLight.ttf +0 -0
  239. package/src/assets/fonts/roboto/Roboto_Condensed-ExtraLightItalic.ttf +0 -0
  240. package/src/assets/fonts/roboto/Roboto_Condensed-Italic.ttf +0 -0
  241. package/src/assets/fonts/roboto/Roboto_Condensed-Light.ttf +0 -0
  242. package/src/assets/fonts/roboto/Roboto_Condensed-LightItalic.ttf +0 -0
  243. package/src/assets/fonts/roboto/Roboto_Condensed-Medium.ttf +0 -0
  244. package/src/assets/fonts/roboto/Roboto_Condensed-MediumItalic.ttf +0 -0
  245. package/src/assets/fonts/roboto/Roboto_Condensed-Regular.ttf +0 -0
  246. package/src/assets/fonts/roboto/Roboto_Condensed-SemiBold.ttf +0 -0
  247. package/src/assets/fonts/roboto/Roboto_Condensed-SemiBoldItalic.ttf +0 -0
  248. package/src/assets/fonts/roboto/Roboto_Condensed-Thin.ttf +0 -0
  249. package/src/assets/fonts/roboto/Roboto_Condensed-ThinItalic.ttf +0 -0
  250. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Black.ttf +0 -0
  251. package/src/assets/fonts/roboto/Roboto_SemiCondensed-BlackItalic.ttf +0 -0
  252. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Bold.ttf +0 -0
  253. package/src/assets/fonts/roboto/Roboto_SemiCondensed-BoldItalic.ttf +0 -0
  254. package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraBold.ttf +0 -0
  255. package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraBoldItalic.ttf +0 -0
  256. package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraLight.ttf +0 -0
  257. package/src/assets/fonts/roboto/Roboto_SemiCondensed-ExtraLightItalic.ttf +0 -0
  258. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Italic.ttf +0 -0
  259. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Light.ttf +0 -0
  260. package/src/assets/fonts/roboto/Roboto_SemiCondensed-LightItalic.ttf +0 -0
  261. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Medium.ttf +0 -0
  262. package/src/assets/fonts/roboto/Roboto_SemiCondensed-MediumItalic.ttf +0 -0
  263. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Regular.ttf +0 -0
  264. package/src/assets/fonts/roboto/Roboto_SemiCondensed-SemiBold.ttf +0 -0
  265. package/src/assets/fonts/roboto/Roboto_SemiCondensed-SemiBoldItalic.ttf +0 -0
  266. package/src/assets/fonts/roboto/Roboto_SemiCondensed-Thin.ttf +0 -0
  267. package/src/assets/fonts/roboto/Roboto_SemiCondensed-ThinItalic.ttf +0 -0
  268. package/src/assets/fonts/roboto-slab/RobotoSlab-Black.ttf +0 -0
  269. package/src/assets/fonts/roboto-slab/RobotoSlab-Bold.ttf +0 -0
  270. package/src/assets/fonts/roboto-slab/RobotoSlab-ExtraBold.ttf +0 -0
  271. package/src/assets/fonts/roboto-slab/RobotoSlab-ExtraLight.ttf +0 -0
  272. package/src/assets/fonts/roboto-slab/RobotoSlab-Light.ttf +0 -0
  273. package/src/assets/fonts/roboto-slab/RobotoSlab-Medium.ttf +0 -0
  274. package/src/assets/fonts/roboto-slab/RobotoSlab-Regular.ttf +0 -0
  275. package/src/assets/fonts/roboto-slab/RobotoSlab-SemiBold.ttf +0 -0
  276. package/src/assets/fonts/roboto-slab/RobotoSlab-Thin.ttf +0 -0
  277. package/src/assets/fonts/roboto-slab/RobotoSlab-VariableFont_wght.ttf +0 -0
  278. package/src/assets/fonts/rubik-mono-one/RubikMonoOne-Regular.ttf +0 -0
  279. package/src/assets/icons/arrows-up-down-left-right.svg +1 -0
  280. package/src/assets/icons/arrows-up-down.svg +1 -0
  281. package/src/assets/icons/attachments.svg +1 -3
  282. package/src/assets/icons/attachments2.svg +3 -0
  283. package/src/assets/icons/clear.svg +1 -5
  284. package/src/assets/icons/cursor-default-custom.svg +10 -0
  285. package/src/assets/icons/cursor-default.svg +1 -0
  286. package/src/assets/icons/cursor-default2.svg +1 -0
  287. package/src/assets/icons/emoji.svg +1 -6
  288. package/src/assets/icons/emoji2.svg +6 -0
  289. package/src/assets/icons/frame.svg +1 -3
  290. package/src/assets/icons/frame2.svg +3 -0
  291. package/src/assets/icons/i-cursor.svg +1 -0
  292. package/src/assets/icons/image.svg +1 -3
  293. package/src/assets/icons/image2.svg +3 -0
  294. package/src/assets/icons/note.svg +1 -3
  295. package/src/assets/icons/note2.svg +3 -0
  296. package/src/assets/icons/pencil.svg +1 -3
  297. package/src/assets/icons/pencil2.svg +3 -0
  298. package/src/assets/icons/select.svg +1 -1
  299. package/src/assets/icons/shapes.svg +1 -3
  300. package/src/assets/icons/shapes2.svg +3 -0
  301. package/src/assets/icons/text-add.svg +1 -3
  302. package/src/assets/icons/text-add2.svg +3 -0
  303. package/src/assets/icons/trash.svg +1 -0
  304. package/src/core/commands/GroupMoveCommand.js +49 -13
  305. package/src/core/commands/MoveObjectCommand.js +4 -24
  306. package/src/core/events/Events.js +2 -0
  307. package/src/core/index.js +72 -40
  308. package/src/grid/GridFactory.js +3 -3
  309. package/src/grid/LineGrid.js +42 -20
  310. package/src/moodboard/MoodBoard.js +11 -0
  311. package/src/objects/DrawingObject.js +5 -5
  312. package/src/objects/FrameObject.js +1 -0
  313. package/src/objects/ImageObject.js +24 -5
  314. package/src/objects/NoteObject.js +221 -48
  315. package/src/services/BoardService.js +3 -3
  316. package/src/services/ZoomPanController.js +14 -3
  317. package/src/tools/BaseTool.js +6 -1
  318. package/src/tools/ToolManager.js +24 -1
  319. package/src/tools/object-tools/DrawingTool.js +3 -1
  320. package/src/tools/object-tools/PlacementTool.js +213 -93
  321. package/src/tools/object-tools/SelectTool.js +318 -134
  322. package/src/tools/object-tools/TextTool.js +23 -2
  323. package/src/ui/FramePropertiesPanel.js +101 -96
  324. package/src/ui/HtmlHandlesLayer.js +253 -52
  325. package/src/ui/HtmlTextLayer.js +120 -32
  326. package/src/ui/NotePropertiesPanel.js +115 -38
  327. package/src/ui/TextPropertiesPanel.js +100 -118
  328. package/src/ui/Toolbar.js +136 -50
  329. package/src/ui/Topbar.js +112 -10
  330. package/src/ui/ZoomPanel.js +8 -2
  331. package/src/ui/styles/index.css +5 -0
  332. package/src/ui/styles/panels.css +232 -0
  333. package/src/ui/styles/toolbar.css +77 -0
  334. package/src/ui/styles/topbar.css +113 -0
  335. package/src/ui/styles/workspace.css +412 -263
  336. package/src/utils/emojiResolver.js +121 -0
@@ -1,4 +1,5 @@
1
1
  import { Events } from '../core/events/Events.js';
2
+ import * as PIXI from 'pixi.js';
2
3
  import rotateIconSvg from '../assets/icons/rotate-icon.svg?raw';
3
4
 
4
5
  /**
@@ -27,9 +28,6 @@ export class HtmlHandlesLayer {
27
28
  attach() {
28
29
  this.layer = document.createElement('div');
29
30
  this.layer.className = 'moodboard-html-handles';
30
- Object.assign(this.layer.style, {
31
- position: 'absolute', inset: '0', pointerEvents: 'none', zIndex: 12,
32
- });
33
31
  this.container.appendChild(this.layer);
34
32
 
35
33
  // Подписки: обновлять при изменениях выбора и трансформациях
@@ -56,6 +54,18 @@ export class HtmlHandlesLayer {
56
54
  this.eventBus.on(Events.Tool.GroupRotateEnd, () => { this._handlesSuppressed = false; this._setHandlesVisibility(true); });
57
55
  this.eventBus.on(Events.UI.ZoomPercent, () => this.update());
58
56
  this.eventBus.on(Events.Tool.PanUpdate, () => this.update());
57
+
58
+ // Обновление рамки при undo/redo команд трансформации (перемещение, ресайз, поворот)
59
+ this.eventBus.on(Events.Object.TransformUpdated, (data) => {
60
+ // Проверяем, что обновленный объект выделен, и обновляем ручки
61
+ if (this.core?.selectTool && data.objectId) {
62
+ const isSelected = this.core.selectTool.selectedObjects.has(data.objectId);
63
+ if (isSelected) {
64
+ console.log(`🔄 HtmlHandlesLayer: Объект ${data.objectId} изменен через команду, обновляем рамку`);
65
+ this.update();
66
+ }
67
+ }
68
+ });
59
69
 
60
70
  this.update();
61
71
  }
@@ -93,24 +103,39 @@ export class HtmlHandlesLayer {
93
103
  height: sizeData.size.height
94
104
  }, id);
95
105
  } else {
96
- // Fallback к getBounds() если события не сработали
106
+ // Fallback к getBounds() если события не сработали — конвертируем в мировые координаты (без зума)
107
+ const world = this.core.pixi.worldLayer || this.core.pixi.app.stage;
97
108
  const b = pixi.getBounds();
98
- this._showBounds({ x: b.x, y: b.y, width: b.width, height: b.height }, id);
109
+ const tl = world.toLocal(new PIXI.Point(b.x, b.y));
110
+ const br = world.toLocal(new PIXI.Point(b.x + b.width, b.y + b.height));
111
+ const wx = Math.min(tl.x, br.x);
112
+ const wy = Math.min(tl.y, br.y);
113
+ const ww = Math.max(1, Math.abs(br.x - tl.x));
114
+ const wh = Math.max(1, Math.abs(br.y - tl.y));
115
+ this._showBounds({ x: wx, y: wy, width: ww, height: wh }, id);
99
116
  }
100
117
  } else {
101
- // Группа: вычислим общий bbox по PIXI
118
+ // Группа: считаем bbox в МИРОВЫХ координатах (независимо от текущего зума)
119
+ const world = this.core.pixi.worldLayer || this.core.pixi.app.stage;
102
120
  let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
103
121
  ids.forEach(id => {
104
122
  const p = this.core.pixi.objects.get(id);
105
123
  if (!p) return;
106
124
  const b = p.getBounds();
107
- minX = Math.min(minX, b.x);
108
- minY = Math.min(minY, b.y);
109
- maxX = Math.max(maxX, b.x + b.width);
110
- maxY = Math.max(maxY, b.y + b.height);
125
+ // Конвертируем углы прямоугольника из экранных в мировые координаты
126
+ const tl = world.toLocal(new PIXI.Point(b.x, b.y));
127
+ const br = world.toLocal(new PIXI.Point(b.x + b.width, b.y + b.height));
128
+ const x0 = Math.min(tl.x, br.x);
129
+ const y0 = Math.min(tl.y, br.y);
130
+ const x1 = Math.max(tl.x, br.x);
131
+ const y1 = Math.max(tl.y, br.y);
132
+ minX = Math.min(minX, x0);
133
+ minY = Math.min(minY, y0);
134
+ maxX = Math.max(maxX, x1);
135
+ maxY = Math.max(maxY, y1);
111
136
  });
112
137
  if (!isFinite(minX)) { this.hide(); return; }
113
- this._showBounds({ x: minX, y: minY, width: maxX - minX, height: maxY - minY }, '__group__');
138
+ this._showBounds({ x: minX, y: minY, width: Math.max(1, maxX - minX), height: Math.max(1, maxY - minY) }, '__group__');
114
139
  }
115
140
  }
116
141
 
@@ -182,7 +207,7 @@ export class HtmlHandlesLayer {
182
207
  this.layer.innerHTML = '';
183
208
  const box = document.createElement('div');
184
209
  box.className = 'mb-handles-box';
185
-
210
+
186
211
  // Получаем угол поворота объекта для поворота рамки
187
212
  let rotation = 0;
188
213
  if (id !== '__group__') {
@@ -209,16 +234,9 @@ export class HtmlHandlesLayer {
209
234
  const mkCorner = (dir, x, y, cursor) => {
210
235
  const h = document.createElement('div');
211
236
  h.dataset.dir = dir; h.dataset.id = id;
212
- Object.assign(h.style, {
213
- position: 'absolute', width: '12px', height: '12px',
214
- background: '#1DE9B6',
215
- border: '2px solid #1DE9B6',
216
- borderRadius: '50%', // Делаем круглыми
217
- boxSizing: 'border-box',
218
- pointerEvents: isFileTarget ? 'none' : 'auto',
219
- zIndex: 10, // Увеличиваем z-index
220
- cursor: cursor
221
- });
237
+ h.className = 'mb-handle';
238
+ h.style.pointerEvents = isFileTarget ? 'none' : 'auto';
239
+ h.style.cursor = cursor;
222
240
  h.style.left = `${x - 6}px`;
223
241
  h.style.top = `${y - 6}px`;
224
242
  // Для файла скрываем ручки, для остальных показываем
@@ -226,15 +244,7 @@ export class HtmlHandlesLayer {
226
244
 
227
245
  // Создаем внутренний белый круг
228
246
  const inner = document.createElement('div');
229
- Object.assign(inner.style, {
230
- position: 'absolute',
231
- top: '1px', left: '1px',
232
- width: '6px', height: '6px',
233
- background: '#fff',
234
- borderRadius: '50%',
235
- pointerEvents: 'none', // Важно: не блокируем события
236
- zIndex: 1
237
- });
247
+ inner.className = 'mb-handle-inner';
238
248
  h.appendChild(inner);
239
249
 
240
250
  // Эффект при наведении
@@ -261,11 +271,7 @@ export class HtmlHandlesLayer {
261
271
  mkCorner('se', x1, y1, 'nwse-resize');
262
272
  mkCorner('sw', x0, y1, 'nesw-resize');
263
273
 
264
- // Боковые ручки (видимые круглые ручки на серединах сторон)
265
- mkCorner('n', cx, y0, 'ns-resize'); // верхняя
266
- mkCorner('e', x1, cy, 'ew-resize'); // правая
267
- mkCorner('s', cx, y1, 'ns-resize'); // нижняя
268
- mkCorner('w', x0, cy, 'ew-resize'); // левая
274
+ // Видимые ручки на серединах сторон отключены (масштабирование по рёбрам работает через невидимые зоны)
269
275
 
270
276
  // Кликабельные грани для ресайза (невидимые области для лучшего UX)
271
277
  // Уменьшаем их, чтобы не перекрывать угловые ручки
@@ -273,12 +279,10 @@ export class HtmlHandlesLayer {
273
279
  const makeEdge = (name, style, cursor) => {
274
280
  const e = document.createElement('div');
275
281
  e.dataset.edge = name; e.dataset.id = id;
282
+ e.className = 'mb-edge';
276
283
  Object.assign(e.style, style, {
277
- position: 'absolute', pointerEvents: isFileTarget ? 'none' : 'auto', cursor,
278
- zIndex: 5, // Меньше чем у ручек (10)
279
- background: 'transparent', // невидимые области
284
+ pointerEvents: isFileTarget ? 'none' : 'auto', cursor,
280
285
  display: isFileTarget ? 'none' : 'block'
281
-
282
286
  });
283
287
  if (!isFileTarget) {
284
288
  e.addEventListener('mousedown', (evt) => this._onEdgeResizeDown(evt));
@@ -328,17 +332,7 @@ export class HtmlHandlesLayer {
328
332
  if (isFileTarget || isFrameTarget) {
329
333
  Object.assign(rotateHandle.style, { display: 'none', pointerEvents: 'none' });
330
334
  } else {
331
- Object.assign(rotateHandle.style, {
332
- position: 'absolute',
333
- width: '20px', height: '20px',
334
- background: 'transparent',
335
- border: 'none',
336
- borderRadius: '50%',
337
- pointerEvents: 'auto',
338
- cursor: 'grab',
339
- zIndex: 15,
340
- display: 'flex', alignItems: 'center', justifyContent: 'center'
341
- });
335
+ rotateHandle.className = 'mb-rotate-handle';
342
336
  // Фиксированная дистанция 20px по диагонали (top-right → bottom-left) от угла (0, h)
343
337
  const d = 38;
344
338
  const L = Math.max(1, Math.hypot(width, height));
@@ -416,6 +410,17 @@ export class HtmlHandlesLayer {
416
410
  }
417
411
 
418
412
  const startMouse = { x: e.clientX, y: e.clientY };
413
+ // Определяем тип объекта (нужно, чтобы для текста автоподгонять высоту)
414
+ let isTextTarget = false;
415
+ let isNoteTarget = false;
416
+ {
417
+ const req = { objectId: id, pixiObject: null };
418
+ this.eventBus.emit(Events.Tool.GetObjectPixi, req);
419
+ const mbType = req.pixiObject && req.pixiObject._mb && req.pixiObject._mb.type;
420
+ isTextTarget = (mbType === 'text' || mbType === 'simple-text');
421
+ isNoteTarget = (mbType === 'note');
422
+ }
423
+
419
424
  const onMove = (ev) => {
420
425
  const dx = ev.clientX - startMouse.x;
421
426
  const dy = ev.clientY - startMouse.y;
@@ -438,6 +443,85 @@ export class HtmlHandlesLayer {
438
443
  newTop = startCSS.top + dy;
439
444
  }
440
445
 
446
+ // Для записки удерживаем квадрат и компенсируем позицию в зависимости от ручки
447
+ if (isNoteTarget) {
448
+ const s = Math.max(newW, newH);
449
+ // базовая фиксация размера
450
+ newW = s; newH = s;
451
+ // корректируем привязку противоположной стороны
452
+ if (dir.includes('w')) { newLeft = startCSS.left + (startCSS.width - s); }
453
+ if (dir.includes('n')) { newTop = startCSS.top + (startCSS.height - s); }
454
+ }
455
+
456
+ // Минимальная ширина = ширина трёх символов текущего шрифта
457
+ if (isTextTarget) {
458
+ try {
459
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
460
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
461
+ if (el && typeof window.getComputedStyle === 'function') {
462
+ const cs = window.getComputedStyle(el);
463
+ const meas = document.createElement('span');
464
+ meas.style.position = 'absolute';
465
+ meas.style.visibility = 'hidden';
466
+ meas.style.whiteSpace = 'pre';
467
+ meas.style.fontFamily = cs.fontFamily;
468
+ meas.style.fontSize = cs.fontSize;
469
+ meas.style.fontWeight = cs.fontWeight;
470
+ meas.style.fontStyle = cs.fontStyle;
471
+ meas.style.letterSpacing = cs.letterSpacing || 'normal';
472
+ meas.textContent = 'WWW';
473
+ document.body.appendChild(meas);
474
+ const minWidthPx = Math.max(1, Math.ceil(meas.getBoundingClientRect().width));
475
+ meas.remove();
476
+ if (newW < minWidthPx) {
477
+ if (dir.includes('w')) {
478
+ newLeft = startCSS.left + (startCSS.width - minWidthPx);
479
+ }
480
+ newW = minWidthPx;
481
+ }
482
+ }
483
+ } catch (_) {}
484
+ }
485
+
486
+ // Для текстовых объектов подгоняем высоту под контент при изменении ширины
487
+ if (isTextTarget) {
488
+ try {
489
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
490
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
491
+ if (el) {
492
+ // Минимальная ширина в 3 символа
493
+ let minWidthPx = 0;
494
+ try {
495
+ const cs = window.getComputedStyle(el);
496
+ const meas = document.createElement('span');
497
+ meas.style.position = 'absolute';
498
+ meas.style.visibility = 'hidden';
499
+ meas.style.whiteSpace = 'pre';
500
+ meas.style.fontFamily = cs.fontFamily;
501
+ meas.style.fontSize = cs.fontSize;
502
+ meas.style.fontWeight = cs.fontWeight;
503
+ meas.style.fontStyle = cs.fontStyle;
504
+ meas.style.letterSpacing = cs.letterSpacing || 'normal';
505
+ meas.textContent = 'WWW';
506
+ document.body.appendChild(meas);
507
+ minWidthPx = Math.max(1, Math.ceil(meas.getBoundingClientRect().width));
508
+ meas.remove();
509
+ } catch (_) {}
510
+
511
+ if (minWidthPx > 0 && newW < minWidthPx) {
512
+ if (dir.includes('w')) {
513
+ newLeft = startCSS.left + (startCSS.width - minWidthPx);
514
+ }
515
+ newW = minWidthPx;
516
+ }
517
+ el.style.width = `${Math.max(1, Math.round(newW))}px`;
518
+ el.style.height = 'auto';
519
+ const measured = Math.max(1, Math.round(el.scrollHeight));
520
+ newH = measured;
521
+ }
522
+ } catch (_) {}
523
+ }
524
+
441
525
  // Обновим визуально (округление до целых для избежания дрожания)
442
526
  box.style.left = `${Math.round(newLeft)}px`;
443
527
  box.style.top = `${Math.round(newTop)}px`;
@@ -527,6 +611,28 @@ export class HtmlHandlesLayer {
527
611
  };
528
612
 
529
613
  this.eventBus.emit(Events.Tool.ResizeEnd, resizeEndData);
614
+ // Для текстовых объектов также пробуем обновить размер по контенту ещё раз
615
+ try {
616
+ const req2 = { objectId: id, pixiObject: null };
617
+ this.eventBus.emit(Events.Tool.GetObjectPixi, req2);
618
+ const mbType2 = req2.pixiObject && req2.pixiObject._mb && req2.pixiObject._mb.type;
619
+ if (mbType2 === 'text' || mbType2 === 'simple-text') {
620
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
621
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
622
+ if (el) {
623
+ el.style.width = `${Math.max(1, Math.round(endCSS.width))}px`;
624
+ el.style.height = 'auto';
625
+ const measured = Math.max(1, Math.round(el.scrollHeight));
626
+ const worldH2 = (measured * res) / s;
627
+ const fixData = {
628
+ object: id,
629
+ size: { width: worldW, height: worldH2 },
630
+ position: isFrameTarget ? null : (isEdgeLeftOrTop ? { x: worldX, y: worldY } : { x: startWorld.x, y: startWorld.y })
631
+ };
632
+ this.eventBus.emit(Events.Tool.ResizeUpdate, fixData);
633
+ }
634
+ }
635
+ } catch (_) {}
530
636
  }
531
637
  };
532
638
  document.addEventListener('mousemove', onMove);
@@ -580,6 +686,16 @@ export class HtmlHandlesLayer {
580
686
  }
581
687
 
582
688
  const startMouse = { x: e.clientX, y: e.clientY };
689
+ // Определяем тип объекта: для текста будем автоподгонять высоту при изменении ширины
690
+ let isTextTarget = false;
691
+ let isNoteTarget = false;
692
+ {
693
+ const req = { objectId: id, pixiObject: null };
694
+ this.eventBus.emit(Events.Tool.GetObjectPixi, req);
695
+ const mbType = req.pixiObject && req.pixiObject._mb && req.pixiObject._mb.type;
696
+ isTextTarget = (mbType === 'text' || mbType === 'simple-text');
697
+ isNoteTarget = (mbType === 'note');
698
+ }
583
699
  const onMove = (ev) => {
584
700
  const dxCSS = ev.clientX - startMouse.x;
585
701
  const dyCSS = ev.clientY - startMouse.y;
@@ -599,6 +715,76 @@ export class HtmlHandlesLayer {
599
715
  newTop = startCSS.top + dyCSS;
600
716
  }
601
717
 
718
+ // Для записки удерживаем квадрат и компенсируем противоположные стороны
719
+ if (isNoteTarget) {
720
+ const s = Math.max(newW, newH);
721
+ switch (edge) {
722
+ case 'right':
723
+ newW = s; newH = s;
724
+ newTop = startCSS.top + Math.round((startCSS.height - s) / 2);
725
+ break;
726
+ case 'left':
727
+ newW = s; newH = s;
728
+ newLeft = startCSS.left + (startCSS.width - s);
729
+ newTop = startCSS.top + Math.round((startCSS.height - s) / 2);
730
+ break;
731
+ case 'bottom':
732
+ newW = s; newH = s;
733
+ newLeft = startCSS.left + Math.round((startCSS.width - s) / 2);
734
+ break;
735
+ case 'top':
736
+ newW = s; newH = s;
737
+ newTop = startCSS.top + (startCSS.height - s);
738
+ newLeft = startCSS.left + Math.round((startCSS.width - s) / 2);
739
+ break;
740
+ }
741
+ }
742
+
743
+ // Минимальная ширина = ширина трёх символов текущего шрифта
744
+ if (isTextTarget) {
745
+ try {
746
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
747
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
748
+ if (el && typeof window.getComputedStyle === 'function') {
749
+ const cs = window.getComputedStyle(el);
750
+ const meas = document.createElement('span');
751
+ meas.style.position = 'absolute';
752
+ meas.style.visibility = 'hidden';
753
+ meas.style.whiteSpace = 'pre';
754
+ meas.style.fontFamily = cs.fontFamily;
755
+ meas.style.fontSize = cs.fontSize;
756
+ meas.style.fontWeight = cs.fontWeight;
757
+ meas.style.fontStyle = cs.fontStyle;
758
+ meas.style.letterSpacing = cs.letterSpacing || 'normal';
759
+ meas.textContent = 'WWW';
760
+ document.body.appendChild(meas);
761
+ const minWidthPx = Math.max(1, Math.ceil(meas.getBoundingClientRect().width));
762
+ meas.remove();
763
+ if (newW < minWidthPx) {
764
+ if (edge === 'left') {
765
+ newLeft = startCSS.left + (startCSS.width - minWidthPx);
766
+ }
767
+ newW = minWidthPx;
768
+ }
769
+ }
770
+ } catch (_) {}
771
+ }
772
+
773
+ // Для текстовых объектов при изменении ширины вычисляем высоту по контенту
774
+ const widthChanged = (edge === 'left' || edge === 'right');
775
+ if (isTextTarget && widthChanged) {
776
+ try {
777
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
778
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
779
+ if (el) {
780
+ el.style.width = `${Math.max(1, Math.round(newW))}px`;
781
+ el.style.height = 'auto';
782
+ const measured = Math.max(1, Math.round(el.scrollHeight));
783
+ newH = measured;
784
+ }
785
+ } catch (_) {}
786
+ }
787
+
602
788
  // Обновим визуально
603
789
  box.style.left = `${newLeft}px`;
604
790
  box.style.top = `${newTop}px`;
@@ -660,10 +846,25 @@ export class HtmlHandlesLayer {
660
846
  // Определяем, изменилась ли позиция для краевого ресайза
661
847
  const edgeFinalPositionChanged = (endCSS.left !== startCSS.left) || (endCSS.top !== startCSS.top);
662
848
 
849
+ // Финальная коррекция высоты для текстовых объектов
850
+ let finalWorldH = worldH;
851
+ if (isTextTarget && (edge === 'left' || edge === 'right')) {
852
+ try {
853
+ const textLayer = (typeof window !== 'undefined') ? window.moodboardHtmlTextLayer : null;
854
+ const el = textLayer && textLayer.idToEl ? textLayer.idToEl.get && textLayer.idToEl.get(id) : null;
855
+ if (el) {
856
+ el.style.width = `${Math.max(1, Math.round(endCSS.width))}px`;
857
+ el.style.height = 'auto';
858
+ const measured = Math.max(1, Math.round(el.scrollHeight));
859
+ finalWorldH = (measured * res) / s;
860
+ }
861
+ } catch (_) {}
862
+ }
863
+
663
864
  const edgeResizeEndData = {
664
865
  object: id,
665
866
  oldSize: { width: startWorld.width, height: startWorld.height },
666
- newSize: { width: worldW, height: worldH },
867
+ newSize: { width: worldW, height: finalWorldH },
667
868
  oldPosition: { x: startWorld.x, y: startWorld.y },
668
869
  newPosition: edgeFinalPositionChanged ? { x: worldX, y: worldY } : { x: startWorld.x, y: startWorld.y }
669
870
  };
@@ -42,7 +42,7 @@ export class HtmlTextLayer {
42
42
  this.updateOne(objectId);
43
43
  });
44
44
 
45
- // Прятать HTML-текст во время редактирования (textarea)
45
+ // Прятать HTML-текст во время редактирования (textarea) — общий текст
46
46
  this.eventBus.on(Events.UI.TextEditStart, ({ objectId }) => {
47
47
  const el = this.idToEl.get(objectId);
48
48
  if (el) el.style.visibility = 'hidden';
@@ -52,6 +52,16 @@ export class HtmlTextLayer {
52
52
  if (el) el.style.visibility = '';
53
53
  });
54
54
 
55
+ // Независимое скрытие/показ для записок
56
+ this.eventBus.on(Events.UI.NoteEditStart, ({ objectId }) => {
57
+ const el = this.idToEl.get(objectId);
58
+ if (el) el.style.visibility = 'hidden';
59
+ });
60
+ this.eventBus.on(Events.UI.NoteEditEnd, ({ objectId }) => {
61
+ const el = this.idToEl.get(objectId);
62
+ if (el) el.style.visibility = '';
63
+ });
64
+
55
65
  // Обработка событий скрытия/показа текста от SelectTool
56
66
  this.eventBus.on(Events.Tool.HideObjectText, ({ objectId }) => {
57
67
  console.log(`🔍 HtmlTextLayer: скрываю текст для объекта ${objectId}`);
@@ -90,12 +100,26 @@ export class HtmlTextLayer {
90
100
  this.eventBus.on(Events.Object.StateChanged, ({ objectId, updates }) => {
91
101
  const el = this.idToEl.get(objectId);
92
102
  if (el && updates) {
93
- if (updates.fontFamily) {
94
- el.style.fontFamily = updates.fontFamily;
95
- console.log(`🔍 HtmlTextLayer: обновлен шрифт для ${objectId}:`, updates.fontFamily);
103
+ // Поддерживаем верхний уровень и updates.properties.fontFamily
104
+ const nextFont = updates.fontFamily || (updates.properties && updates.properties.fontFamily);
105
+ if (nextFont) {
106
+ el.style.fontFamily = nextFont;
107
+ console.log(`🔍 HtmlTextLayer: обновлен шрифт для ${objectId}:`, nextFont);
96
108
  }
97
109
  if (updates.fontSize) {
98
110
  el.style.fontSize = `${updates.fontSize}px`;
111
+ // Также обновляем line-height согласно новой шкале
112
+ const fs = updates.fontSize;
113
+ const lh = (fs <= 12) ? Math.round(fs * 1.40)
114
+ : (fs <= 18) ? Math.round(fs * 1.34)
115
+ : (fs <= 36) ? Math.round(fs * 1.26)
116
+ : (fs <= 48) ? Math.round(fs * 1.24)
117
+ : (fs <= 72) ? Math.round(fs * 1.22)
118
+ : (fs <= 96) ? Math.round(fs * 1.20)
119
+ : Math.round(fs * 1.18);
120
+ el.style.lineHeight = `${lh}px`;
121
+ // Синхронизируем базовый размер шрифта для дальнейших пересчётов (zoom/resize)
122
+ el.dataset.baseFontSize = String(fs);
99
123
  console.log(`🔍 HtmlTextLayer: обновлен размер шрифта для ${objectId}:`, updates.fontSize);
100
124
  }
101
125
  if (updates.color) {
@@ -106,7 +130,9 @@ export class HtmlTextLayer {
106
130
  el.style.backgroundColor = updates.backgroundColor === 'transparent' ? '' : updates.backgroundColor;
107
131
  console.log(`🔍 HtmlTextLayer: обновлен фон для ${objectId}:`, updates.backgroundColor);
108
132
  }
109
- // Здесь можно добавить обработку других свойств текста
133
+ // После изменения свойств текста автоподгон высоты рамки под контент и принудительное обновление
134
+ this._autoFitTextHeight(objectId);
135
+ this.updateOne(objectId);
110
136
  }
111
137
  });
112
138
 
@@ -171,26 +197,40 @@ export class HtmlTextLayer {
171
197
  el.className = 'mb-text';
172
198
  el.dataset.id = objectId;
173
199
  // Получаем свойства из properties объекта
174
- const fontFamily = objectData.fontFamily || objectData.properties?.fontFamily || 'Arial, sans-serif';
200
+ const fontFamily = objectData.properties?.fontFamily || objectData.fontFamily || 'Caveat, Arial, cursive';
175
201
  const color = objectData.color || objectData.properties?.color || '#000000';
176
202
  const backgroundColor = objectData.backgroundColor || objectData.properties?.backgroundColor || 'transparent';
177
203
 
178
- Object.assign(el.style, {
179
- position: 'absolute',
180
- transformOrigin: 'top left',
181
- color: color,
182
- whiteSpace: 'pre-wrap',
183
- overflowWrap: 'anywhere',
184
- wordBreak: 'break-word',
185
- pointerEvents: 'none', // всё взаимодействие остаётся на PIXI
186
- userSelect: 'none',
187
- fontFamily: fontFamily,
188
- backgroundColor: backgroundColor === 'transparent' ? '' : backgroundColor
189
- });
204
+ // Базовый line-height исходя из стартового размера шрифта
205
+ const baseFs = objectData.fontSize || objectData.properties?.fontSize || 32;
206
+ const baseLineHeight = (() => {
207
+ const fs = baseFs;
208
+ if (fs <= 12) return Math.round(fs * 1.40);
209
+ if (fs <= 18) return Math.round(fs * 1.34);
210
+ if (fs <= 36) return Math.round(fs * 1.26);
211
+ if (fs <= 48) return Math.round(fs * 1.24);
212
+ if (fs <= 72) return Math.round(fs * 1.22);
213
+ if (fs <= 96) return Math.round(fs * 1.20);
214
+ return Math.round(fs * 1.18);
215
+ })();
216
+
217
+ el.classList.add('mb-text');
218
+ el.style.color = color;
219
+ el.style.fontFamily = fontFamily;
220
+ el.style.backgroundColor = backgroundColor === 'transparent' ? '' : backgroundColor;
221
+ el.style.lineHeight = `${baseLineHeight}px`;
222
+ // Выравнивание рендеринга с textarea
223
+ el.style.whiteSpace = 'pre-wrap';
224
+ el.style.wordBreak = 'break-word';
225
+ el.style.overflow = 'visible';
226
+ el.style.letterSpacing = '0px';
227
+ el.style.fontKerning = 'normal';
228
+ el.style.textRendering = 'optimizeLegibility';
229
+ el.style.padding = '0'; // без внутренних отступов
190
230
  const content = objectData.content || objectData.properties?.content || '';
191
231
  el.textContent = content;
192
232
  // Базовые размеры сохраняем в dataset
193
- const fs = objectData.fontSize || objectData.properties?.fontSize || 16;
233
+ const fs = objectData.fontSize || objectData.properties?.fontSize || 32;
194
234
  const bw = Math.max(1, objectData.width || objectData.properties?.baseW || 160);
195
235
  const bh = Math.max(1, objectData.height || objectData.properties?.baseH || 36);
196
236
  el.dataset.baseFontSize = String(fs);
@@ -230,24 +270,40 @@ export class HtmlTextLayer {
230
270
  const y = obj.position?.y || 0;
231
271
  const w = obj.width || 0;
232
272
  const h = obj.height || 0;
233
- const angle = obj.rotation || obj.transform?.rotation || 0;
273
+ // Угол: во время поворота state ещё не обновлён, поэтому берем актуальный из PIXI
274
+ const pixiObj = this.core?.pixi?.objects?.get ? this.core.pixi.objects.get(objectId) : null;
275
+ const angle = (pixiObj && typeof pixiObj.rotation === 'number')
276
+ ? (pixiObj.rotation * 180 / Math.PI)
277
+ : (obj.rotation || obj.transform?.rotation || 0);
234
278
 
235
279
  // Чёткая отрисовка: меняем реальный font-size, учитывая зум и изменение размеров
236
- const baseFS = parseFloat(el.dataset.baseFontSize || '16') || 16;
280
+ const baseFS = parseFloat(el.dataset.baseFontSize || `${obj.properties?.fontSize || obj.fontSize || 32}`) || 32;
237
281
  const baseW = parseFloat(el.dataset.baseW || '160') || 160;
238
282
  const baseH = parseFloat(el.dataset.baseH || '36') || 36;
239
283
  const scaleX = w && baseW ? (w / baseW) : 1;
240
284
  const scaleY = h && baseH ? (h / baseH) : 1;
241
- // Для текстовых объектов не масштабируем шрифт от изменения размеров блока,
242
- // чтобы сохранять вид как при редактировании (как в Miro)
243
- const sObj = (obj?.type === 'text' || obj?.type === 'simple-text')
285
+ // Для записок также не масштабируем шрифт от размера блока — редактор совпадает точно
286
+ const sObj = (obj?.type === 'text' || obj?.type === 'simple-text' || obj?.type === 'note')
244
287
  ? 1
245
288
  : Math.min(scaleX, scaleY);
246
289
  const sCss = s / res;
247
290
  const fontSizePx = Math.max(1, baseFS * sObj * sCss);
248
291
  el.style.fontSize = `${fontSizePx}px`;
249
- // Синхронизируем межстрочный интервал с режимом редактирования
250
- el.style.lineHeight = `${fontSizePx}px`;
292
+ // Адаптивный межстрочный интервал по размеру шрифта
293
+ const computeLineHeightPx = (fs) => {
294
+ if (fs <= 12) return Math.round(fs * 1.40);
295
+ if (fs <= 18) return Math.round(fs * 1.34);
296
+ if (fs <= 36) return Math.round(fs * 1.26);
297
+ if (fs <= 48) return Math.round(fs * 1.24);
298
+ if (fs <= 72) return Math.round(fs * 1.22);
299
+ if (fs <= 96) return Math.round(fs * 1.20);
300
+ return Math.round(fs * 1.18);
301
+ };
302
+ // Применяем новый line-height только если он отличается от текущего, чтобы избежать конфликтов CSS
303
+ const newLH = `${computeLineHeightPx(fontSizePx)}px`;
304
+ if (el.style.lineHeight !== newLH) {
305
+ el.style.lineHeight = newLH;
306
+ }
251
307
 
252
308
  // Позиция и габариты в экранных координатах
253
309
  const left = (tx + s * x) / res;
@@ -258,18 +314,23 @@ export class HtmlTextLayer {
258
314
  el.style.width = `${Math.max(1, (w * s) / res)}px`;
259
315
  el.style.height = `${Math.max(1, (h * s) / res)}px`;
260
316
  }
261
- // Поворот вокруг top-left
262
- if (angle) {
263
- el.style.transform = `rotate(${angle}deg)`;
264
- } else {
265
- el.style.transform = '';
266
- }
317
+ // Поворот вокруг центра (как у PIXI и HTML-ручек)
318
+ el.style.transformOrigin = 'center center';
319
+ el.style.transform = angle ? `rotate(${angle}deg)` : '';
267
320
  // Текст
268
321
  const content = obj.content || obj.properties?.content;
269
322
  if (typeof content === 'string') {
270
323
  el.textContent = content;
271
324
  console.log(`🔍 HtmlTextLayer: содержимое обновлено в updateOne для ${objectId}:`, content);
272
325
  }
326
+
327
+ // Гарантируем, что высота соответствует контенту (особенно после смены font-size)
328
+ try {
329
+ el.style.height = 'auto';
330
+ // Добавим небольшой нижний отступ для хвостов букв, чтобы не отсекались (например, у «з»)
331
+ const h = Math.max(1, Math.round(el.scrollHeight + 2));
332
+ el.style.height = `${h}px`;
333
+ } catch (_) {}
273
334
 
274
335
  console.log(`🔍 HtmlTextLayer: позиция обновлена для ${objectId}:`, {
275
336
  left: `${left}px`,
@@ -282,6 +343,33 @@ export class HtmlTextLayer {
282
343
  textContent: el.textContent
283
344
  });
284
345
  }
346
+
347
+ _autoFitTextHeight(objectId) {
348
+ const el = this.idToEl.get(objectId);
349
+ if (!el || !this.core) return;
350
+ try {
351
+ // Измеряем фактическую высоту HTML-текста
352
+ el.style.height = 'auto';
353
+ const measured = Math.max(1, Math.round(el.scrollHeight));
354
+ el.style.height = `${measured}px`;
355
+ // Пересчитываем мировую высоту и отправляем обновление размера через события ResizeUpdate
356
+ const world = this.core.pixi.worldLayer || this.core.pixi.app.stage;
357
+ const s = world?.scale?.x || 1;
358
+ const res = (this.core?.pixi?.app?.renderer?.resolution) || 1;
359
+ const worldH = (measured * res) / s;
360
+ // Узнаём текущую ширину в мире
361
+ const obj = (this.core.state.state.objects || []).find(o => o.id === objectId);
362
+ const worldW = obj?.width || 0;
363
+ const position = obj?.position || null;
364
+ if (worldW > 0 && position) {
365
+ this.core.eventBus.emit(Events.Tool.ResizeUpdate, {
366
+ object: objectId,
367
+ size: { width: worldW, height: worldH },
368
+ position
369
+ });
370
+ }
371
+ } catch (_) {}
372
+ }
285
373
  }
286
374
 
287
375