PensProps.vue 34 KB

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