Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

PhotoRun.vue 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <div class="photo-run" :class="previewClass" data-private>
  3. <div class="run__preview" :style="previewStyle" />
  4. <div
  5. v-if="run.preferences.body.randomize || run.preferences.body.progressive.enabled"
  6. class="run__preferences">
  7. <div class="preference">
  8. <span>Boobs</span>
  9. <span>{{ run.preferences.body.boobs.size | fixedValue }}</span>
  10. </div>
  11. <div class="preference">
  12. <span>Areola</span>
  13. <span>{{ run.preferences.body.areola.size | fixedValue }}</span>
  14. </div>
  15. <div class="preference">
  16. <span>Nipple</span>
  17. <span>{{ run.preferences.body.nipple.size | fixedValue }}</span>
  18. </div>
  19. <div class="preference">
  20. <span>Vagina</span>
  21. <span>{{ run.preferences.body.vagina.size | fixedValue }}</span>
  22. </div>
  23. <div class="preference">
  24. <span>Pubic hair</span>
  25. <span>{{ run.preferences.body.pubicHair.size | fixedValue }}</span>
  26. </div>
  27. </div>
  28. <div class="run__content">
  29. <div v-if="run.running" class="content__item">
  30. <p class="text-white">
  31. <span>
  32. <font-awesome-icon icon="running" />
  33. </span>
  34. <span>{{ run.timer.duration }}s</span>
  35. </p>
  36. </div>
  37. <div v-else-if="run.failed" class="content__item">
  38. <p class="text-danger-500">
  39. <span>
  40. <font-awesome-icon icon="exclamation-circle" />
  41. </span>
  42. <span>Error!</span>
  43. </p>
  44. </div>
  45. <div v-else-if="run.finished" class="content__item">
  46. <p class="text-white">
  47. <span>
  48. <font-awesome-icon icon="heart" />
  49. </span>
  50. <span>{{ run.timer.duration }}s</span>
  51. </p>
  52. </div>
  53. <div v-else class="content__item">
  54. <p class="text-white">
  55. <span>
  56. <font-awesome-icon icon="clock" />
  57. </span>
  58. </p>
  59. </div>
  60. <div v-show="run.finished && run.outputFile.exists" class="content__item">
  61. <button
  62. v-tooltip="'Open photo'"
  63. class="button button--info button--sm"
  64. @click.prevent="open">
  65. <font-awesome-icon icon="image" />
  66. </button>
  67. </div>
  68. <div v-show="run.finished && run.outputFile.exists" class="content__item">
  69. <button
  70. v-tooltip="'Save photo'"
  71. class="button button--info button--sm"
  72. @click.prevent="save">
  73. <font-awesome-icon icon="save" />
  74. </button>
  75. </div>
  76. <div v-show="run.finished" class="content__item">
  77. <button v-tooltip="'Rerun'" class="button button--success button--sm" @click.prevent="rerun">
  78. <font-awesome-icon icon="undo" />
  79. </button>
  80. </div>
  81. <div v-show="run.running" class="content__item">
  82. <button v-tooltip="'Stop'" class="button button--danger button--sm" @click.prevent="cancel">
  83. <font-awesome-icon icon="stop" />
  84. </button>
  85. </div>
  86. <div v-show="hasMaskfin" class="content__item">
  87. <button
  88. v-tooltip="'View Maskfin'"
  89. class="button button--sm"
  90. @click.prevent="$refs.maskfinDialog.showModal()">
  91. <font-awesome-icon icon="mask" />
  92. </button>
  93. </div>
  94. <div class="content__item">
  95. <button
  96. v-tooltip="'View terminal'"
  97. class="button button--sm"
  98. @click.prevent="$refs.terminalDialog.showModal()">
  99. <font-awesome-icon icon="terminal" />
  100. </button>
  101. </div>
  102. </div>
  103. <!-- Maskfin Dialog -->
  104. <dialog v-if="hasMaskfin" ref="maskfinDialog">
  105. <div class="dialog__content dialog__maskfin">
  106. <div class="maskfin__preview">
  107. <img :src="run.maskfinFile.path">
  108. </div>
  109. <div class="maskfin__description">
  110. <p>This is the Maskfin, a mask that represents in layers the areas that the algorithm will replace with the fake nude.</p>
  111. <p>Click on the "Add to queue" button to add it as an additional photo, edit the layers with the editor and continue with the nudification. You can also save it to your computer, edit it with an external program and continue the nudification manually.</p>
  112. <p>
  113. For more information please consult the
  114. <a :href="manualURL" target="_blank">guide</a>.
  115. </p>
  116. </div>
  117. <div class="dialog__buttons">
  118. <button class="button" @click.prevent="addMaskToQueue">
  119. Add to queue
  120. </button>
  121. <button class="button button--success" @click.prevent="saveMask">
  122. Save
  123. </button>
  124. <button class="button button--danger" @click.prevent="$refs.maskfinDialog.close()">
  125. Close
  126. </button>
  127. </div>
  128. </div>
  129. </dialog>
  130. <!-- Terminal Dialog -->
  131. <dialog ref="terminalDialog">
  132. <div class="dialog__content">
  133. <div class="terminal">
  134. <li
  135. v-for="(item, index) in run.cli.lines"
  136. :key="index"
  137. :class="item.css">
  138. > {{ item.text }}
  139. </li>
  140. </div>
  141. <div class="dialog__buttons">
  142. <button class="button button--danger" @click.prevent="$refs.terminalDialog.close()">
  143. Close
  144. </button>
  145. </div>
  146. </div>
  147. </dialog>
  148. </div>
  149. </template>
  150. <script>
  151. import { dreamtrack } from '~/modules/services'
  152. import { Nudify } from '~/modules/nudify'
  153. export default {
  154. filters: {
  155. size(value) {
  156. return Number.parseFloat(value).toFixed(2)
  157. },
  158. fixedValue(value) {
  159. return Number(value).toFixed(2)
  160. },
  161. },
  162. props: {
  163. run: {
  164. type: Object,
  165. required: true,
  166. },
  167. },
  168. computed: {
  169. previewStyle() {
  170. if (!this.run.finished) {
  171. return {}
  172. }
  173. const url = encodeURI(this.run.outputFile.path)
  174. return { backgroundImage: `url(${url})` }
  175. },
  176. previewClass() {
  177. return {
  178. 'run--failed': this.run.failed,
  179. 'run--running': this.run.running,
  180. 'run--finished': this.run.finished,
  181. }
  182. },
  183. hasMaskfin() {
  184. return this.run.maskfinFile.exists
  185. },
  186. manualURL() {
  187. return dreamtrack.get(
  188. 'urls.docs.manual',
  189. 'https://time.dreamnet.tech/docs/guide/upload',
  190. )
  191. },
  192. },
  193. methods: {
  194. save() {
  195. this.run.outputFile.save(this.run.outputName)
  196. },
  197. open() {
  198. this.run.outputFile.openItem()
  199. },
  200. rerun() {
  201. this.run.add()
  202. },
  203. cancel() {
  204. this.run.cancel()
  205. },
  206. addMaskToQueue() {
  207. Nudify.add(this.run.maskfinFile, { isMaskfin: true })
  208. },
  209. saveMask() {
  210. this.run.maskfinFile.save(`maskfin-${this.run.outputName}`)
  211. },
  212. },
  213. }
  214. </script>
  215. <style lang="scss" scoped>
  216. .photo-run {
  217. @apply relative border-2 border-dark-500;
  218. background-image: url("~@/assets/images/curls.png"); /* Background pattern from Toptal Subtle Patterns */
  219. min-height: 512px;
  220. transition: border-color 0.2s linear;
  221. &.run--failed {
  222. @apply border-danger-500;
  223. }
  224. &.run--running {
  225. @apply border-primary-500;
  226. }
  227. &.run--finished {
  228. .run__preview {
  229. @apply opacity-100;
  230. }
  231. }
  232. &:hover {
  233. @apply border-primary-300;
  234. .run__content,
  235. .run__preferences {
  236. @apply opacity-100;
  237. }
  238. }
  239. .run__preview {
  240. @apply absolute opacity-0 left-0 right-0 top-0 bottom-0 z-10;
  241. @apply bg-contain bg-center bg-no-repeat;
  242. transition: opacity 0.3s linear;
  243. }
  244. }
  245. .run__content,
  246. .run__preferences {
  247. @apply absolute z-20;
  248. @apply flex opacity-0 bg-dark-800-80 w-full;
  249. backdrop-filter: blur(6px);
  250. transition: opacity 0.1s linear;
  251. }
  252. .run__preferences {
  253. @apply flex top-0;
  254. height: 80px;
  255. .preference {
  256. @apply flex flex-col flex-1 items-center justify-center;
  257. span {
  258. &:first-child {
  259. @apply text-xs;
  260. }
  261. &:last-child {
  262. @apply text-sm text-white font-bold;
  263. }
  264. }
  265. }
  266. }
  267. .run__content {
  268. @apply bottom-0;
  269. height: 100px;
  270. .content__item {
  271. @apply flex-1 flex justify-center items-center;
  272. &:not(:first-child) {
  273. @apply mr-2;
  274. }
  275. .button {
  276. @apply w-full;
  277. }
  278. p {
  279. @apply font-bold text-center;
  280. span {
  281. @apply block;
  282. }
  283. }
  284. }
  285. }
  286. .dialog__maskfin {
  287. a {
  288. @apply text-primary-500 underline;
  289. }
  290. .maskfin__preview {
  291. @apply mb-4 flex justify-center items-center;
  292. img {
  293. max-height: 350px;
  294. }
  295. }
  296. .maskfin__description {
  297. @apply mb-4 text-sm;
  298. p {
  299. @apply mb-2;
  300. }
  301. }
  302. }
  303. .section__preferences {
  304. p {
  305. @apply text-sm;
  306. .preference__name {
  307. @apply inline-block text-generic-300;
  308. width: 150px;
  309. }
  310. .preference__value {
  311. @apply inline-block font-bold text-generic-100;
  312. }
  313. }
  314. }
  315. .terminal {
  316. @apply p-2 mb-2 bg-black overflow-auto rounded;
  317. height: 400px;
  318. li {
  319. @apply font-mono text-xs text-generic-100 mb-2 block;
  320. &.text-danger {
  321. @apply text-danger-500;
  322. }
  323. }
  324. }
  325. </style>