index.vue 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905
  1. <template>
  2. <div class="editor">
  3. <!-- 头部 -->
  4. <HeaderMain></HeaderMain>
  5. <HeaderEdit
  6. :title="title"
  7. :shareModel="shareModel"
  8. :goback="dialogSave"
  9. :save="save"
  10. :zoom="zoom"
  11. :zoomNum="zoomNum"
  12. @saveThemeSuccess="showPreView=true"
  13. />
  14. <!-- 内容区域 -->
  15. <section class="section">
  16. <!-- 左侧图层 -->
  17. <Overview
  18. ref="overview"
  19. class="overview"
  20. :testcaseId="testcaseId"
  21. :resultCount="resultPageCount"
  22. :questions="questions"
  23. />
  24. <!-- 编辑区域 -->
  25. <div class="edit-area">
  26. <div
  27. class="container"
  28. id="h5editor"
  29. :style="{transform:`scale(${zoomNum},${zoomNum})`+`translate(${translateX}px,${translateY}px)`}"
  30. >
  31. <elab-canvas
  32. v-show="animatedNameGlobal!=''"
  33. :width="750"
  34. :height="1334"
  35. :cstyle="`height:1334px;width:750px;position: absolute;z-index:99999; pointer-events:none`"
  36. :background="'transparent'"
  37. :type="animatedNameGlobal"
  38. ></elab-canvas>
  39. <elab-background-canvas
  40. v-if="animatedNameBackgroundGlobal!=''"
  41. :width="canvasWidth"
  42. :height="(canvasHeight)"
  43. :cstyle="`position: absolute;z-index:1; pointer-events:none`"
  44. :background="'transparent'"
  45. :type="animatedNameBackgroundGlobal"
  46. ></elab-background-canvas>
  47. <Page
  48. :isOverView="false"
  49. ref="page"
  50. id="canvasPage"
  51. :hideFoot="hideFoot"
  52. class="canvas"
  53. :elements="editorPage.elements"
  54. :editorElement="element"
  55. :animatedNameGlobal="animatedNameGlobal"
  56. :selectedElement="selectedElement"
  57. :style="{ width: 750 + 'px', height: 1334 + 'px',backgroundColor: bodyBackgroundColor }"
  58. />
  59. <div
  60. v-if="this.gridTempField"
  61. :style="{'background-image':'linear-gradient(90deg,rgba(204,204,204,0.3) 10%,transparent 0), linear-gradient(rgba(204,204,204,0.3) 10%,transparent 0)',
  62. 'background-size':'15px 15px', 'z-index':100000,width: '750px', height: '1334px'}"
  63. style="position: absolute;left: 0;top: 0;z-index: 9999;pointer-events: none"
  64. ></div>
  65. </div>
  66. </div>
  67. <!-- 属性设置 -->
  68. <div class="control-panel">
  69. <div class="funcs">
  70. <div class="tagPage">
  71. <div
  72. style="width:44px;height: 44px; margin-top: 20px;display: flex;justify-content: center"
  73. @click="togglePanel(1)"
  74. :class="{ active: panelState === 1 }"
  75. >
  76. <div class="page-create-txt" :class="{ active: panelState === 1 }"></div>
  77. </div>
  78. <div class="page-tag-btn-tip">创建文本</div>
  79. </div>
  80. <div class="tagPage">
  81. <div
  82. style="width:44px;height: 44px;display: flex;justify-content: center"
  83. @click="togglePanel(2)"
  84. :class="{ active: panelState === 2 }"
  85. >
  86. <div class="page-create-btn" :class="{ active: panelState === 2 }"></div>
  87. </div>
  88. <div class="page-tag-btn-tip">装饰元素</div>
  89. </div>
  90. <div class="tagPage">
  91. <div
  92. style="width:44px;height: 44px;display: flex;justify-content: center"
  93. @click="togglePanel(3)"
  94. :class="{ active: panelState === 3 }"
  95. >
  96. <div class="page-create-lunbo" :class="{ active: panelState === 3 }"></div>
  97. </div>
  98. <div class="page-tag-btn-tip">新建轮播</div>
  99. </div>
  100. <div class="tagPage">
  101. <div
  102. style="width:44px;height: 44px;display: flex;justify-content: center"
  103. @click="togglePanel(4)"
  104. :class="{ active: panelState === 4 }"
  105. >
  106. <div class="page-create-jiaohuanniu" :class="{ active: panelState === 4 }"></div>
  107. </div>
  108. <div class="page-tag-btn-tip">交互按钮</div>
  109. </div>
  110. <el-tooltip v-show="false" effect="dark" content="保存" placement="left">
  111. <div
  112. style="width:44px;height: 44px;display: flex;justify-content: center"
  113. @click="save"
  114. >
  115. <img
  116. style="width:34px;height: 34px;"
  117. src="http://yun-image.elab-plus.com/images/dyb/new-jiaohuanniu.png"
  118. alt
  119. />
  120. </div>
  121. </el-tooltip>
  122. </div>
  123. <div class="wrapper custom-scrollbar">
  124. <!-- 设置背景 0 -->
  125. <div class="panel panel-bg">
  126. <div class="clearfix" v-if="panelTabState !== 1 && panelTabState !== 3">
  127. <div
  128. style="display: flex;flex-direction: row;justify-content: space-between; padding:23px;border-bottom: #E2E4EE solid 1px;"
  129. >
  130. <div
  131. style="width:45%;
  132. height:28px;
  133. text-align: center;
  134. background:rgba(78,93,255,1);
  135. border-radius:14px;font-size:14px;
  136. font-family:MicrosoftYaHei;
  137. color:rgba(255,255,255,1);
  138. line-height:28px;"
  139. @click="cleanBG"
  140. >移除背景</div>
  141. <div
  142. style="width:45%;height:28px;text-align: center;background:rgba(78,93,255,1);border-radius:14px;font-size:14px;
  143. font-family:MicrosoftYaHei;color:rgba(255,255,255,1);line-height:28px;"
  144. @click="panelTabState = 1"
  145. >更换背景</div>
  146. </div>
  147. <div
  148. style="display: flex;flex-direction: row;align-items: center;padding-left: 23px;border-bottom: #E2E4EE solid 1px;padding-top: 11px;padding-bottom: 11px;"
  149. >
  150. <label
  151. style="font-size:12px;
  152. font-family:MicrosoftYaHei;
  153. color:rgba(51,51,51,1);
  154. margin-right: 10px;
  155. "
  156. >画布背景色</label>
  157. <el-color-picker
  158. v-model="bodyBackgroundColor"
  159. @change="bodyBackgroundColorChange"
  160. size="mini"
  161. ></el-color-picker>
  162. </div>
  163. <div
  164. style="display: flex;flex-direction: row ;padding-left: 23px;padding-top: 12px;padding-bottom: 12px;border-bottom: #E2E4EE solid 1px;"
  165. >
  166. <div style="display: flex;flex-direction: column;">
  167. <label
  168. style="font-size:12px;
  169. font-family:MicrosoftYaHei;
  170. color:rgba(51,51,51,1); margin-bottom: 6px;"
  171. >画布宽度</label>
  172. <el-input-number
  173. v-model="canvasWidth"
  174. :disabled="true"
  175. size="small"
  176. style="width:110px;"
  177. ></el-input-number>
  178. </div>
  179. <div style="display: flex;flex-direction: column; margin-left:45px">
  180. <label
  181. style="font-size:12px;
  182. font-family:MicrosoftYaHei;
  183. color:rgba(51,51,51,1); margin-bottom: 6px;"
  184. >画布高度</label>
  185. <el-input-number v-model="canvasHeight" size="small" style="width:110px;"></el-input-number>
  186. </div>
  187. </div>
  188. <div
  189. class="clearfix"
  190. v-if="panelTabState !== 1 && panelTabState !== 3"
  191. style="border-bottom: #E2E4EE solid 1px; padding-top:010px;padding-bottom:2px;
  192. padding-left:23px;
  193. "
  194. >
  195. <label
  196. style="font-size:12px;
  197. font-family:MicrosoftYaHei; display:block;
  198. color:rgba(51,51,51,1);margin-bottom:10px;"
  199. >屏飘动效</label>
  200. <div class="content" :xxx="`animatedNameGlobal`">
  201. <div
  202. style="display: inline-flex;overflow: hidden;text-align: center; cursor: pointer; margin-right:12px;"
  203. v-for="(item,index) in animateGlobalList"
  204. >
  205. <div
  206. v-model="animatedNameGlobal"
  207. @click="checkGlobalAnimation(item)"
  208. :title="item.name"
  209. :style="{'background':'rgba(238,242,250,1)',
  210. 'border-radius':'12px', 'margin-bottom':'10px',
  211. 'border':'1px solid rgba(205,209,221,1)','font-size': '12px',
  212. color: animatedNameGlobal==item.id? 'white':'#999999','letter-spacing': 0,
  213. 'word-break':'keep-all',padding: '4px 13px','background': animatedNameGlobal===item.id? '#4E5DFF':'rgba(238,242,250,1)',
  214. 'border': animatedNameGlobal===item.id? '1px solid #4E5DFF':'1px solid rgba(205,209,221,1)',
  215. }"
  216. >{{item.name}}</div>
  217. </div>
  218. </div>
  219. </div>
  220. <div
  221. class="clearfix"
  222. v-if="panelTabState !== 1 && panelTabState !== 3"
  223. style="border-bottom: #E2E4EE solid 1px; padding-top:010px;padding-bottom:2px;
  224. padding-left:23px;"
  225. >
  226. <label
  227. style="font-size:12px;
  228. font-family:MicrosoftYaHei; display:block;
  229. color:rgba(51,51,51,1);margin-bottom:10px;"
  230. >背景动效</label>
  231. <div class="content" :xxx="`animatedNameBackgroundGlobal`">
  232. <div
  233. style="display: inline-flex;overflow: hidden;text-align: center; cursor: pointer"
  234. v-for="(item,index) in animateBackgroundGlobalList"
  235. >
  236. <div
  237. v-model="animatedNameBackgroundGlobal"
  238. @click="checkBackgroundGlobalAnimation(item)"
  239. :title="item.name"
  240. :style="{'background':'rgba(238,242,250,1)', 'margin-right':'12px',
  241. 'border-radius':'12px', 'margin-bottom':'10px',
  242. 'border':'1px solid rgba(205,209,221,1)','font-size': '12px',
  243. color: animatedNameBackgroundGlobal==item.id? 'white':'#999999','letter-spacing': 0,
  244. 'word-break':'keep-all',padding: '4px 13px','background': animatedNameBackgroundGlobal===item.id? '#4E5DFF':'rgba(238,242,250,1)',
  245. 'border': animatedNameBackgroundGlobal===item.id? '1px solid #4E5DFF':'1px solid rgba(205,209,221,1)'}"
  246. >{{item.name}}</div>
  247. </div>
  248. </div>
  249. </div>
  250. <div class="item" style="padding:10px 23px;">
  251. <label
  252. style="font-size:12px;
  253. font-family:MicrosoftYaHei;
  254. color:rgba(51,51,51,1);"
  255. >背景音乐</label>
  256. <div class="content">
  257. <AudioPanel class="ele"></AudioPanel>
  258. </div>
  259. </div>
  260. </div>
  261. <!--<div class="clearfix">
  262. <label>设置作品信息</label>
  263. <div class="content">
  264. <el-input
  265. placeholder="请输入标题"
  266. v-model="title"
  267. clearable>
  268. </el-input>
  269. </div>
  270. <div class="content">
  271. <el-input
  272. placeholder="请输入描述"
  273. v-model="description"
  274. clearable>
  275. </el-input>
  276. </div>
  277. </div>-->
  278. <div class="clearfix" v-if="panelTabState === 1">
  279. <ImgPanel :selectedImg="addBG" />
  280. </div>
  281. <div class="clearfix" v-if="panelTabState === 3">
  282. <div style="margin-top: 5px; height:100%;vertical-align: middle;padding-right:10px">
  283. <div style="display: inline-flex; overflow: hidden;">
  284. <div
  285. style="font-size: 14px;color: #999999;letter-spacing: 0; word-break:keep-all;width:100%"
  286. >组合对齐布局</div>
  287. </div>
  288. <div style="margin-top: 10px">
  289. <div
  290. style="display: inline-flex; overflow: hidden;width: 14%; cursor: pointer; text-align: center"
  291. >
  292. <div
  293. @click="toLeft"
  294. title="左对齐"
  295. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  296. >
  297. <img
  298. src="http://yun-image.elab-plus.com/images/tfb/icon_left2.png"
  299. width="20"
  300. height="20"
  301. />
  302. </div>
  303. </div>
  304. <div
  305. title="水平居中对齐"
  306. style="display: inline-flex; overflow: hidden;width: 14%; cursor: pointer;text-align: center"
  307. @click="toCenter"
  308. >
  309. <div
  310. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  311. >
  312. <img
  313. src="http://yun-image.elab-plus.com/images/tfb/horizontal_center.png"
  314. width="20"
  315. height="20"
  316. />
  317. </div>
  318. </div>
  319. <div
  320. title="右对齐"
  321. style="display: inline-flex;cursor: pointer;width: 14%; text-align: center"
  322. @click="toRight"
  323. >
  324. <div
  325. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  326. >
  327. <img
  328. src="http://yun-image.elab-plus.com/images/tfb/icon_right2.png"
  329. width="20"
  330. height="20"
  331. />
  332. </div>
  333. </div>
  334. <div
  335. style="display: inline-flex; overflow: hidden;width: 14%; cursor: pointer; text-align: center"
  336. >
  337. <div
  338. @click="toTop"
  339. title="上对齐"
  340. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  341. >
  342. <img
  343. src="http://yun-image.elab-plus.com/images/tfb/icon_top.png"
  344. width="20"
  345. height="20"
  346. />
  347. </div>
  348. </div>
  349. <div
  350. title="垂直居中对齐"
  351. style="display: inline-flex; overflow: hidden;width: 14%; cursor: pointer;text-align: center"
  352. @click="toVertialCenter"
  353. >
  354. <div
  355. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  356. >
  357. <img
  358. src="http://yun-image.elab-plus.com/images/tfb/vertical_center.png"
  359. width="20"
  360. height="20"
  361. />
  362. </div>
  363. </div>
  364. <div
  365. title="下对齐"
  366. style="display: inline-flex;cursor: pointer;width: 14%; text-align: center"
  367. @click="toBottom"
  368. >
  369. <div
  370. :style="{'font-size': '12px','letter-spacing': 0, 'word-break':'keep-all','text-align':'center','width':'100%'}"
  371. >
  372. <img
  373. src="http://yun-image.elab-plus.com/images/tfb/icon_down.png"
  374. width="20"
  375. height="20"
  376. />
  377. </div>
  378. </div>
  379. </div>
  380. </div>
  381. </div>
  382. </div>
  383. <!-- 添加文字 1 -->
  384. <div class="panel panel-text" v-show="panelState === 1">
  385. <div
  386. class="btn"
  387. @click="addTextElement('title')"
  388. style="font-size: 32px; font-weight: bold;"
  389. >插入标题</div>
  390. <div class="btn" @click="addTextElement('plain')">插入文本</div>
  391. <div class="btn" @click="addTextElement('frame')">插入方框</div>
  392. </div>
  393. <!-- 添加元素 2 -->
  394. <div class="panel panel-element clearfix" v-show="panelState === 2">
  395. <ImgPanel :selectedImg="addPicElement" :themeId="itemId" :isButton="false" />
  396. </div>
  397. <!-- 添加多图上元素 3 -->
  398. <div class="panel panel-element clearfix" v-if="panelState === 3">
  399. <ImgPanel :selectedImg="addMorePicElement" :ismultiple="true" />
  400. </div>
  401. <!-- 添加按钮 4 -->
  402. <div class="panel panel-element clearfix" v-if="panelState === 4">
  403. <ImgPanel
  404. :selectedImg="addButtonElement"
  405. :themeId="itemId"
  406. :isButton="true"
  407. :showSelectedPicOrUnSelectedPic="uploadSelectedPicOrUnSelectedPic"
  408. />
  409. </div>
  410. <!-- 图层编辑面板 -->
  411. <EditPanel
  412. :element="element"
  413. :panelState="panelState"
  414. v-if="panelState > 10"
  415. :showSelectedPicOrUnSelectedPic="changeSelectedPicOrUnSelectedPic"
  416. :changeCurrentImg="changeCurrentImg"
  417. />
  418. </div>
  419. </div>
  420. </section>
  421. <PreView :itemId="itemId" @hideView="showPreView=false" v-if="showPreView" />
  422. <div v-show="dialogVisible" class="dialog">
  423. <div
  424. style="width:560px;height: 353px;background:rgba(255,255,255,1);
  425. box-shadow:0px 5px 11px 0px rgba(78,93,255,0.42); margin:0 auto; margin-top:10%;
  426. border-radius:6px;"
  427. >
  428. <div
  429. style="width:560px;
  430. height:34px;
  431. display: flex;
  432. flex-direction: row;
  433. justify-content: space-between;
  434. align-items: center;
  435. background:rgba(78,93,255,1);
  436. border-radius:6px 6px 0px 0px;"
  437. >
  438. <span
  439. style="font-size:16px;
  440. font-family:PingFangSC;
  441. font-weight:400;
  442. color:rgba(255,255,255,1); margin-left:20px;
  443. line-height:34px;"
  444. >上传按钮样式</span>
  445. <img
  446. src="../../assets/images/close-icon.png"
  447. @click="closeUploadButton"
  448. style="width: 16px; height: 16px; margin-right: 10px; cursor: pointer;"
  449. />
  450. </div>
  451. <div
  452. style="display: flex;flex-direction: row; justify-content: center;margin-top:42px;margin-bottom:40px; align-items: center"
  453. >
  454. <div
  455. style="width:130px; display: flex;
  456. flex-direction: column; align-items: center;
  457. "
  458. >
  459. <span
  460. style="font-size:14px;
  461. font-family:MicrosoftYaHei;display:block;
  462. color:rgba(51,51,51,1); margin-bottom:14px;
  463. line-height:19px;"
  464. >默认状态</span>
  465. <div
  466. v-if="unSelectedButtom"
  467. :style="{ backgroundImage: 'url(' + buttonData.backgroundUnselectedImg + ')','width':'130px', 'height':'130px','background-repeat': 'no-repeat',
  468. 'background-position': 'center',
  469. 'background-size': 'contain'}"
  470. style="position: relative"
  471. >
  472. <div
  473. style="font-size:12px;width: 100%; height: 20px;
  474. font-family:MicrosoftYaHei;
  475. color:rgba(255,255,255,1);
  476. background:rgba(0,0,0,0.8);
  477. display: flex; position: absolute;
  478. bottom: 0;
  479. justify-content: center;
  480. line-height:20px;"
  481. >更换素材</div>
  482. <label class="lable">
  483. <input style="display: none;" type="file" @change="upload($event, false)" />
  484. </label>
  485. </div>
  486. <label class="lable" v-else>
  487. <div
  488. style="width:100%;
  489. display: flex;
  490. flex-direction: column;
  491. justify-content: center;
  492. align-items: center;
  493. height:100%;
  494. border:1px dashed rgba(100,107,129,1);"
  495. >
  496. <img
  497. style="width:16px;
  498. height:16px;"
  499. src="../../assets/images/add-ele.png"
  500. />
  501. <span
  502. style="font-size:12px;
  503. font-family:PingFangSC-Regular;
  504. font-weight:400;
  505. margin-top: 6px;
  506. color:rgba(51,51,51,1);
  507. line-height:17px;"
  508. >上传素材</span>
  509. </div>
  510. <input
  511. style="display: none;"
  512. type="file"
  513. multiple
  514. @change="changeSelectedPicOrUnSelectedPic($event, true)"
  515. />
  516. </label>
  517. </div>
  518. <img
  519. src="../../assets/images/changeImg.png"
  520. alt
  521. style="width:32px; height:32px; margin-left:30px;margin-right:30px;"
  522. @click="changeImg"
  523. />
  524. <div
  525. style="width:130px; display: flex;
  526. flex-direction: column; align-items: center;
  527. "
  528. >
  529. <span
  530. style="font-size:14px;
  531. font-family:MicrosoftYaHei;display:block;
  532. color:rgba(51,51,51,1);margin-bottom:14px;
  533. line-height:19px;"
  534. >选中状态</span>
  535. <div
  536. v-if="selectedButtom"
  537. :style="{ backgroundImage: 'url(' + buttonData.backgroundSelectedImg + ')','width':'130px', 'height':'130px','background-repeat': 'no-repeat',
  538. 'background-position': 'center',
  539. 'background-size': 'contain'}"
  540. style="position: relative"
  541. >
  542. <div
  543. style="font-size:12px;width: 100%; height: 20px;
  544. font-family:MicrosoftYaHei;
  545. color:rgba(255,255,255,1);
  546. background:rgba(0,0,0,0.8);
  547. display: flex; position: absolute;
  548. bottom: 0;
  549. justify-content: center;
  550. line-height:20px;"
  551. >更换素材</div>
  552. <label class="lable">
  553. <input style="display: none;" type="file" @change="upload($event, true)" />
  554. </label>
  555. </div>
  556. <label class="lable" v-else>
  557. <div
  558. style="width:100%;
  559. display: flex;
  560. flex-direction: column;
  561. justify-content: center;
  562. align-items: center;
  563. height:100%;
  564. border:1px dashed rgba(100,107,129,1);"
  565. >
  566. <img
  567. style="width:16px;
  568. height:16px;"
  569. src="../../assets/images/add-ele.png"
  570. />
  571. <span
  572. style="font-size:12px;
  573. font-family:PingFangSC-Regular;
  574. font-weight:400;
  575. margin-top: 6px;
  576. color:rgba(51,51,51,1);
  577. line-height:17px;"
  578. >上传素材</span>
  579. </div>
  580. <input
  581. style="display: none;"
  582. type="file"
  583. multiple
  584. @change="changeSelectedPicOrUnSelectedPic($event, true)"
  585. />
  586. </label>
  587. </div>
  588. </div>
  589. <div
  590. style="width:105px;
  591. height:34px;margin:0 auto;
  592. background:rgba(78,93,255,1);
  593. border-radius:19px;font-size:14px;
  594. font-family:PingFangSC;
  595. font-weight:500; text-align: center;
  596. color:rgba(255,255,255,1);
  597. line-height:34px;cursor: pointer;"
  598. @click="uploadButton"
  599. >确定</div>
  600. <span
  601. v-if="canSave"
  602. style="font-size:12px;
  603. font-family:MicrosoftYaHei;display: inline-block;margin-top: 10px;
  604. color:rgba(255,0,0,1); width: 100%; text-align: center;
  605. line-height:16px;"
  606. >*两种状态都上传素材后才能保存</span>
  607. </div>
  608. </div>
  609. </div>
  610. </template>
  611. <script>
  612. import tools from "../../util/tools";
  613. import Overview from "./overview";
  614. import Page from "../../components/Page";
  615. import PicPicker from "../../components/PicturePicker";
  616. import PreView from "../../components/PreView";
  617. import HeaderEdit from "../../components/HeaderEdit";
  618. import EditPanel from "../../components/EditPanel";
  619. import SvgPanel from "../../components/SvgPanel";
  620. import ImgPanel from "../../components/ImgPanel";
  621. import appConst from "../../util/appConst";
  622. import html2canvas from "html2canvas";
  623. import { uploadBase64 } from "../../util/http";
  624. import elabCanvas from "../../util/canvas/elabCanvas.vue";
  625. import elabBackgroundCanvas from "../../util/canvas/elabBackgroundCanvas";
  626. import AudioPanel from "../../components/AudioPanel";
  627. import HeaderMain from "../../components/HeaderMain";
  628. import * as http from "../../util/http";
  629. const $ = require("jquery");
  630. export default {
  631. data() {
  632. return {
  633. itemId: null,
  634. testcaseId: null,
  635. questions: [],
  636. panelState: 0,
  637. canvasWidth: 750,
  638. canvasHeight: 504,
  639. bodyBackgroundColor: "rgba(255,255,255,0)",
  640. bgc: "#B1C096",
  641. btnColor: "#5f8a61",
  642. title: "标题",
  643. description: "描述",
  644. dialogSaveBeforeBack: false,
  645. picBase64: "",
  646. http: appConst.BACKEND_DOMAIN,
  647. releaseUrl: "",
  648. showPreView: false,
  649. isLoadingPreview: false,
  650. panelTabState: 0,
  651. animatedNameGlobal: "",
  652. shareModel: null,
  653. resultPageCount: 0,
  654. animateGlobalList: [
  655. { id: "Snow", name: "下雪", type: 0 },
  656. { id: "Bubble", name: "冒泡", type: 0 },
  657. { id: "Flower", name: "樱花", type: 0 },
  658. { id: "Rain", name: "下雨", type: 0 },
  659. { id: "Bubble2", name: "飞沙", type: 0 },
  660. { id: "Particles", name: "粒子", type: "0" },
  661. { id: "Circle", name: "圆圈", type: "0" },
  662. { id: "FlowField", name: "流场", type: "0" },
  663. { id: "cloud", name: "云飘", type: "0" },
  664. { id: "nephelo", name: "雾霾", type: "0" }
  665. ],
  666. animateBackgroundGlobalList: [
  667. { id: "Smoke", name: "烟雾", type: 1 },
  668. { id: "Wave", name: "波浪", type: 2 },
  669. // {id: 'WaterRipple', name: '水波', type: 3},
  670. { id: "Bubble2", name: "飞沙", type: 0 },
  671. { id: "Particles", name: "粒子", type: "0" },
  672. { id: "Circle", name: "圆圈", type: "0" },
  673. { id: "FlowField", name: "流场", type: "0" },
  674. { id: "ColorRandom", name: "渐变色", type: "0" }
  675. ],
  676. animatedNameBackgroundGlobal: "",
  677. animatedBackgroundCustom: false,
  678. globalAnimatedBackgroundTag: false,
  679. dialogVisible: false,
  680. buttonData: {},
  681. unSelectedButtom: false,
  682. selectedButtom: false,
  683. canSave: false,
  684. zoomNum: 1,
  685. translateX: 360,
  686. translateY: 100
  687. };
  688. },
  689. watch: {
  690. element() {
  691. let ele = this.$store.state.editor.editorElement;
  692. let type = ele ? ele.type : "null";
  693. this.panelTabState = 0;
  694. var length = this.$store.state.editor.complexEditorElement.length;
  695. if (length > 1) {
  696. type = "group";
  697. this.panelTabState = 3;
  698. }
  699. switch (type) {
  700. case "text":
  701. this.panelState = 11;
  702. break;
  703. case "icon":
  704. case "pic":
  705. this.panelState = 12;
  706. break;
  707. case "audio":
  708. this.panelState = 12;
  709. break;
  710. case "morePic":
  711. this.panelState = 13;
  712. break;
  713. case "frame":
  714. this.panelState = 14;
  715. break;
  716. case "button":
  717. this.panelState = 15;
  718. break;
  719. case "group":
  720. this.panelState = 0;
  721. default:
  722. this.panelState = 0;
  723. }
  724. },
  725. "$store.state.editor.complexEditorElement": function() {
  726. var complexEditorElement = this.$store.state.editor.complexEditorElement;
  727. if (complexEditorElement.length == 0 && this.panelTabState == 3) {
  728. this.panelTabState = 0;
  729. }
  730. }
  731. },
  732. computed: {
  733. themeId() {
  734. return this.$store.state.editor.editorTheme._id;
  735. },
  736. editorPage() {
  737. this.shareModel = {
  738. id: this.itemId,
  739. testcaseId: this.testcaseId,
  740. shareTitle: this.$store.state.editor.editorTheme.shareTitle,
  741. shareContent: this.$store.state.editor.editorTheme.shareContent,
  742. shareImg: this.$store.state.editor.editorTheme.shareImg,
  743. shareUrl: this.$store.state.editor.editorTheme.shareUrl
  744. };
  745. this.resultPageCount = this.$store.state.editor.editorTheme.resultPageCount;
  746. this.bgc = this.$store.state.editor.editorTheme.bgc || "#B1C096";
  747. this.btnColor =
  748. this.$store.state.editor.editorTheme.btnColor || "#5f8a61";
  749. this.bodyBackgroundColor =
  750. this.$store.state.editor.editorTheme.bodyBackgroundColor ||
  751. "rgba(255,255,255,0)";
  752. this.canvasWidth =
  753. this.$store.state.editor.editorTheme.canvasWidth || 750;
  754. this.canvasHeight = this.$store.state.editor.editorTheme.canvasHeight;
  755. this.description = this.$store.state.editor.editorTheme.description;
  756. this.animatedNameGlobal =
  757. this.$store.state.editor.editorTheme.animatedNameGlobal || "";
  758. this.animatedNameBackgroundGlobal =
  759. this.$store.state.editor.editorTheme.animatedNameBackgroundGlobal || "";
  760. this.title = this.$store.state.editor.editorTheme.title;
  761. this.gridTempField = this.$store.state.editor.gridTempField;
  762. var pages = this.$store.state.editor.editorTheme.pages || [];
  763. console.log("每页数据", pages);
  764. this.questions = [];
  765. for (var i = 1; i < pages.length; i++) {
  766. if (pages[i].questions) {
  767. console.log("每页数据", pages[i].questions);
  768. var result = pages[i].questions.map(function(a) {
  769. return a.questionId;
  770. });
  771. this.questions.push(result);
  772. } else {
  773. this.questions.push([]);
  774. }
  775. }
  776. console.log("拼接数据", this.questions);
  777. return this.$store.state.editor.editorPage;
  778. },
  779. element() {
  780. let ele = this.$store.state.editor.editorElement;
  781. return ele || {};
  782. },
  783. hideFoot() {
  784. let pages = this.$store.state.editor.editorTheme.pages || [];
  785. let index = pages.indexOf(this.editorPage);
  786. return index == pages.length - 1 ? false : true;
  787. },
  788. complexEditorElement() {
  789. return this.$store.state.editor.complexEditorElement;
  790. }
  791. },
  792. methods: {
  793. async changeCurrentImg(event, num) {
  794. var that = this;
  795. let files = event.target.files;
  796. if (!files.length) {
  797. return false;
  798. }
  799. const loading = this.$loading({
  800. lock: true,
  801. text: "Loading",
  802. spinner: "el-icon-loading",
  803. background: "rgba(0, 0, 0, 0.7)"
  804. });
  805. for (var i = 0; i < files.length; i++) {
  806. var file = files[i];
  807. if (file) {
  808. if (files.length == 1 && i == 0) {
  809. http.uploadMaterielFile(
  810. file,
  811. function(res) {
  812. let img = document.createElement("img");
  813. loading.close();
  814. img.onload = () => {
  815. that.element.width = img.width;
  816. that.element.height = img.height;
  817. if (num == 1) {
  818. that.element.backgroundUnselectedImg = res;
  819. } else if (num == 2) {
  820. that.element.backgroundSelectedImg = res;
  821. }
  822. };
  823. img.src = res;
  824. },
  825. function(res) {
  826. if (res.total.percent == 100) {
  827. loading.close();
  828. }
  829. }
  830. );
  831. }
  832. }
  833. }
  834. },
  835. zoom(isAdd) {
  836. var zooms = [0.2, 0.3, 0.5, 0.75, 0.8, 0.9, 1, 1.2, 1.5, 2, 3, 4];
  837. var translateYs = [80, 80, 80, 80, 80, 90, 100, 150, 200, 250, 300, 330];
  838. if (isAdd) {
  839. if (this.zoomNum <= 3) {
  840. this.zoomNum = zooms[zooms.indexOf(this.zoomNum) + 1];
  841. this.translateY = translateYs[zooms.indexOf(this.zoomNum)];
  842. }
  843. } else {
  844. if (this.zoomNum > 0.2) {
  845. this.zoomNum = zooms[zooms.indexOf(this.zoomNum) - 1];
  846. this.translateY = translateYs[zooms.indexOf(this.zoomNum)];
  847. }
  848. }
  849. },
  850. dialogSave() {
  851. // return Promise.resolve().then(() => this.save()).then(() => this.$router.replace('themeList'))
  852. if (!window.hasSaveFlag) {
  853. this.$confirm(
  854. "请确保已经将修改的内容保存,否则页面将丢失。是否确认退出编辑?",
  855. "提示",
  856. {
  857. confirmButtonText: "确定",
  858. cancelButtonText: "取消",
  859. type: "warning"
  860. }
  861. )
  862. .then(() => {
  863. window.hasSaveFlag = true;
  864. return Promise.resolve().then(() =>
  865. this.$router.replace("myHistoryTest")
  866. );
  867. })
  868. .catch(() => {});
  869. } else {
  870. return Promise.resolve().then(() =>
  871. this.$router.replace("myHistoryTest")
  872. );
  873. }
  874. },
  875. getPicList(_id) {
  876. this.$store.dispatch("getPicListByThemeId", _id);
  877. },
  878. addPicElement(ele) {
  879. // if (ele) {
  880. let obj = {};
  881. obj.type = "pic";
  882. obj.top = document.getElementById("h5editor").scrollTop;
  883. obj.left = 0;
  884. obj.width = ele.width;
  885. obj.height = ele.height;
  886. obj.imgSrc = ele.filePath;
  887. obj.loop = ele.loop;
  888. this.$store.dispatch("addElement", obj);
  889. // } else {
  890. // this.$store.dispatch('addElement', this.element)
  891. // }
  892. this.element.type = "pic";
  893. },
  894. addMorePicElement(ele) {
  895. // if (ele) {
  896. let obj = {};
  897. obj.type = "morePic";
  898. obj.top = document.getElementById("h5editor").scrollTop;
  899. obj.left = 0;
  900. obj.width = ele.morePic[0].width;
  901. obj.height = ele.morePic[0].height;
  902. obj.imgSrc = ele.filePath;
  903. obj.morePic = ele.morePic;
  904. obj.loop = ele.loop;
  905. this.$store.dispatch("addElement", obj);
  906. this.element.type = "morePic";
  907. },
  908. //添加按钮
  909. addButtonElement(ele) {
  910. // if (ele) {
  911. let obj = {};
  912. obj.type = "button";
  913. obj.top = document.getElementById("h5editor").scrollTop;
  914. obj["text"] = "请输入文本";
  915. obj["lineHeight"] = 1.5;
  916. obj.left = 0;
  917. obj.width = ele.width;
  918. obj.height = ele.height;
  919. obj.backgroundUnselectedImg = ele.backgroundUnselectedImg;
  920. obj.backgroundSelectedImg = ele.backgroundSelectedImg;
  921. obj.loop = ele.loop;
  922. this.$store.dispatch("addElement", obj);
  923. // } else {
  924. // this.$store.dispatch('addElement', this.element)
  925. // }
  926. this.element.type = "button";
  927. },
  928. addBG(file) {
  929. this.$store.dispatch("addBGElement", {
  930. type: "bg",
  931. imgSrc: file.filePath
  932. });
  933. },
  934. cleanBG() {
  935. this.$store.dispatch("cleanBG");
  936. },
  937. cleanEle() {
  938. this.$store.dispatch("cleanEle", this.element);
  939. },
  940. addTextElement(type) {
  941. let param = {};
  942. param.top = document.getElementById("h5editor").scrollTop;
  943. param["type"] = "text";
  944. param["text"] = "请输入文本";
  945. param["width"] = 300;
  946. param["lineHeight"] = 1.5;
  947. param["backgroundColor"] = "";
  948. param["verticalAlign"] = "top";
  949. param["display"] = "block";
  950. param["textIndent"] = "0.0";
  951. param["letterSpacing"] = "0.0";
  952. param["allTransparent"] = "";
  953. param["nodeId"] = "Id" + Math.random();
  954. switch (type) {
  955. case "plain":
  956. break;
  957. case "title":
  958. param["fontSize"] = 32;
  959. param["fontWeight"] = "bold";
  960. param["textAlign"] = "center";
  961. break;
  962. case "frame":
  963. param["type"] = "frame";
  964. param["text"] = "";
  965. param["width"] = this.canvasWidth;
  966. param["border"] = "1px solid #000";
  967. param["height"] = 500;
  968. break;
  969. default:
  970. }
  971. this.$store.dispatch("addElement", param);
  972. },
  973. playAnimate() {
  974. this.$store.dispatch("playAnimate");
  975. },
  976. async save() {
  977. var loading = this.$loading({
  978. lock: true,
  979. text: "模板保存中...",
  980. spinner: "el-icon-loading",
  981. background: "rgba(0, 0, 0, 0.7)"
  982. });
  983. $(".animated").css("animation-name", "null");
  984. $(".animated>div").css("animation-name", "null");
  985. $(".animated span").css({
  986. animationDelay: "0s",
  987. animationDuration: "0s"
  988. });
  989. await html2canvas(document.querySelector("#canvasPage"), {
  990. useCORS: true,
  991. scale: 0.5,
  992. height: 1334,
  993. logging: false //日志开关,便于查看html2canvas的内部执行流程
  994. }).then(async canvas => {
  995. var result = await uploadBase64({ base64Str: canvas.toDataURL() });
  996. if (result.data.success) {
  997. this.$store.state.editor.editorTheme.cover =
  998. result.data.single.filePath;
  999. console.log("封面地址", result.data.single.filePath);
  1000. } else {
  1001. this.$message.error("封面图片上传失败!");
  1002. }
  1003. });
  1004. this.$store.state.editor.editorTheme.bgc = this.bgc;
  1005. this.$store.state.editor.editorTheme.btnColor = this.btnColor;
  1006. this.$store.state.editor.editorTheme.bodyBackgroundColor =
  1007. this.bodyBackgroundColor || "rgba(255,255,255,0)";
  1008. this.$store.state.editor.editorTheme.canvasWidth =
  1009. this.canvasWidth || 750;
  1010. this.$store.state.editor.editorTheme.canvasHeight = this.canvasHeight;
  1011. this.$store.state.editor.editorTheme.title = this.title;
  1012. this.$store.state.editor.editorTheme.description = this.description;
  1013. this.$store.state.editor.editorTheme.animatedNameGlobal =
  1014. this.animatedNameGlobal || "";
  1015. this.$store.state.editor.editorTheme.animatedNameBackgroundGlobal =
  1016. this.animatedNameBackgroundGlobal || "";
  1017. this.editorPage.elements.forEach(function(element) {
  1018. if (element.type == "text") {
  1019. var height = window
  1020. .getComputedStyle(document.getElementById(element.nodeId))
  1021. .height.replace("px", "");
  1022. element.height = height;
  1023. } else if (element.type == "frame") {
  1024. element.children.forEach(function(_element) {
  1025. if (_element.type == "text") {
  1026. var height = window
  1027. .getComputedStyle(document.getElementById(_element.nodeId))
  1028. .height.replace("px", "");
  1029. _element.height = height;
  1030. }
  1031. });
  1032. }
  1033. });
  1034. let chil = this.$refs.overview;
  1035. console.log("子组件结果页的值:", chil.resultPageCount);
  1036. let param = {
  1037. id: this.itemId,
  1038. coverImg: this.$store.state.editor.editorTheme.cover,
  1039. jsonString: JSON.stringify(this.$store.state.editor.editorTheme),
  1040. resultPageCount: chil.resultPageCount,
  1041. updator: "admin"
  1042. };
  1043. console.log("参数", param);
  1044. return this.$store
  1045. .dispatch("saveTheme", param)
  1046. .then(() => {
  1047. loading.close();
  1048. this.$message({
  1049. message: "保存成功",
  1050. type: "success"
  1051. });
  1052. })
  1053. .catch(() => {
  1054. loading.close();
  1055. this.$message({
  1056. message: "保存失败",
  1057. type: "error"
  1058. });
  1059. });
  1060. },
  1061. deploy() {
  1062. this.isLoadingPreview = true;
  1063. this.$store
  1064. .dispatch(
  1065. "saveTheme",
  1066. tools.vue2json(this.$store.state.editor.editorTheme)
  1067. )
  1068. .then(() => {
  1069. var param = setTimeout(() => {
  1070. this.showPreView = true;
  1071. this.isLoadingPreview = false;
  1072. }, 1000);
  1073. });
  1074. },
  1075. selectedElement(element) {
  1076. this.$store.dispatch("setEditorElement", element);
  1077. },
  1078. deleteListener(event) {
  1079. if (
  1080. event.keyCode === 8 &&
  1081. event.target.nodeName !== "INPUT" &&
  1082. event.target.nodeName !== "TEXTAREA"
  1083. ) {
  1084. this.deleteElement();
  1085. }
  1086. },
  1087. deleteElement() {
  1088. this.$store.dispatch("deleteSelectedElement");
  1089. },
  1090. togglePanel(code) {
  1091. this.panelState = code;
  1092. if (code === 0) {
  1093. this.panelTabState = 0;
  1094. this.$store.dispatch("setEditorElement", null);
  1095. }
  1096. },
  1097. checkGlobalAnimation(item) {
  1098. if (this.animatedNameGlobal != item.id) {
  1099. this.animatedNameGlobal = item.id;
  1100. this.$store.state.editor.editorTheme.animatedNameGlobal = this.animatedNameGlobal;
  1101. } else {
  1102. this.animatedNameGlobal = "";
  1103. this.$store.state.editor.editorTheme.animatedNameGlobal = "";
  1104. }
  1105. },
  1106. checkBackgroundGlobalAnimation(item) {
  1107. if (this.animatedNameBackgroundGlobal != item.id) {
  1108. this.animatedNameBackgroundGlobal = item.id;
  1109. this.animatedBackgroundCustom = item.type == 0 ? false : true;
  1110. this.$store.state.editor.editorTheme.animatedNameBackgroundGlobal = this.animatedNameBackgroundGlobal;
  1111. } else {
  1112. this.animatedNameBackgroundGlobal = "";
  1113. this.$store.state.editor.editorTheme.animatedNameBackgroundGlobal = "";
  1114. }
  1115. },
  1116. bodyBackgroundColorChange() {
  1117. this.$store.state.editor.editorTheme.bodyBackgroundColor =
  1118. this.bodyBackgroundColor || "rgba(255,255,255,0)";
  1119. },
  1120. IMChange() {
  1121. this.$store.state.editor.editorTheme.bgc = this.bgc;
  1122. this.$store.state.editor.editorTheme.btnColor = this.btnColor;
  1123. },
  1124. toLeft() {
  1125. let complexEditorElement = this.complexEditorElement;
  1126. let arr = complexEditorElement.map(item => {
  1127. return item.left;
  1128. });
  1129. let min = Math.min.apply(null, arr);
  1130. complexEditorElement.forEach(ele => {
  1131. ele.left = min;
  1132. });
  1133. },
  1134. toCenter() {
  1135. let complexEditorElement = this.complexEditorElement;
  1136. let arr = complexEditorElement.map(item => {
  1137. return item.left;
  1138. });
  1139. let total = 0;
  1140. for (let i = 0; i < arr.length; i++) {
  1141. total += arr[i];
  1142. }
  1143. let p = total / arr.length;
  1144. complexEditorElement.forEach(ele => {
  1145. ele.left = p;
  1146. });
  1147. },
  1148. toRight() {
  1149. let complexEditorElement = this.complexEditorElement;
  1150. let arr = complexEditorElement.map(item => {
  1151. return item.width + item.left;
  1152. });
  1153. let max = Math.max.apply(null, arr);
  1154. complexEditorElement.forEach(ele => {
  1155. ele.left = max - ele.width;
  1156. });
  1157. },
  1158. toTop() {
  1159. let complexEditorElement = this.complexEditorElement;
  1160. let arr = complexEditorElement.map(item => {
  1161. return item.top;
  1162. });
  1163. let min = Math.min.apply(null, arr);
  1164. complexEditorElement.forEach(ele => {
  1165. ele.top = min;
  1166. });
  1167. },
  1168. toVertialCenter() {
  1169. let complexEditorElement = this.complexEditorElement;
  1170. let arr = complexEditorElement.map(item => {
  1171. return item.top;
  1172. });
  1173. let total = 0;
  1174. for (let i = 0; i < arr.length; i++) {
  1175. total += arr[i];
  1176. }
  1177. let p = total / arr.length;
  1178. complexEditorElement.forEach(ele => {
  1179. ele.top = p;
  1180. });
  1181. },
  1182. toBottom() {
  1183. let complexEditorElement = this.complexEditorElement;
  1184. let arr = complexEditorElement.map(item => {
  1185. return item.height + item.top;
  1186. });
  1187. let max = Math.max.apply(null, arr);
  1188. complexEditorElement.forEach(ele => {
  1189. ele.top = max - ele.height;
  1190. });
  1191. },
  1192. handleClose(done) {
  1193. this.$confirm("确认关闭?")
  1194. .then(_ => {
  1195. done();
  1196. })
  1197. .catch(_ => {});
  1198. },
  1199. uploadSelectedPicOrUnSelectedPic() {
  1200. this.dialogVisible = true;
  1201. },
  1202. async changeSelectedPicOrUnSelectedPic(event, isAddButton) {
  1203. var that = this;
  1204. let files = event.target.files;
  1205. if (!files.length) {
  1206. return false;
  1207. }
  1208. const loading = this.$loading({
  1209. lock: true,
  1210. text: "Loading",
  1211. spinner: "el-icon-loading",
  1212. background: "rgba(0, 0, 0, 0.7)"
  1213. });
  1214. for (var i = 0; i < files.length; i++) {
  1215. var file = files[i];
  1216. if (file) {
  1217. if (files.length == 1 && i == 0) {
  1218. http.uploadMaterielFile(
  1219. file,
  1220. function(res) {
  1221. let img = document.createElement("img");
  1222. that.buttonData.itemId = that.itemId;
  1223. that.buttonData.isButton = true;
  1224. loading.close();
  1225. img.onload = () => {
  1226. that.buttonData.width = img.width;
  1227. that.buttonData.height = img.height;
  1228. if (!isAddButton) {
  1229. that.buttonData.backgroundUnselectedImg = res;
  1230. that.uploadButtonImg("single");
  1231. } else {
  1232. that.buttonData.backgroundSelectedImg = res;
  1233. that.selectedButtom = false;
  1234. var param = setTimeout(() => {
  1235. that.selectedButtom = true;
  1236. }, 1);
  1237. }
  1238. };
  1239. img.src = res;
  1240. },
  1241. function(res) {
  1242. if (res.total.percent == 100) {
  1243. loading.close();
  1244. }
  1245. }
  1246. );
  1247. } else if (files.length > 1) {
  1248. http.uploadMaterielFile(
  1249. file,
  1250. function(res) {
  1251. that.buttonData.itemId = that.itemId;
  1252. that.buttonData.isButton = true;
  1253. if (res.endsWith(files[0].name)) {
  1254. that.buttonData.backgroundUnselectedImg = res;
  1255. } else if (res.endsWith(files[1].name)) {
  1256. that.buttonData.backgroundSelectedImg = res;
  1257. let img = document.createElement("img");
  1258. img.onload = () => {
  1259. that.buttonData.width = img.width;
  1260. that.buttonData.height = img.height;
  1261. if (!isAddButton) {
  1262. that.uploadButtonImg("both");
  1263. } else {
  1264. that.selectedButtom = false;
  1265. var param = setTimeout(() => {
  1266. that.selectedButtom = true;
  1267. }, 1);
  1268. that.unSelectedButtom = false;
  1269. var param2 = setTimeout(() => {
  1270. that.unSelectedButtom = true;
  1271. }, 1);
  1272. }
  1273. };
  1274. img.src = res;
  1275. loading.close();
  1276. }
  1277. },
  1278. function(res) {
  1279. if (res.total.percent == 100) {
  1280. }
  1281. }
  1282. );
  1283. }
  1284. }
  1285. }
  1286. },
  1287. uploadButtonImg(type) {
  1288. let that = this;
  1289. this.element.width = that.buttonData.width;
  1290. this.element.height = that.buttonData.height;
  1291. if (type == "single") {
  1292. this.element.backgroundUnselectedImg =
  1293. that.buttonData.backgroundUnselectedImg;
  1294. this.element.backgroundSelectedImg = that.element.backgroundSelectedImg;
  1295. } else if (type == "both") {
  1296. this.element.backgroundUnselectedImg =
  1297. that.buttonData.backgroundUnselectedImg;
  1298. this.element.backgroundSelectedImg =
  1299. that.buttonData.backgroundSelectedImg;
  1300. }
  1301. this.buttonData = {};
  1302. },
  1303. closeUploadButton() {
  1304. this.buttonData = {};
  1305. this.dialogVisible = false;
  1306. this.selectedButtom = false;
  1307. this.unSelectedButtom = false;
  1308. this.canSave = false;
  1309. },
  1310. async upload(event, isSelected) {
  1311. var that = this;
  1312. let files = event.target.files;
  1313. if (!files.length) {
  1314. return false;
  1315. }
  1316. const loading = this.$loading({
  1317. lock: true,
  1318. text: "Loading",
  1319. spinner: "el-icon-loading",
  1320. background: "rgba(0, 0, 0, 0.7)"
  1321. });
  1322. for (var i = 0; i < files.length; i++) {
  1323. var file = files[i];
  1324. if (file) {
  1325. http.uploadMaterielFile(
  1326. file,
  1327. function(res) {
  1328. loading.close();
  1329. let img = document.createElement("img");
  1330. img.onload = () => {
  1331. if (isSelected) {
  1332. that.buttonData.backgroundSelectedImg = res;
  1333. that.selectedButtom = false;
  1334. var params = setTimeout(() => {
  1335. that.selectedButtom = true;
  1336. }, 1);
  1337. } else {
  1338. that.buttonData.backgroundUnselectedImg = res;
  1339. that.unSelectedButtom = false;
  1340. var param = setTimeout(() => {
  1341. that.unSelectedButtom = true;
  1342. }, 1);
  1343. }
  1344. that.buttonData.itemId = that.itemId;
  1345. that.buttonData.width = img.width;
  1346. that.buttonData.height = img.height;
  1347. that.buttonData.isButton = true;
  1348. };
  1349. img.src = res;
  1350. },
  1351. function(res) {
  1352. if (res.total.percent == 100 && files.length == i + 1) {
  1353. loading.close();
  1354. }
  1355. }
  1356. );
  1357. }
  1358. }
  1359. },
  1360. uploadButton() {
  1361. let that = this;
  1362. if (
  1363. that.buttonData.backgroundUnselectedImg &&
  1364. that.buttonData.backgroundSelectedImg
  1365. ) {
  1366. this.canSave = false;
  1367. } else {
  1368. this.canSave = true;
  1369. return false;
  1370. }
  1371. this.$store.dispatch("savePic", {
  1372. backgroundUnselectedImg: that.buttonData.backgroundUnselectedImg,
  1373. backgroundSelectedImg: that.buttonData.backgroundSelectedImg,
  1374. themeId: that.buttonData.itemId,
  1375. width: that.buttonData.width,
  1376. height: that.buttonData.height,
  1377. isButton: that.buttonData.isButton
  1378. });
  1379. this.buttonData = {};
  1380. this.dialogVisible = false;
  1381. this.selectedButtom = false;
  1382. this.unSelectedButtom = false;
  1383. this.canSave = false;
  1384. },
  1385. changeImg() {
  1386. var temp = "";
  1387. temp = this.buttonData.backgroundSelectedImg;
  1388. this.buttonData.backgroundSelectedImg = this.buttonData.backgroundUnselectedImg;
  1389. this.buttonData.backgroundUnselectedImg = temp;
  1390. this.selectedButtom = false;
  1391. var params1 = setTimeout(() => {
  1392. this.selectedButtom = true;
  1393. }, 0.1);
  1394. this.unSelectedButtom = false;
  1395. var params2 = setTimeout(() => {
  1396. this.unSelectedButtom = true;
  1397. }, 0.1);
  1398. }
  1399. },
  1400. components: {
  1401. Overview,
  1402. Page,
  1403. PicPicker,
  1404. appConst,
  1405. PreView,
  1406. HeaderEdit,
  1407. EditPanel,
  1408. SvgPanel,
  1409. ImgPanel,
  1410. AudioPanel,
  1411. elabCanvas,
  1412. elabBackgroundCanvas,
  1413. HeaderMain
  1414. },
  1415. created() {
  1416. // new SnowCanvas(curWinWidth, curWinHeight);
  1417. // new Snow().process()
  1418. this.testcaseId = this.$route.query.testcaseId;
  1419. this.itemId = this.$route.query.itemId;
  1420. if (this.itemId) {
  1421. if (!this.pages) {
  1422. this.$store.dispatch("getPageByThemeId", this.itemId);
  1423. }
  1424. // this.getPicList(this.itemId);
  1425. } else {
  1426. this.$store.dispatch("createTheme");
  1427. this.$store.dispatch("addPage");
  1428. this.$store.dispatch("cleanPicList");
  1429. }
  1430. document.addEventListener("keyup", this.deleteListener);
  1431. window.onbeforeunload = () => false;
  1432. },
  1433. destroyed() {
  1434. document.removeEventListener("keyup", this.deleteListener);
  1435. window.onbeforeunload = null;
  1436. }
  1437. };
  1438. </script>
  1439. <style lang="less" scoped>
  1440. .lable {
  1441. display: block;
  1442. cursor: pointer;
  1443. width: 130px;
  1444. height: 130px;
  1445. }
  1446. .dialog {
  1447. width: 100%;
  1448. height: 100%;
  1449. background: rgba(255, 255, 255, 0.6);
  1450. position: absolute;
  1451. top: 0;
  1452. z-index: 100;
  1453. }
  1454. .tagPage {
  1455. position: relative;
  1456. }
  1457. .tagPage:hover div {
  1458. display: block;
  1459. }
  1460. .page-create-txt {
  1461. width: 34px;
  1462. height: 34px;
  1463. background: url("http://yun-image.elab-plus.com/images/dyb/new-text.png")
  1464. center no-repeat;
  1465. background-size: 34px 34px;
  1466. &:hover {
  1467. background: url("http://yun-image.elab-plus.com/images/dyb/new-text-hover.png")
  1468. center no-repeat;
  1469. background-size: 34px 34px;
  1470. }
  1471. &.active {
  1472. background: url("http://yun-image.elab-plus.com/images/dyb/new-text-active.png")
  1473. center no-repeat;
  1474. background-size: 34px 34px;
  1475. }
  1476. }
  1477. .page-create-btn {
  1478. width: 34px;
  1479. height: 34px;
  1480. background: url("http://yun-image.elab-plus.com/images/dyb/new-zhuangshi.png")
  1481. center no-repeat;
  1482. background-size: 34px 34px;
  1483. &:hover {
  1484. background: url("http://yun-image.elab-plus.com/images/dyb/new-zhuangshi-hover.png")
  1485. center no-repeat;
  1486. background-size: 34px 34px;
  1487. }
  1488. &.active {
  1489. background: url("http://yun-image.elab-plus.com/images/dyb/new-zhuangshi-active.png")
  1490. center no-repeat;
  1491. background-size: 34px 34px;
  1492. }
  1493. }
  1494. .page-create-lunbo {
  1495. width: 34px;
  1496. height: 34px;
  1497. background: url("http://yun-image.elab-plus.com/images/dyb/new-lunbo.png")
  1498. center no-repeat;
  1499. background-size: 34px 34px;
  1500. &:hover {
  1501. background: url("http://yun-image.elab-plus.com/images/dyb/new-lunbo-hover.png")
  1502. center no-repeat;
  1503. background-size: 34px 34px;
  1504. }
  1505. &.active {
  1506. background: url("http://yun-image.elab-plus.com/images/dyb/new-lunbo-active.png")
  1507. center no-repeat;
  1508. background-size: 34px 34px;
  1509. }
  1510. }
  1511. .page-create-jiaohuanniu {
  1512. width: 34px;
  1513. height: 34px;
  1514. background: url("http://yun-image.elab-plus.com/images/dyb/new-jiaohuanniu.png")
  1515. center no-repeat;
  1516. background-size: 34px 34px;
  1517. &:hover {
  1518. background: url("http://yun-image.elab-plus.com/images/dyb/new-jiaohuanniu-hover.png")
  1519. center no-repeat;
  1520. background-size: 34px 34px;
  1521. }
  1522. &.active {
  1523. background: url("http://yun-image.elab-plus.com/images/dyb/new-jiaohuanniu-active.png")
  1524. center no-repeat;
  1525. background-size: 34px 34px;
  1526. }
  1527. }
  1528. .page-tag-btn-tip {
  1529. width: 80px;
  1530. height: 26px;
  1531. position: absolute;
  1532. left: -85px;
  1533. top: 50%;
  1534. transform: translateY(-50%);
  1535. display: none;
  1536. text-align: center;
  1537. line-height: 26px;
  1538. font-size: 14px;
  1539. color: #fff;
  1540. background: url(../../assets/images/page_tag_btn_tip.png) center no-repeat;
  1541. background-size: cover;
  1542. }
  1543. .editor {
  1544. background-color: rgb(237, 239, 247);
  1545. position: relative;
  1546. height: 100%;
  1547. overflow: hidden;
  1548. user-select: none;
  1549. }
  1550. .section {
  1551. position: absolute;
  1552. left: 0;
  1553. right: 0;
  1554. top: 120px;
  1555. bottom: 0;
  1556. overflow: hidden;
  1557. }
  1558. .overview {
  1559. position: absolute;
  1560. left: 0;
  1561. width: 225px;
  1562. height: 100%;
  1563. z-index: 10;
  1564. }
  1565. .canvas {
  1566. /*position: absolute !important;*/
  1567. /*top: 50%;*/
  1568. /*left: 50%;*/
  1569. /*transform: translate(-75%, -50%);*/
  1570. border: 2px solid #373f42;
  1571. box-shadow: 0px 2px 30px 5px rgba(0, 0, 0, 0.2);
  1572. box-sizing: content-box;
  1573. margin-bottom: 200px;
  1574. }
  1575. .edit-area {
  1576. position: absolute !important;
  1577. height: 100%;
  1578. width: auto;
  1579. left: 270px;
  1580. right: 367px;
  1581. top: 0;
  1582. overflow: scroll;
  1583. }
  1584. .container {
  1585. height: 100%;
  1586. width: 770px;
  1587. }
  1588. .control-panel {
  1589. position: absolute;
  1590. width: 324px;
  1591. height: 100%;
  1592. right: 0;
  1593. top: 0;
  1594. border-left: 1px solid #d6d6d6;
  1595. background-color: white;
  1596. z-index: 10;
  1597. .funcs {
  1598. position: absolute;
  1599. left: -44px;
  1600. top: 0;
  1601. height: 100%;
  1602. width: 44px;
  1603. background-color: white;
  1604. border-right: 2px solid #e2e4ee;
  1605. box-shadow: 0px 1px 15px 1px rgba(0, 0, 0, 0.2);
  1606. .func {
  1607. color: white;
  1608. background: transparent;
  1609. cursor: pointer;
  1610. margin-top: 20px;
  1611. display: block;
  1612. width: 50px;
  1613. height: 50px;
  1614. &:hover {
  1615. color: #000;
  1616. }
  1617. &.active {
  1618. border-right: 1px solid #ececec;
  1619. background-color: #ececec;
  1620. color: #000;
  1621. }
  1622. }
  1623. }
  1624. .wrapper {
  1625. height: 100%;
  1626. overflow-y: auto;
  1627. overflow-x: hidden;
  1628. position: relative;
  1629. }
  1630. .panel {
  1631. position: absolute;
  1632. left: 0;
  1633. top: 0;
  1634. height: 100%;
  1635. width: 100%;
  1636. z-index: 2;
  1637. background-color: white;
  1638. overflow-y: auto;
  1639. overflow-x: hidden;
  1640. }
  1641. .panel-bg {
  1642. .btn {
  1643. float: left;
  1644. width: 48%;
  1645. margin-left: 1%;
  1646. margin-right: 1%;
  1647. }
  1648. .bgs {
  1649. float: left;
  1650. width: 80px;
  1651. height: 80px;
  1652. background-repeat: no-repeat;
  1653. background-position: center;
  1654. background-size: contain;
  1655. margin: 5px 5px;
  1656. &:hover {
  1657. border: 2px solid #18ccc0;
  1658. cursor: pointer;
  1659. }
  1660. }
  1661. }
  1662. .panel-text {
  1663. .btn {
  1664. height: 50px;
  1665. line-height: 50px;
  1666. text-align: center;
  1667. border: 2px solid transparent;
  1668. &:hover {
  1669. cursor: pointer;
  1670. border-color: #4e5dff;
  1671. }
  1672. }
  1673. }
  1674. }
  1675. /* 2018/07/23 所有前台自定义字体,需要放七牛云服务器上,暂时放这个样式文件里面 */
  1676. @font-face {
  1677. font-family: "PenCrane";
  1678. src: url("http://yun-image.elab-plus.com/PenCrane.ttf") format("truetype");
  1679. font-weight: normal;
  1680. font-style: normal;
  1681. }
  1682. @font-face {
  1683. font-family: 手书体;
  1684. src: url("http://yun-image.elab-plus.com/new/手书体.ttf") format("truetype");
  1685. font-weight: normal;
  1686. font-style: normal;
  1687. }
  1688. @font-face {
  1689. font-family: 汉仪粗仿宋简;
  1690. src: url("http://yun-image.elab-plus.com/汉仪粗仿宋简.ttf") format("truetype");
  1691. font-weight: normal;
  1692. font-style: normal;
  1693. }
  1694. @font-face {
  1695. font-family: 华康黑体W3;
  1696. src: url("http://yun-image.elab-plus.com/华康黑体W3.ttf") format("truetype");
  1697. font-weight: normal;
  1698. font-style: normal;
  1699. }
  1700. @font-face {
  1701. font-family: 华康黑体W7;
  1702. src: url("http://yun-image.elab-plus.com/华康黑体W7.ttf") format("truetype");
  1703. font-weight: normal;
  1704. font-style: normal;
  1705. }
  1706. @font-face {
  1707. font-family: 华康黑体W9;
  1708. src: url("http://yun-image.elab-plus.com/华康黑体W9.ttf") format("truetype");
  1709. font-weight: normal;
  1710. font-style: normal;
  1711. }
  1712. @font-face {
  1713. font-family: 华康黑体W12;
  1714. src: url("http://yun-image.elab-plus.com/华康黑体W12.ttf") format("truetype");
  1715. font-weight: normal;
  1716. font-style: normal;
  1717. }
  1718. @font-face {
  1719. font-family: 华康楷体W5;
  1720. src: url("http://yun-image.elab-plus.com/华康楷体W5.ttf") format("truetype");
  1721. font-weight: normal;
  1722. font-style: normal;
  1723. }
  1724. @font-face {
  1725. font-family: 华康勘亭流W9;
  1726. src: url("http://yun-image.elab-plus.com/华康勘亭流W9.ttf") format("truetype");
  1727. font-weight: normal;
  1728. font-style: normal;
  1729. }
  1730. @font-face {
  1731. font-family: 华康瘦金体W3;
  1732. src: url("http://yun-image.elab-plus.com/华康瘦金体W3.ttf") format("truetype");
  1733. font-weight: normal;
  1734. font-style: normal;
  1735. }
  1736. @font-face {
  1737. font-family: 华康宋体W3;
  1738. src: url("http://yun-image.elab-plus.com/华康宋体W3.ttf") format("truetype");
  1739. font-weight: normal;
  1740. font-style: normal;
  1741. }
  1742. @font-face {
  1743. font-family: 华康宋体W7;
  1744. src: url("http://yun-image.elab-plus.com/华康宋体W7.ttf") format("truetype");
  1745. font-weight: normal;
  1746. font-style: normal;
  1747. }
  1748. @font-face {
  1749. font-family: 华康宋体W12;
  1750. src: url("http://yun-image.elab-plus.com/华康宋体W12.ttf") format("truetype");
  1751. font-weight: normal;
  1752. font-style: normal;
  1753. }
  1754. @font-face {
  1755. font-family: 华康魏碑W7;
  1756. src: url("http://yun-image.elab-plus.com/华康魏碑W7.ttf") format("truetype");
  1757. font-weight: normal;
  1758. font-style: normal;
  1759. }
  1760. @font-face {
  1761. font-family: 华康新综艺W7;
  1762. src: url("http://yun-image.elab-plus.com/华康新综艺W7.ttf") format("truetype");
  1763. font-weight: normal;
  1764. font-style: normal;
  1765. }
  1766. @font-face {
  1767. font-family: 华康雅宋体W9;
  1768. src: url("http://yun-image.elab-plus.com/华康雅宋体W9.ttf") format("truetype");
  1769. font-weight: normal;
  1770. font-style: normal;
  1771. }
  1772. @font-face {
  1773. font-family: 华康圆体W3;
  1774. src: url("http://yun-image.elab-plus.com/华康圆体W3.ttf") format("truetype");
  1775. font-weight: normal;
  1776. font-style: normal;
  1777. }
  1778. @font-face {
  1779. font-family: 华康圆体W5;
  1780. src: url("http://yun-image.elab-plus.com/华康圆体W5.ttf") format("truetype");
  1781. font-weight: normal;
  1782. font-style: normal;
  1783. }
  1784. @font-face {
  1785. font-family: 华康圆体W9;
  1786. src: url("http://yun-image.elab-plus.com/华康圆体W9.ttf") format("truetype");
  1787. font-weight: normal;
  1788. font-style: normal;
  1789. }
  1790. @font-face {
  1791. font-family: 庞门正道标题体增强版;
  1792. src: url("http://yun-image.elab-plus.com/庞门正道标题体增强版.ttf")
  1793. format("truetype");
  1794. font-weight: normal;
  1795. font-style: normal;
  1796. }
  1797. @font-face {
  1798. font-family: 站酷高端黑修订版;
  1799. src: url("http://yun-image.elab-plus.com/站酷高端黑修订版.ttf")
  1800. format("truetype");
  1801. font-weight: normal;
  1802. font-style: normal;
  1803. }
  1804. @font-face {
  1805. font-family: 站酷酷黑;
  1806. src: url("http://yun-image.elab-plus.com/站酷酷黑.ttf") format("truetype");
  1807. font-weight: normal;
  1808. font-style: normal;
  1809. }
  1810. </style>