index.tsx 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. import { IconDelete } from "@/assets/icons";
  2. import { DesignComp } from "@/modules/editor/objects/DesignTemp/DesignComp";
  3. import { css, cx } from "@linaria/core";
  4. import { defineUI } from "queenjs";
  5. import { nextTick, onUnmounted, reactive, ref } from "vue";
  6. import { Container, Draggable } from "vue-dndrop";
  7. import { useEditor } from "../../..";
  8. import { HotKeyCtrl } from "../../../controllers/HotKeyCtrl";
  9. import { CompUI } from "../../CompUI";
  10. import { SelectTransfer } from "../../CompUI/basicUI/Transfer/select";
  11. import { TipIcons } from "../../TipIcons";
  12. import { history } from "@/modules/editor/objects/DesignTemp/factory";
  13. export default defineUI({
  14. setup() {
  15. const editor = useEditor();
  16. const { store, actions, helper, controls } = editor;
  17. const hotKeyCtrl = new HotKeyCtrl(editor);
  18. hotKeyCtrl.init();
  19. onUnmounted(() => {
  20. hotKeyCtrl.destroy();
  21. });
  22. const state = reactive({
  23. draging: false,
  24. });
  25. const NotFoundComp = () => <div>无效的组件</div>;
  26. const flagRef = ref();
  27. const containRef = ref();
  28. controls.cropCtrl.modifyCtrl.toolbars = TipIcons;
  29. const editLayerRef = ref();
  30. const refs = controls.editorCtrl.useEditor();
  31. return () => {
  32. console.log("rootId=>", controls.pageCtrl.state.rootId );
  33. const page = controls.pageCtrl;
  34. const pageRoot = helper.findRootComp();
  35. if (!pageRoot) return;
  36. // const streamCardIndex = store.streamCardIds.indexOf(
  37. // store.currStreamCardId
  38. // );
  39. if (!flagRef.value) {
  40. flagRef.value = true;
  41. setTimeout(() => {
  42. actions.onViewReady(
  43. pageRoot.$el,
  44. refs.canvas.value,
  45. refs.parent.value
  46. );
  47. helper.initEditLayer(editLayerRef.value);
  48. }, 100);
  49. }
  50. return (
  51. <div class="flex flex-1 relative">
  52. <div class={["scrollbar", cardList]}>
  53. <div>
  54. <Container
  55. class="space-y-15px mt-15px"
  56. onDrop={(e: any) => {
  57. if (e.payload) {
  58. actions.addCompToDesign(e.payload, e.addedIndex);
  59. } else {
  60. actions.moveComp(e.removedIndex, e.addedIndex);
  61. }
  62. }}
  63. >
  64. {page.streamCardIds.map((item) => {
  65. const c = helper.findComp(item) as DesignComp;
  66. const Comp =
  67. controls.compUICtrl.state.components.get(c.compKey)
  68. ?.Component || NotFoundComp;
  69. const r = c.layout.size[1] / c.layout.size[0];
  70. let h = 80 * r;
  71. if (h > 80) h = 80;
  72. if (h < 40) h = 40;
  73. const style: any = { height: h + "px" };
  74. return (
  75. <Draggable>
  76. <div
  77. key={item + controls.screenCtrl.currScreenId}
  78. class={cx(
  79. "card-item relative transition-opacity hover:opacity-80",
  80. store.currStreamCardId == item && "active"
  81. )}
  82. style={style}
  83. onClick={() => {
  84. controls.editorCtrl.clickPickComp(item);
  85. history.submit();
  86. nextTick(() => {
  87. controls.editorCtrl.autoInScreen();
  88. });
  89. }}
  90. >
  91. {page.streamCardIds.length > 1 && (
  92. <IconDelete
  93. onClick={() => {
  94. actions.removeStreamCard(item);
  95. }}
  96. class="deleteitem absolute right-4px top-4px text-light-50"
  97. />
  98. )}
  99. <div class="pointer-events-none">
  100. <Comp
  101. compId={c.id}
  102. style={{
  103. transformOrigin: "0 0",
  104. pointerEvent: "none",
  105. transform: `scale(${
  106. 80.0 / helper.designSizeToPx(c.layout.size[0])
  107. })`,
  108. }}
  109. />
  110. </div>
  111. </div>
  112. </Draggable>
  113. );
  114. })}
  115. <img
  116. class="mt-15px cursor-pointer"
  117. onClick={() => {
  118. const index = page.streamCardIds.length;
  119. actions.addCompToDesign("Container", index);
  120. history.submit();
  121. setTimeout(() => {
  122. controls.editorCtrl.autoInScreen();
  123. }, 200);
  124. }}
  125. src={require("@/assets/imgs/add.svg")}
  126. alt=""
  127. />
  128. </Container>
  129. </div>
  130. </div>
  131. <div ref={refs.parent} class={["absolute", viewportStyle]}>
  132. <div ref={refs.editor}>
  133. <div ref={refs.page} class={"select-none " + contentCls}>
  134. <CompUI.Page.Component compId={pageRoot.id}>
  135. {{
  136. Container(children: any) {
  137. return (
  138. <>
  139. <Container
  140. behaiver="drop-zone"
  141. should-accept-drop={(
  142. sourceContainerOptions: any,
  143. payload: any
  144. ) => {
  145. if (
  146. sourceContainerOptions.groupName != "canvas"
  147. ) {
  148. return false;
  149. }
  150. console.log("payload===>", "xxx", payload);
  151. if (typeof payload == "string") {
  152. controls.dragAddCtrl.updateCompKey(payload);
  153. } else {
  154. controls.dragAddCtrl.updateCompKey(
  155. payload.type
  156. );
  157. controls.dragAddCtrl.updateCompData(
  158. payload.data
  159. );
  160. }
  161. return false;
  162. }}
  163. onDrop={(e: any) => {
  164. debugger;
  165. if (e.payload) {
  166. console.log("xx a");
  167. actions.addCompToDesign(
  168. e.payload,
  169. e.addedIndex
  170. );
  171. }
  172. }}
  173. >
  174. {children}
  175. </Container>
  176. {!state.draging && <SelectTransfer />}
  177. </>
  178. );
  179. },
  180. CompItem(comp: DesignComp) {
  181. const Comp =
  182. controls.compUICtrl.state.components.get(comp.compKey)
  183. ?.Component || NotFoundComp;
  184. return (
  185. <Comp
  186. compId={comp.id}
  187. key={comp.id + controls.screenCtrl.currScreenId}
  188. showMask={true}
  189. />
  190. );
  191. },
  192. }}
  193. </CompUI.Page.Component>
  194. </div>
  195. <div class={editLayerStyle} ref={editLayerRef}></div>
  196. </div>
  197. <canvas class={selectCls} ref={refs.canvas} />
  198. {/* <div class={meatureStyle}>
  199. <div class="ruler top" id="rulerTop"></div>
  200. <div class="ruler left" id="rulerLeft"></div>
  201. <div class="ruler right" id="rulerRight"></div>
  202. <div class="ruler bottom" id="rulerBottom"></div>
  203. </div> */}
  204. </div>
  205. </div>
  206. );
  207. };
  208. },
  209. });
  210. const contentCls = css`
  211. position: absolute;
  212. .dndrop-container.vertical > .dndrop-draggable-wrapper {
  213. overflow: unset;
  214. }
  215. `;
  216. const selectCls = css`
  217. position: absolute;
  218. pointer-events: none;
  219. left: 0;
  220. top: 0;
  221. width: 100%;
  222. height: 100%;
  223. z-index: 10000;
  224. `;
  225. const meatureStyle = css`
  226. position: absolute;
  227. width: 100%;
  228. height: 100%;
  229. left: 0;
  230. top: 0px;
  231. z-index: 998;
  232. pointer-events: none;
  233. .ruler {
  234. position: absolute;
  235. cursor: ns-resize;
  236. pointer-events: auto;
  237. }
  238. .top {
  239. top: 0;
  240. left: 0px;
  241. height: 20px;
  242. width: 100%;
  243. z-index: 2;
  244. background-color: rgba(38, 38, 38, 0.8);
  245. background-image: repeating-linear-gradient(
  246. 90deg,
  247. #434343 0,
  248. #434343 1px,
  249. transparent 0,
  250. transparent 1cm
  251. ),
  252. repeating-linear-gradient(
  253. 90deg,
  254. #434343 0,
  255. #434343 1px,
  256. transparent 0,
  257. transparent 0.5cm
  258. );
  259. border-bottom: 1px solid #434343;
  260. background-position: 0.5cm 100%;
  261. background-repeat: no-repeat;
  262. background-size: 100% 15px, 100% 10px;
  263. }
  264. .bottom {
  265. bottom: 0;
  266. left: 0;
  267. height: 10px;
  268. width: 100%;
  269. }
  270. .left {
  271. top: 0;
  272. left: 0px;
  273. height: 100%;
  274. width: 20px;
  275. z-index: 1;
  276. cursor: ew-resize;
  277. border-right: 1px solid #434343;
  278. background-color: rgba(38, 38, 38, 0.8);
  279. background-image: repeating-linear-gradient(
  280. 180deg,
  281. #434343 0,
  282. #434343 1px,
  283. transparent 0,
  284. transparent 1cm
  285. ),
  286. repeating-linear-gradient(
  287. 180deg,
  288. #434343 0,
  289. #434343 1px,
  290. transparent 0,
  291. transparent 0.5cm
  292. );
  293. background-position: 100% 0.5cm;
  294. background-repeat: no-repeat;
  295. background-size: 15px 100%, 10px 100%;
  296. }
  297. .right {
  298. top: 0;
  299. right: 0;
  300. height: 100%;
  301. width: 20px;
  302. cursor: ew-resize;
  303. }
  304. `;
  305. const editLayerStyle = css`
  306. pointer-events: none;
  307. position: absolute;
  308. left: 0;
  309. top: 0;
  310. width: 100%;
  311. height: 100%;
  312. z-index: 1000;
  313. `;
  314. const cardList = css`
  315. width: 120px;
  316. height: 100%;
  317. background: #1f1f1f;
  318. overflow-x: hidden;
  319. pointer-events: auto;
  320. display: flex;
  321. flex-direction: column;
  322. align-items: center;
  323. position: absolute;
  324. padding-bottom: 120px;
  325. .card-item {
  326. flex-shrink: 0;
  327. width: 80px;
  328. height: 80px;
  329. background: #1f1f1f;
  330. border-radius: 4px 4px 4px 4px;
  331. cursor: pointer;
  332. overflow: hidden;
  333. color: white;
  334. &:before {
  335. content: "";
  336. position: absolute;
  337. left: 0;
  338. right: 0;
  339. top: 0;
  340. bottom: 0;
  341. border-radius: 4px;
  342. z-index: 1;
  343. transition: box-shadow 0.2s ease-in-out;
  344. }
  345. &.active {
  346. &:before {
  347. box-shadow: #ea9e40 0px 0px 0px 1px inset, #000 0px 0px 0px 3px inset;
  348. }
  349. }
  350. .deleteitem {
  351. z-index: 1000;
  352. opacity: 0;
  353. font-size: 20px;
  354. }
  355. &:hover {
  356. .deleteitem {
  357. opacity: 1;
  358. background: rgba(0, 0, 0, 0.8);
  359. }
  360. }
  361. }
  362. `;
  363. const viewportStyle = css`
  364. width: calc(100% - 120px);
  365. height: 100%;
  366. left: 120px;
  367. top: 0px;
  368. overflow: hidden;
  369. `;