PensProps.vue 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932
  1. <template>
  2. <div class="props">
  3. <t-tabs v-model="data.tab">
  4. <t-tab-panel :value="1" label="外观">
  5. <t-space direction="vertical" class="py-16 w-full">
  6. <div class="px-16 flex between">
  7. <label>选中了{{ selections.pens.length }}个图元</label>
  8. <div class="icons">
  9. <t-tooltip
  10. class="mr-4"
  11. v-if="!data.locked"
  12. content="可编辑"
  13. placement="top"
  14. >
  15. <svg class="l-icon" aria-hidden="true" @click="lock(1)">
  16. <use xlink:href="#l-unlock"></use>
  17. </svg>
  18. </t-tooltip>
  19. <t-tooltip
  20. class="mr-4"
  21. v-else-if="data.locked == 1"
  22. content="禁止编辑"
  23. placement="top"
  24. >
  25. <svg class="l-icon" aria-hidden="true" @click="lock(2)">
  26. <use xlink:href="#l-lock"></use>
  27. </svg>
  28. </t-tooltip>
  29. <t-tooltip
  30. class="mr-4"
  31. v-else-if="data.locked == 2"
  32. content="禁止编辑和移动"
  33. placement="top"
  34. >
  35. <svg class="l-icon" aria-hidden="true" @click="lock(10)">
  36. <use xlink:href="#l-wufayidong"></use>
  37. </svg>
  38. </t-tooltip>
  39. <t-tooltip
  40. class="mr-4"
  41. v-else-if="data.locked == 10"
  42. content="禁止所有事件"
  43. placement="top"
  44. >
  45. <svg class="l-icon" aria-hidden="true" @click="lock(0)">
  46. <use xlink:href="#l-jinyong"></use>
  47. </svg>
  48. </t-tooltip>
  49. <t-icon
  50. v-if="data.visible !== false"
  51. name="browse"
  52. @click="visible(false)"
  53. class="ml-8"
  54. />
  55. <t-icon
  56. v-else
  57. name="browse-off"
  58. @click="visible(true)"
  59. class="ml-8"
  60. />
  61. </div>
  62. </div>
  63. <t-collapse
  64. :defaultValue="['1', '2', '3', '4']"
  65. expandIconPlacement="right"
  66. :borderless="true"
  67. >
  68. <t-collapse-panel value="1" header="对齐">
  69. <t-space direction="vertical" size="small" class="w-full">
  70. <div style="color: var(--color); margin-bottom: 2px">
  71. 区域对齐
  72. </div>
  73. <div class="icons">
  74. <t-tooltip
  75. v-for="item in aligns"
  76. :content="item.label"
  77. placement="top"
  78. >
  79. <svg
  80. class="l-icon btn"
  81. aria-hidden="true"
  82. @click="align(item.value)"
  83. >
  84. <use :xlink:href="item.icon"></use>
  85. </svg>
  86. </t-tooltip>
  87. </div>
  88. </t-space>
  89. <t-divider
  90. style="margin: 16px -16px 12px -16px; width: calc(100% + 32px)"
  91. />
  92. <t-space direction="vertical" size="small" class="w-full">
  93. <div style="color: var(--color); margin-bottom: 2px">
  94. 以最后选中图元对齐
  95. </div>
  96. <div class="icons">
  97. <t-tooltip
  98. v-for="item in aligns2"
  99. :content="item.label"
  100. placement="top"
  101. >
  102. <svg
  103. class="l-icon btn"
  104. aria-hidden="true"
  105. @click="align2(item.value)"
  106. >
  107. <use :xlink:href="item.icon"></use>
  108. </svg>
  109. </t-tooltip>
  110. </div>
  111. </t-space>
  112. </t-collapse-panel>
  113. <t-collapse-panel value="2" header="外观">
  114. <t-space direction="vertical" size="small" class="w-full">
  115. <div class="form-item">
  116. <t-color-picker
  117. class="simple mt-8 mr-4"
  118. format="CSS"
  119. :enable-alpha="true"
  120. :color-modes="['monochrome']"
  121. :show-primary-color-preview="false"
  122. :clearable="true"
  123. v-model="data.color"
  124. @change="changeValue('color')"
  125. />
  126. <label style="width: 64px">前景颜色</label>
  127. <t-color-picker
  128. class="simple mt-8 mr-4"
  129. format="CSS"
  130. :enable-alpha="true"
  131. :color-modes="['monochrome']"
  132. :show-primary-color-preview="false"
  133. v-model="data.hoverColor"
  134. @change="changeValue('hoverColor')"
  135. />
  136. <label style="width: 64px">悬停颜色</label>
  137. <t-color-picker
  138. class="simple mt-8 mr-4"
  139. format="CSS"
  140. :enable-alpha="true"
  141. :color-modes="['monochrome']"
  142. :show-primary-color-preview="false"
  143. v-model="data.activeColor"
  144. @change="changeValue('activeColor')"
  145. />
  146. <label style="width: 64px">选中颜色</label>
  147. </div>
  148. <div class="form-item">
  149. <label style="width: 32px">线条 </label>
  150. <t-select
  151. v-model="data.dash"
  152. placeholder="线条样式"
  153. @change="changeValue('dash')"
  154. style="width: 80px"
  155. >
  156. <template #valueDisplay="{ value }">
  157. <svg
  158. xmlns="http://www.w3.org/2000/svg"
  159. version="1.1"
  160. style="width: 100%; height: 20px"
  161. >
  162. <g fill="none" stroke="var(--color)" stroke-width="1">
  163. <path v-if="value === 0" d="M0 9 l85 0" />
  164. <path
  165. v-else-if="value === 1"
  166. stroke-dasharray="5 5"
  167. d="M0 9 l85 0"
  168. />
  169. <path
  170. v-else-if="value === 2"
  171. stroke-dasharray="10 10"
  172. d="M0 9 l85 0"
  173. />
  174. <path
  175. v-else-if="value === 3"
  176. stroke-dasharray="10 10 2 10"
  177. d="M0 9 l85 0"
  178. />
  179. </g>
  180. </svg>
  181. </template>
  182. <t-option :key="0" :value="0">
  183. <svg
  184. xmlns="http://www.w3.org/2000/svg"
  185. version="1.1"
  186. style="width: 80px; height: 14px"
  187. >
  188. <g fill="none" stroke="var(--color)" stroke-width="1">
  189. <path d="M0 9 l85 0" />
  190. </g>
  191. </svg>
  192. </t-option>
  193. <t-option :key="1" :value="1">
  194. <svg
  195. xmlns="http://www.w3.org/2000/svg"
  196. version="1.1"
  197. style="width: 80px; height: 14px"
  198. >
  199. <g fill="none" stroke="var(--color)" stroke-width="1">
  200. <path stroke-dasharray="5 5" d="M0 9 l85 0" />
  201. </g>
  202. </svg>
  203. </t-option>
  204. <t-option :key="2" :value="2">
  205. <svg
  206. xmlns="http://www.w3.org/2000/svg"
  207. version="1.1"
  208. style="width: 80px; height: 14px"
  209. >
  210. <g fill="none" stroke="var(--color)" stroke-width="1">
  211. <path stroke-dasharray="10 10" d="M0 9 l85 0" />
  212. </g>
  213. </svg>
  214. </t-option>
  215. <t-option :key="3" :value="3">
  216. <svg
  217. xmlns="http://www.w3.org/2000/svg"
  218. version="1.1"
  219. style="width: 80px; height: 14px"
  220. >
  221. <g fill="none" stroke="var(--color)" stroke-width="1">
  222. <path stroke-dasharray="10 10 2 10" d="M0 9 l85 0" />
  223. </g>
  224. </svg>
  225. </t-option>
  226. </t-select>
  227. <t-input-number
  228. theme="normal"
  229. placeholder="线条宽度"
  230. v-model="data.lineWidth"
  231. :min="1"
  232. :decimalPlaces="0"
  233. @change="changeValue('lineWidth')"
  234. class="ml-4"
  235. style="width: 40px"
  236. />
  237. <t-tooltip content="线条渐变" placement="top">
  238. <div class="flex middle ml-8">
  239. <t-checkbox
  240. v-model="data.strokeType"
  241. @change="changeValue('strokeType')"
  242. style="width: 22px"
  243. />
  244. <t-color-picker
  245. v-if="data.strokeType"
  246. class="simple mr-4"
  247. format="CSS"
  248. :color-modes="['linear-gradient']"
  249. :show-primary-color-preview="false"
  250. :clearable="true"
  251. :enableAlpha="true"
  252. v-model="data.lineGradientColors"
  253. @change="changeValue('lineGradientColors')"
  254. placeholder="无"
  255. />
  256. </div>
  257. </t-tooltip>
  258. </div>
  259. <div class="flex" style="margin-left: 40px">
  260. <div class="flex column middle">
  261. <t-radio-group
  262. size="small"
  263. v-model="data.lineCap"
  264. default-value="butt"
  265. @change="changeValue('lineCap')"
  266. >
  267. <t-radio-button value="butt">
  268. <t-tooltip content="默认" placement="top">
  269. <svg class="l-icon" aria-hidden="true">
  270. <use xlink:href="#l-duandian1"></use>
  271. </svg>
  272. </t-tooltip>
  273. </t-radio-button>
  274. <t-radio-button value="round">
  275. <t-tooltip content="圆形" placement="top">
  276. <svg class="l-icon" aria-hidden="true">
  277. <use xlink:href="#l-duandian2"></use>
  278. </svg>
  279. </t-tooltip>
  280. </t-radio-button>
  281. <t-radio-button value="square">
  282. <t-tooltip content="方形" placement="top">
  283. <svg class="l-icon" aria-hidden="true">
  284. <use xlink:href="#l-duandian3"></use>
  285. </svg>
  286. </t-tooltip>
  287. </t-radio-button>
  288. </t-radio-group>
  289. <div class="mt-4" style="font-size: 12px">末端样式</div>
  290. </div>
  291. <div class="flex column middle ml-16">
  292. <t-radio-group
  293. size="small"
  294. v-model="data.lineJoin"
  295. default-value="miter"
  296. @change="changeValue('lineJoin')"
  297. >
  298. <t-radio-button value="miter">
  299. <t-tooltip content="默认" placement="top">
  300. <svg class="l-icon" aria-hidden="true">
  301. <use xlink:href="#l-jiedian1"></use>
  302. </svg>
  303. </t-tooltip>
  304. </t-radio-button>
  305. <t-radio-button value="round">
  306. <t-tooltip content="圆形" placement="top">
  307. <svg class="l-icon" aria-hidden="true">
  308. <use xlink:href="#l-jiedian2"></use>
  309. </svg>
  310. </t-tooltip>
  311. </t-radio-button>
  312. <t-radio-button value="bevel">
  313. <t-tooltip content="斜角" placement="top">
  314. <svg class="l-icon" aria-hidden="true">
  315. <use xlink:href="#l-jiedian3"></use>
  316. </svg>
  317. </t-tooltip>
  318. </t-radio-button>
  319. </t-radio-group>
  320. <div class="mt-4" style="font-size: 12px">连接样式</div>
  321. </div>
  322. </div>
  323. <div class="form-item">
  324. <label style="width: 32px">背景</label>
  325. <div class="ml-8">
  326. <t-radio-group
  327. size="small"
  328. v-model="data.bkType"
  329. :default-value="0"
  330. @change="changeValue('bkType')"
  331. >
  332. <t-radio-button :value="0"> 纯色 </t-radio-button>
  333. <t-radio-button :value="1"> 线性渐变 </t-radio-button>
  334. <t-radio-button :value="2"> 径向渐变 </t-radio-button>
  335. </t-radio-group>
  336. <div v-if="data.bkType === 0" class="mt-8 -ml-8">
  337. <t-color-picker
  338. class="w-full"
  339. format="CSS"
  340. :enable-alpha="true"
  341. :color-modes="['monochrome']"
  342. :show-primary-color-preview="false"
  343. v-model="data.background"
  344. @change="changeValue('background')"
  345. />
  346. </div>
  347. <div
  348. v-else-if="data.bkType === 1"
  349. class="mt-8 -ml-8"
  350. style="width: 200px"
  351. >
  352. <t-color-picker
  353. class="w-full"
  354. format="CSS"
  355. :enable-alpha="true"
  356. :color-modes="['linear-gradient']"
  357. :show-primary-color-preview="false"
  358. v-model="data.gradientColors"
  359. @change="changeValue('gradientColors')"
  360. />
  361. </div>
  362. <div v-else-if="data.bkType === 2" class="mt-8 flex middle">
  363. <t-color-picker
  364. class="simple"
  365. format="CSS"
  366. :enable-alpha="true"
  367. :color-modes="['linear-gradient']"
  368. :show-primary-color-preview="false"
  369. v-model="data.gradientColors"
  370. @change="changeValue('gradientColors')"
  371. />
  372. <t-input-number
  373. theme="column"
  374. placeholder="渐变半径"
  375. v-model="data.gradientRadius"
  376. :min="0"
  377. :max="1"
  378. :step="0.1"
  379. @change="changeValue('gradientRadius')"
  380. class="ml-8"
  381. style="width: 100px"
  382. />
  383. </div>
  384. </div>
  385. </div>
  386. <div class="form-item">
  387. <label style="width: 32px">阴影 </label>
  388. <div class="flex middle ml-8">
  389. <t-checkbox
  390. v-model="data.shadow"
  391. @change="changeValue('shadow')"
  392. style="width: 22px"
  393. />
  394. <t-color-picker
  395. v-if="data.shadow"
  396. class="simple"
  397. format="CSS"
  398. :enable-alpha="true"
  399. :color-modes="['monochrome']"
  400. :show-primary-color-preview="false"
  401. v-model="data.shadowColor"
  402. @change="changeValue('shadowColor')"
  403. />
  404. </div>
  405. </div>
  406. <div class="form-item" v-if="data.shadow">
  407. <label style="width: 28px"></label>
  408. <div class="flex" style="margin-top: -8px">
  409. <t-input
  410. class="ml-4"
  411. label="X"
  412. placeholder="0"
  413. v-model.number="data.shadowOffsetX"
  414. style="width: 60px"
  415. @change="changeValue('x')"
  416. title="X偏移"
  417. />
  418. <t-input
  419. class="ml-4"
  420. label="Y"
  421. placeholder="0"
  422. v-model.number="data.shadowOffsetY"
  423. style="width: 60px"
  424. @change="changeValue('shadowOffsetY')"
  425. title="Y偏移"
  426. />
  427. <t-input
  428. class="ml-4"
  429. label="模糊"
  430. placeholder="0"
  431. v-model.number="data.shadowBlur"
  432. style="width: 64px"
  433. @change="changeValue('shadowBlur')"
  434. title="模糊大小"
  435. />
  436. </div>
  437. </div>
  438. </t-space>
  439. </t-collapse-panel>
  440. <t-collapse-panel value="3" header="文字">
  441. <t-space direction="vertical" size="small" class="w-full">
  442. <div class="form-item">
  443. <div class="flex middle" style="margin-left: -10px">
  444. <t-select-input
  445. :value="data.fontFamily"
  446. :popup-visible="data.fontFamilyPopupVisible"
  447. placeholder="字体名"
  448. allow-input
  449. style="width: 170px"
  450. @change="changeValue('fontFamily')"
  451. @enter="changeValue('fontFamily')"
  452. @blur="changeValue('fontFamily')"
  453. @popup-visible-change="onFontPopupVisible"
  454. :popup-props="{
  455. overlayInnerStyle: { width: 'auto' },
  456. }"
  457. >
  458. <template #panel>
  459. <ul style="padding: 12px">
  460. <li
  461. v-for="item in fonts"
  462. :key="item"
  463. @click="onFontFamily(item)"
  464. >
  465. {{ item }}
  466. </li>
  467. </ul>
  468. </template>
  469. <template #suffixIcon>
  470. <t-icon name="chevron-down" />
  471. </template>
  472. </t-select-input>
  473. <t-input
  474. class="ml-8"
  475. placeholder="字体大小"
  476. v-model.number="data.fontSize"
  477. style="width: 80px"
  478. :format="decimalRound"
  479. @change="changeValue('fontSize')"
  480. />
  481. </div>
  482. </div>
  483. <div class="flex middle">
  484. <t-radio-group
  485. size="small"
  486. v-model="data.textAlign"
  487. default-value="center"
  488. @change="changeValue('textAlign')"
  489. >
  490. <t-radio-button value="left">
  491. <t-tooltip content="居左" placement="top">
  492. <t-icon name="format-vertical-align-left" />
  493. </t-tooltip>
  494. </t-radio-button>
  495. <t-radio-button value="center">
  496. <t-tooltip content="居中" placement="top">
  497. <t-icon name="format-vertical-align-center" />
  498. </t-tooltip>
  499. </t-radio-button>
  500. <t-radio-button value="right">
  501. <t-tooltip content="居右" placement="top">
  502. <t-icon name="format-vertical-align-right" />
  503. </t-tooltip>
  504. </t-radio-button>
  505. </t-radio-group>
  506. <t-radio-group
  507. class="ml-8"
  508. size="small"
  509. v-model="data.textBaseline"
  510. default-value="top"
  511. @change="changeValue('textBaseline')"
  512. >
  513. <t-radio-button value="top">
  514. <t-tooltip content="顶部对齐" placement="top">
  515. <t-icon name="format-horizontal-align-top" />
  516. </t-tooltip>
  517. </t-radio-button>
  518. <t-radio-button value="middle">
  519. <t-tooltip content="垂直居中" placement="middle">
  520. <t-icon name="format-horizontal-align-center" />
  521. </t-tooltip>
  522. </t-radio-button>
  523. <t-radio-button value="bottom">
  524. <t-tooltip content="底部对齐" placement="top">
  525. <t-icon name="format-horizontal-align-bottom" />
  526. </t-tooltip>
  527. </t-radio-button>
  528. </t-radio-group>
  529. <t-button
  530. :class="{ active: data.fontWeight === 'bold' }"
  531. class="ml-8 icon"
  532. shape="rectangle"
  533. variant="text"
  534. @click="
  535. data.fontWeight === 'bold'
  536. ? (data.fontWeight = 'normal')
  537. : (data.fontWeight = 'bold');
  538. changeValue('fontWeight');
  539. "
  540. >
  541. B
  542. </t-button>
  543. <t-button
  544. :class="{ active: data.fontStyle === 'italic' }"
  545. class="ml-4 icon"
  546. shape="rectangle"
  547. variant="text"
  548. @click="
  549. data.fontStyle === 'italic'
  550. ? (data.fontStyle = 'normal')
  551. : (data.fontStyle = 'italic');
  552. changeValue('fontStyle');
  553. "
  554. style="font-style: italic; font-family: serif"
  555. >I</t-button
  556. >
  557. </div>
  558. <div class="form-item">
  559. <t-color-picker
  560. class="simple mt-8 mr-4"
  561. format="CSS"
  562. :enable-alpha="true"
  563. :color-modes="['monochrome']"
  564. :show-primary-color-preview="false"
  565. :clearable="true"
  566. v-model="data.color"
  567. @change="changeValue('color')"
  568. />
  569. <label style="width: 44px">前景</label>
  570. <t-color-picker
  571. class="simple mt-8 mr-4"
  572. :enable-alpha="true"
  573. format="CSS"
  574. :color-modes="['monochrome']"
  575. :show-primary-color-preview="false"
  576. v-model="data.background"
  577. @change="changeValue('background')"
  578. />
  579. <label style="width: 44px">背景</label>
  580. <t-color-picker
  581. class="simple mt-8 mr-4"
  582. :enable-alpha="true"
  583. format="CSS"
  584. :color-modes="['monochrome']"
  585. :show-primary-color-preview="false"
  586. v-model="data.hoverColor"
  587. @change="changeValue('hoverColor')"
  588. />
  589. <label style="width: 44px">悬停</label>
  590. <t-color-picker
  591. class="simple mt-8 mr-4"
  592. format="CSS"
  593. :enable-alpha="true"
  594. :color-modes="['monochrome']"
  595. :show-primary-color-preview="false"
  596. v-model="data.activeColor"
  597. @change="changeValue('activeColor')"
  598. />
  599. <label style="width: 44px">选中</label>
  600. </div>
  601. <div class="form-item">
  602. <t-checkbox
  603. v-model="data.whiteSpace"
  604. @change="changeValue('whiteSpace')"
  605. style="width: 64px"
  606. >
  607. 换行
  608. </t-checkbox>
  609. <t-checkbox
  610. v-model="data.ellipsis"
  611. @change="changeValue('ellipsis')"
  612. style="width: 68px"
  613. >
  614. 省略号
  615. </t-checkbox>
  616. <t-tooltip content="行高">
  617. <t-input
  618. placeholder="行高"
  619. v-model.number="data.lineHeight"
  620. style="width: 40px"
  621. @change="changeValue('lineHeight')"
  622. />
  623. </t-tooltip>
  624. <t-tooltip content="显示时保留小数位数">
  625. <t-input
  626. class="ml-4"
  627. placeholder="小数"
  628. v-model.number="data.keepDecimal"
  629. style="width: 60px"
  630. @change="changeValue('keepDecimal')"
  631. />
  632. </t-tooltip>
  633. </div>
  634. <div class="form-item" style="margin-top: -4px">
  635. <t-tooltip content="水平偏移">
  636. <t-input
  637. placeholder="X"
  638. v-model.number="data.textLeft"
  639. style="width: 60px; margin-left: -8px"
  640. @change="changeValue('textLeft')"
  641. />
  642. </t-tooltip>
  643. <t-tooltip content="垂直偏移">
  644. <t-input
  645. class="ml-4"
  646. placeholder="Y"
  647. v-model.number="data.textTop"
  648. style="width: 60px"
  649. @change="changeValue('textTop')"
  650. />
  651. </t-tooltip>
  652. <t-tooltip content="宽">
  653. <t-input
  654. class="ml-4"
  655. placeholder="宽"
  656. v-model.number="data.textWidth"
  657. style="width: 60px"
  658. @change="changeValue('textWidth')"
  659. />
  660. </t-tooltip>
  661. <t-tooltip content="高">
  662. <t-input
  663. class="ml-4"
  664. placeholder="高"
  665. v-model.number="data.textHeight"
  666. style="width: 60px"
  667. @change="changeValue('textHeight')"
  668. />
  669. </t-tooltip>
  670. </div>
  671. <div class="flex middle">
  672. <t-checkbox
  673. v-model="data.disableInput"
  674. @change="changeValue('disableInput')"
  675. style="width: 64px"
  676. >
  677. 只读
  678. </t-checkbox>
  679. <t-checkbox
  680. v-model="data.hiddenText"
  681. @change="changeValue('hiddenText')"
  682. style="width: 90px"
  683. >
  684. 隐藏文字
  685. </t-checkbox>
  686. </div>
  687. </t-space>
  688. </t-collapse-panel>
  689. </t-collapse>
  690. </t-space>
  691. <t-divider style="margin-top: -8px" />
  692. <div class="form-item p-16">
  693. <t-checkbox
  694. v-model="data.flipX"
  695. @change="changeValue('flipX')"
  696. style="width: 90px"
  697. >
  698. 水平翻转
  699. </t-checkbox>
  700. <t-checkbox
  701. v-model="data.flipY"
  702. @change="changeValue('flipY')"
  703. style="width: 90px"
  704. >
  705. 垂直翻转
  706. </t-checkbox>
  707. <label style="width: 50px">锚点半径</label>
  708. <input
  709. class="ml-4"
  710. v-model.number="data.anchorRadius"
  711. style="width: 20px"
  712. @change="changeValue('anchorRadius')"
  713. placeholder="4"
  714. />
  715. </div>
  716. <t-divider />
  717. <div class="form-item p-16" style="margin-bottom: 20px">
  718. <t-checkbox
  719. v-model="data.disableRotate"
  720. @change="changeValue('disableRotate')"
  721. style="width: 90px"
  722. >
  723. 禁止旋转
  724. </t-checkbox>
  725. <t-checkbox
  726. v-model="data.disableSize"
  727. @change="changeValue('disableSize')"
  728. style="width: 90px"
  729. >
  730. 禁止缩放
  731. </t-checkbox>
  732. <t-checkbox
  733. v-model="data.disableAnchor"
  734. @change="changeValue('disableAnchor')"
  735. style="width: 90px"
  736. >
  737. 禁用锚点
  738. </t-checkbox>
  739. </div>
  740. </t-tab-panel>
  741. </t-tabs>
  742. </div>
  743. </template>
  744. <script lang="ts" setup>
  745. import { onBeforeMount, onUnmounted, reactive, ref } from 'vue';
  746. import { LockState, Pen } from '@meta2d/core';
  747. import { updatePen } from './pen';
  748. import { useSelection } from '@/services/selections';
  749. import { fonts, setChildrenVisible } from '@/services/common';
  750. const { selections } = useSelection();
  751. const data = reactive<any>({
  752. tab: 1,
  753. locked: 0,
  754. lineWidth: 1,
  755. });
  756. const aligns = [
  757. {
  758. value: 'left',
  759. label: '左对齐',
  760. icon: '#l-align-left',
  761. },
  762. {
  763. value: 'right',
  764. label: '水平居中对齐',
  765. icon: '#l-align-center',
  766. },
  767. {
  768. value: 'right',
  769. label: '右对齐',
  770. icon: '#l-align-right',
  771. },
  772. {
  773. value: 'top',
  774. label: '顶部对齐',
  775. icon: '#l-align-top',
  776. },
  777. {
  778. value: 'right',
  779. label: '垂直居中对齐',
  780. icon: '#l-align-middle',
  781. },
  782. {
  783. value: 'bottom',
  784. label: '底部对齐',
  785. icon: '#l-align-bottom',
  786. },
  787. {
  788. value: 'h-distribute',
  789. label: '水平等距',
  790. icon: '#l-horizontal-between',
  791. },
  792. {
  793. value: 'v-distribute',
  794. label: '垂直等距',
  795. icon: '#l-vertical-between',
  796. },
  797. ];
  798. const aligns2 = [
  799. {
  800. value: 'left',
  801. label: '左对齐',
  802. icon: '#l-align-left',
  803. },
  804. {
  805. value: 'right',
  806. label: '水平居中对齐',
  807. icon: '#l-align-center',
  808. },
  809. {
  810. value: 'right',
  811. label: '右对齐',
  812. icon: '#l-align-right',
  813. },
  814. {
  815. value: 'top',
  816. label: '顶部对齐',
  817. icon: '#l-align-top',
  818. },
  819. {
  820. value: 'right',
  821. label: '垂直居中对齐',
  822. icon: '#l-align-middle',
  823. },
  824. {
  825. value: 'bottom',
  826. label: '底部对齐',
  827. icon: '#l-align-bottom',
  828. },
  829. {
  830. value: 'same-size',
  831. label: '相同大小',
  832. icon: '#l-same-size',
  833. },
  834. ];
  835. onBeforeMount(() => {});
  836. const lock = (v: LockState) => {
  837. data.locked = v;
  838. for (const item of selections.pens) {
  839. meta2d.setValue({
  840. id: item.id,
  841. locked: v,
  842. });
  843. }
  844. };
  845. const visible = (v: boolean) => {
  846. data.visible = v;
  847. for (const item of selections.pens) {
  848. meta2d.setVisible(item as any, v);
  849. }
  850. };
  851. const align = (align: string) => {
  852. if (align === 'h-distribute') {
  853. meta2d.spaceBetween(meta2d.store.active);
  854. } else if (align === 'v-distribute') {
  855. meta2d.spaceBetweenColumn(meta2d.store.active);
  856. } else {
  857. meta2d.alignNodes(align, meta2d.store.active);
  858. }
  859. };
  860. const align2 = (align: string) => {
  861. if (align === 'same-size') {
  862. meta2d.beSameByLast(meta2d.store.active);
  863. } else {
  864. meta2d.alignNodesByLast(align, meta2d.store.active);
  865. }
  866. };
  867. const changeValue = (prop: string) => {
  868. for (const item of selections.pens) {
  869. data.id = item.id;
  870. updatePen(data, prop, false);
  871. }
  872. meta2d.render();
  873. };
  874. const onFontFamily = (fontFamily: string) => {
  875. data.fontFamily = fontFamily;
  876. data.fontFamilyPopupVisible = false;
  877. changeValue('fontFamily');
  878. };
  879. const onFontPopupVisible = (val: boolean) => {
  880. data.fontFamilyPopupVisible = val;
  881. };
  882. const decimalRound = (val: number) => {
  883. return Math.round(+val || 0);
  884. };
  885. </script>
  886. <style lang="postcss" scoped>
  887. .props {
  888. .icons {
  889. display: flex;
  890. svg:hover {
  891. cursor: pointer;
  892. color: var(--color-primary);
  893. }
  894. .btn {
  895. font-size: 16px;
  896. margin-right: 16px;
  897. color: var(--color);
  898. }
  899. }
  900. }
  901. </style>