select.tsx 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. import { IconRotate , IconMove} from "@/assets/icons";
  2. import { CompToolbars } from "@/modules/editor/objects/Toolbars";
  3. import { css } from "@linaria/core";
  4. import { defineComponent, onMounted, onUnmounted, ref, nextTick } from "vue";
  5. import { useEditor } from "../../../..";
  6. export const SelectTransfer = defineComponent({
  7. setup() {
  8. const editor = useEditor();
  9. const { controls, store } = editor;
  10. const { selectCtrl } = controls;
  11. const { transferStyle } = selectCtrl;
  12. return () => {
  13. let toolbarOpts = CompToolbars.default;
  14. let comp: any = null;
  15. if (selectCtrl.selected.length == 1) {
  16. comp = selectCtrl.selected[0].comp;
  17. //@ts-ignore
  18. toolbarOpts = CompToolbars[comp.compKey] || toolbarOpts;
  19. } else {
  20. toolbarOpts = CompToolbars.MultiSelector;
  21. }
  22. const w = selectCtrl.objContainer?.getBound();
  23. const isTextEdit = selectCtrl.selected.length == 1 && selectCtrl.selected[0].comp.compKey == "Text";
  24. return (
  25. <div
  26. class={[
  27. "absolute transfer z-998",
  28. transferStyle.showGizmo && transferStyle.mode != 2 ? showgizmo : hideGizmo,
  29. ]}
  30. style={{
  31. top: transferStyle.baseCardTop
  32. }}
  33. >
  34. <div
  35. id= "toolbar"
  36. class={toolbarStyle}
  37. style={{
  38. top: w?.y + "px",
  39. left: w?.x + "px",
  40. }}
  41. >
  42. {
  43. toolbarOpts.map((item) => {
  44. return item.getVisible.call(editor, comp) ? (
  45. <item.component
  46. class="p-4px"
  47. value={item.getValue?.(comp)}
  48. onClick={() => item.onClick.call(editor, comp)}
  49. />
  50. ) : null;
  51. })
  52. }
  53. </div>
  54. <div
  55. class={["absolute", selctRectStyle]}
  56. id="movecenter"
  57. style={{
  58. width: transferStyle.width + "px",
  59. height: transferStyle.height + "px",
  60. transform: transferStyle.matrix,
  61. transformOrigin: `0 0`,
  62. }}
  63. >
  64. <div class={borderStyle} style={{ transform: transferStyle.matrixInvert, transformOrigin: `0 0`}} >
  65. <div class={borderContentStyle} style={{width: transferStyle.relWidth + "px", height: transferStyle.relHeight + "px"}}></div>
  66. </div>
  67. <>
  68. {
  69. !isTextEdit && <div
  70. class={[resizeStyle, scaleBottomRightStyle]}
  71. style={{ transform: transferStyle.matrixInvert }}
  72. id="scaleBottomright"
  73. />
  74. }
  75. {
  76. !isTextEdit && <div
  77. class={[resizeStyle, scaleBottomLeftStyle]}
  78. style={{ transform: transferStyle.matrixInvert }}
  79. id="scaleBottomleft"
  80. />
  81. }
  82. {
  83. !isTextEdit &&<div
  84. class={[resizeStyle, scaleTopLeftStyle]}
  85. style={{ transform: transferStyle.matrixInvert }}
  86. id="scaleTopleft"
  87. />
  88. }
  89. {
  90. !isTextEdit && <div
  91. class={[resizeStyle, scaleTopRightStyle]}
  92. style={{ transform: transferStyle.matrixInvert }}
  93. id="scaleTopright"
  94. />
  95. }
  96. <div class={transformBtnsStyle} style={{ transform: transferStyle.matrixInvert }}>
  97. <div
  98. class={transBtnStyle}
  99. id="moveicon"
  100. >
  101. <IconMove />
  102. </div>
  103. <div
  104. class={transBtnStyle}
  105. id = "rotate"
  106. >
  107. <IconRotate />
  108. </div>
  109. </div>
  110. {transferStyle.showOrthScale && !isTextEdit && (
  111. <div
  112. class={[resizeHeightBtnCls, scaleTopCls]}
  113. style={{ transform: transferStyle.matrixInvert }}
  114. id="scaletop"
  115. />
  116. )}
  117. {transferStyle.showOrthScale && !isTextEdit && (
  118. <div
  119. class={[resizeHeightBtnCls, scaleBottomCls]}
  120. style={{ transform: transferStyle.matrixInvert }}
  121. id="scalebottom"
  122. />
  123. )}
  124. {transferStyle.showOrthScale && (
  125. <div
  126. class={[resizeWidthBtnCls, scaleRightCls]}
  127. style={{ transform: transferStyle.matrixInvert }}
  128. id="scaleright"
  129. />
  130. )}
  131. {transferStyle.showOrthScale && (
  132. <div
  133. class={[resizeWidthBtnCls, scaleLeftCls]}
  134. style={{ transform: transferStyle.matrixInvert }}
  135. id="scaleleft"
  136. />
  137. )}
  138. </>
  139. </div>
  140. </div>
  141. );
  142. };
  143. },
  144. });
  145. const selctRectStyle = css`
  146. pointer-events: none;
  147. `;
  148. const showgizmo = css`
  149. display: block;
  150. left: 0;
  151. top: 0;
  152. /* pointer-events: none; */
  153. `;
  154. const hideGizmo = css`
  155. display: none;
  156. `;
  157. const borderStyle = css`
  158. position: absolute;
  159. top: 0;
  160. left: 0;
  161. width: 100%;
  162. height: 100%;
  163. pointer-events: none;
  164. z-index: 999;
  165. `;
  166. const borderContentStyle = css`
  167. position: absolute;
  168. top: 0;
  169. left: 0;
  170. width: 100%;
  171. height: 100%;
  172. outline: 2px solid @inf-primary-color;
  173. `
  174. const resizeStyle = css`
  175. position: absolute;
  176. width: 16px;
  177. height: 16px;
  178. border-radius: 50%;
  179. background-color: #fff;
  180. z-index: 999;
  181. transform: translate(50%, 50%);
  182. pointer-events: auto;
  183. box-shadow: 0 0 2px 2px rgba(0, 0, 0, 0.2);
  184. cursor: nwse-resize;
  185. &:hover {
  186. border-color: @inf-primary-color;
  187. }
  188. `;
  189. const scaleBottomRightStyle = css`
  190. bottom: -8px;
  191. right: -8px;
  192. `;
  193. const scaleBottomLeftStyle = css`
  194. bottom: -8px;
  195. left: -8px;
  196. `;
  197. const scaleTopLeftStyle = css`
  198. top: -8px;
  199. left: -8px;
  200. `;
  201. const scaleTopRightStyle = css`
  202. top: -8px;
  203. right: -8px;
  204. `;
  205. const transformBtnsStyle = css`
  206. @apply space-x-10px whitespace-nowrap;
  207. position: absolute;
  208. bottom: 0px;
  209. left:calc(50% - 32px);
  210. font-size: 16px;
  211. z-index: 999;
  212. pointer-events: auto;
  213. transform-origin: 50% 100%;
  214. pointer-events: none;
  215. `;
  216. const transBtnStyle = css`
  217. display: inline-block;
  218. width: 28px;
  219. height: 28px;
  220. border-radius: 50%;
  221. background-color: #fff;
  222. text-align: center;
  223. line-height: 28px;
  224. font-size: 16px;
  225. color: #333;
  226. position: relative;
  227. top: 50px;
  228. @apply shadow cursor-move;
  229. pointer-events: auto;
  230. &:hover {
  231. color: #fff;
  232. background-color: @inf-primary-color;
  233. }
  234. `;
  235. const toolbarStyle = css`
  236. @apply bg-white shadow rounded space-x-4px p-4px whitespace-nowrap;
  237. position: absolute;
  238. top: 0;
  239. left: 50%;
  240. transform: translate(0%, -60px);
  241. z-index: 999;
  242. `;
  243. const resizeHeightBtnCls = css`
  244. position: absolute;
  245. width: 30px;
  246. height: 8px;
  247. border-radius: 4px;
  248. left: 50%;
  249. transform: translate(-50%, -4px);
  250. pointer-events: auto;
  251. cursor: ns-resize;
  252. background: rgba(255, 255, 255, 0.3);
  253. &:hover {
  254. background: @inf-primary-color;
  255. }
  256. @apply shadow;
  257. z-index: 999;
  258. `;
  259. const scaleTopCls = css`
  260. top: -4px;
  261. left: calc(50% - 15px);
  262. `;
  263. const scaleBottomCls = css`
  264. bottom:-4px;
  265. left: calc(50% - 15px);
  266. `;
  267. const resizeWidthBtnCls = css`
  268. position: absolute;
  269. width: 8px;
  270. height: 30px;
  271. border-radius: 4px;
  272. pointer-events: auto;
  273. cursor: ew-resize;
  274. background: rgba(255, 255, 255, 0.3);
  275. &:hover {
  276. background: @inf-primary-color;
  277. }
  278. @apply shadow;
  279. z-index: 999;
  280. `;
  281. const scaleRightCls = css`
  282. right: -4px;
  283. top: calc(50% - 15px);
  284. `;
  285. const scaleLeftCls = css`
  286. left: -4px;
  287. top: calc(50% - 15px);
  288. `;