PensProps.vue 36 KB

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