CodePreviewIndex.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398
  1. <template>
  2. <div class="platform-sdk-code rounded-20px">
  3. <div class="relative flex justify-between rounded-t-30px border-b-1px border-b-[#EEEEEE] <lg:hidden">
  4. <div
  5. v-for="(device, index) in devices"
  6. :key="index"
  7. :class="[
  8. 'item',
  9. 'relative',
  10. 'flex',
  11. 'flex-col',
  12. 'items-center',
  13. 'mb-10px',
  14. 'py-12px',
  15. 'font-bold',
  16. 'cursor-pointer',
  17. 'hover:text-[#272E3B]',
  18. device === currentPlatform ? '!text-brand-0' : 'text-[#AAAEB7]',
  19. { active: device === currentPlatform }
  20. ]"
  21. @click="currentPlatform = device"
  22. >
  23. <component :is="device" />
  24. <span class="inline-block mt-10px text-tiny">{{ device }}</span>
  25. </div>
  26. </div>
  27. <div class="code-container relative flex flex-1 flex-col lg:mt-40px <lg:mt-16px text-left rounded-16px overflow-hidden <lg:hidden">
  28. <div class="px-24px pt-24px pb-44px bg-[#272E3B]">
  29. <div class="options">
  30. <span
  31. v-for="(value, key, index) in code[currentPlatform]"
  32. :key="key"
  33. class="code-tab inline-block p-8px rounded-4px text-sm font-bold text-[#FFFFFFA6]"
  34. :class="[
  35. 'relative',
  36. currentLanguageIndex === index ? '!text-white bg-[#545C6A]' : 'hover:text-white active:text-[#FFFFFFD9]',
  37. index && 'ml-16px',
  38. 'text-sm',
  39. 'cursor-pointer'
  40. ]"
  41. @click="changeLanguage(key, index)"
  42. >{{ key }}</span>
  43. </div>
  44. <pre
  45. class="flex-grow-1 h-550px mt-24px pb-44px overflow-auto"
  46. ><code
  47. ref="code-content"
  48. class="text-sm text-white whitespace-pre-wrap"
  49. v-html="code[currentPlatform][currentLanguage]"
  50. ></code></pre>
  51. <transition>
  52. <span
  53. v-show="copied"
  54. class="toast absolute bottom-170px right-14px opacity-100 py-5px px-8px text-sm rounded-4px bg-[#CCCCCC] transition-all duration-300"
  55. >Copied</span>
  56. </transition>
  57. <span class="<lg:hidden absolute bottom-120px right-24px flex justify-center items-center w-46px h-46px cursor-pointer bg-[#FFFFFF29] text-[#FFFFFFA6] rounded-full hover:text-[#FFFFFF] active:text-[#FFFFFFD9]">
  58. <Copy
  59. @click="copy(code[currentPlatform][currentLanguage])"
  60. />
  61. </span>
  62. </div>
  63. <div class="help relative flex items-center py-24px pl-24px bg-white rounded-b-16px">
  64. <a v-if="currentPlatform !== 'Web' && currentPlatform !== 'Linux'" class="flex items-center mr-28px cursor-pointer" :href="getGuidesUrl()">
  65. <Guides /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">操作指南</span>
  66. </a>
  67. <a class="flex items-center cursor-pointer mr-28px" href="/contact-sales">
  68. <Contact class="rounded-full bg-[#EBF2FF] text-[#256FFF]" /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">联系我们</span>
  69. </a>
  70. <a class="flex items-center cursor-pointer" href="https://www.pdfreaderpro.com/online-tools">
  71. <Trial /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">在线试用</span>
  72. </a>
  73. </div>
  74. </div>
  75. <template
  76. v-for="(device, index) in devices"
  77. >
  78. <div
  79. :key="index"
  80. ref="platform"
  81. :class="[
  82. 'relative',
  83. 'flex',
  84. 'items-center',
  85. 'justify-between',
  86. 'rounded-8px',
  87. 'p-16px',
  88. 'mt-16px',
  89. 'bg-white',
  90. 'lg:hidden',
  91. 'font-bold',
  92. 'cursor-pointer',
  93. device === currentPlatform && !minHidden ? 'text-brand-0' : 'text-[#AAAEB7]',
  94. ]"
  95. @click="handlePlatformChange(device, index)"
  96. >
  97. <div class="flex items-center">
  98. <component :is="device" class="w-24px h-auto" />
  99. <span class="inline-block <lg:ml-16px <lg:text-16px <lg:leading-16px">{{ device }}</span>
  100. </div>
  101. <Arrow class="w-16px h-auto transform" :class="currentPlatform === device && !minHidden ? 'rotate-270' : 'rotate-90'" />
  102. </div>
  103. <div v-if="device === currentPlatform && width < 930 && !minHidden" class="code-container relative flex flex-1 flex-col lg:mt-40px <lg:mt-16px text-left rounded-16px overflow-hidden lg:hidden">
  104. <div class="px-24px pt-24px pb-44px bg-[#272E3B]">
  105. <div class="options">
  106. <span
  107. v-for="(value, key, index) in code[currentPlatform]"
  108. :key="key"
  109. class="code-tab inline-block p-8px rounded-4px text-sm font-bold text-[#FFFFFFA6]"
  110. :class="[
  111. 'relative',
  112. currentLanguageIndex === index ? '!text-white bg-[#545C6A]' : 'hover:text-white active:text-[#FFFFFFD9]',
  113. index && 'ml-16px',
  114. 'text-sm',
  115. 'cursor-pointer'
  116. ]"
  117. @click="changeLanguage(key, index)"
  118. >{{ key }}</span>
  119. </div>
  120. <pre
  121. class="flex-grow-1 h-550px mt-24px pb-44px overflow-auto"
  122. ><code
  123. ref="code-content"
  124. class="text-sm text-white whitespace-pre-wrap"
  125. v-html="code[currentPlatform][currentLanguage]"
  126. ></code></pre>
  127. <transition>
  128. <span
  129. v-show="copied"
  130. class="toast absolute bottom-170px right-14px opacity-100 py-5px px-8px text-sm rounded-4px bg-[#CCCCCC] transition-all duration-300"
  131. >Copied</span>
  132. </transition>
  133. <span class="<lg:hidden absolute bottom-120px right-24px flex justify-center items-center w-46px h-46px cursor-pointer bg-[#FFFFFF29] text-[#FFFFFFA6] rounded-full hover:text-[#FFFFFF] active:text-[#FFFFFFD9]">
  134. <Copy
  135. @click="copy(code[currentPlatform][currentLanguage])"
  136. />
  137. </span>
  138. </div>
  139. <div class="help relative flex items-center py-24px pl-8px bg-white rounded-b-16px">
  140. <a v-if="currentPlatform !== 'Web' && currentPlatform !== 'Linux'" class="flex items-center mr-13px cursor-pointer" :href="getGuidesUrl()">
  141. <Guides /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">操作指南</span>
  142. </a>
  143. <a class="flex items-center cursor-pointer mr-13px" href="/contact-sales">
  144. <Contact class="rounded-full bg-[#EBF2FF] text-[#256FFF]" /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">联系我们</span>
  145. </a>
  146. <a class="flex items-center cursor-pointer" href="https://www.pdfreaderpro.com/online-tools">
  147. <Trial /><span class="text-brand-3 text-sm ml-6px hover:text-brand-0">在线试用</span>
  148. </a>
  149. </div>
  150. </div>
  151. </template>
  152. </div>
  153. </template>
  154. <script>
  155. import { ResizeObserver } from '@juggle/resize-observer'
  156. import clipboard from 'copy-to-clipboard'
  157. import iOS from '~/assets/images/icons/apple.svg?inline'
  158. import Mac from '~/assets/images/icons/macos.svg?inline'
  159. import Android from '~/assets/images/icons/android.svg?inline'
  160. import Windows from '~/assets/images/icons/windows.svg?inline'
  161. import Web from '~/assets/images/icons/web.svg?inline'
  162. import Copy from '~/assets/images/icons/copy.svg?inline'
  163. import Guides from '~/assets/images/icons/guides.svg?inline'
  164. import Contact from '~/assets/images/icons/contact.svg?inline'
  165. import Arrow from '~/assets/images/icons/arrow.svg?inline'
  166. import Trial from '~/assets/images/icons/trial.svg?inline'
  167. import Linux from '~/assets/images/icons/linux.svg?inline'
  168. export default {
  169. components: {
  170. iOS,
  171. Mac,
  172. Android,
  173. Windows,
  174. Web,
  175. Copy,
  176. Guides,
  177. Contact,
  178. Arrow,
  179. Trial,
  180. Linux
  181. },
  182. props: {
  183. platform: {
  184. default: 'iOS'
  185. },
  186. language: {
  187. default: 'Objective-C'
  188. },
  189. languageIndex: {
  190. default: 0
  191. },
  192. code: Object,
  193. devices: Array
  194. },
  195. data () {
  196. return {
  197. currentPlatform: this.platform,
  198. currentLanguage: this.language,
  199. currentLanguageIndex: this.languageIndex,
  200. copied: false,
  201. timer: null,
  202. showOptions: false,
  203. width: 929,
  204. minHidden: false
  205. }
  206. },
  207. watch: {
  208. code () {
  209. if (!this.code.Web) {
  210. this.currentPlatform = 'iOS'
  211. this.currentLanguage = 'Objective-C'
  212. }
  213. },
  214. currentPlatform (value, oldValue) {
  215. if (value === oldValue) {
  216. return
  217. }
  218. this.currentLanguageIndex = 0
  219. switch (value) {
  220. case 'iOS':
  221. case 'Mac':
  222. this.currentLanguage = 'Objective-C'
  223. break
  224. case 'Android':
  225. this.currentLanguage = 'Java'
  226. break
  227. case 'Windows':
  228. this.currentLanguage = 'C# WPF'
  229. break
  230. case 'Web':
  231. this.currentLanguage = 'JavaScript'
  232. break
  233. case 'Linux':
  234. this.currentLanguage = 'CMD'
  235. break
  236. }
  237. }
  238. },
  239. mounted () {
  240. document.addEventListener('click', () => {
  241. if (this.showOptions) {
  242. this.showOptions = false
  243. }
  244. })
  245. const ro = new ResizeObserver((entries, observer) => {
  246. entries.forEach((entry, index) => {
  247. const { inlineSize: width } = entry.borderBoxSize[0]
  248. this.width = width
  249. })
  250. })
  251. ro.observe(document.body)
  252. },
  253. methods: {
  254. changeLanguage (language, index) {
  255. if (this.currentLanguage === language) {
  256. return
  257. }
  258. this.currentLanguage = language
  259. this.currentLanguageIndex = index
  260. },
  261. handlePlatformChange (platform, index) {
  262. if (platform === this.currentPlatform) {
  263. if (this.width < 930) {
  264. this.minHidden = !this.minHidden
  265. }
  266. return
  267. }
  268. this.minHidden = false
  269. this.currentPlatform = platform
  270. this.$nextTick(() => {
  271. window.scrollTo({
  272. left: 0,
  273. top: this.$refs.platform[index].offsetTop - 66
  274. })
  275. })
  276. },
  277. getGuidesUrl () {
  278. if (this.currentPlatform === 'Web' || this.currentPlatform === 'Linux') {
  279. return false
  280. } else {
  281. return 'https://www.compdf.com/guides/' + this.currentPlatform.toLowerCase()
  282. }
  283. },
  284. copy (content) {
  285. content = content.replace(/<\/?.+?>/g, '')
  286. content = content.replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&').replace(/&quot;/g, '"')
  287. clipboard(content, {
  288. format: 'text/plain'
  289. })
  290. this.copied = true
  291. if (this.timer) {
  292. clearTimeout(this.timer)
  293. this.timer = null
  294. }
  295. this.timer = setTimeout(() => {
  296. this.copied = false
  297. }, 1500)
  298. }
  299. }
  300. }
  301. </script>
  302. <style lang="scss" scoped>
  303. .item.active::after {
  304. content: '';
  305. position: absolute;
  306. left: 0;
  307. bottom: -11px;
  308. display: block;
  309. width: 100%;
  310. height: 2px;
  311. background-color: #1460F3;
  312. transition: width .3s;
  313. }
  314. .item {
  315. width: 28%;
  316. max-width: 204px;
  317. svg {
  318. width: auto;
  319. height: 35px;
  320. }
  321. }
  322. .over-arrow::after {
  323. margin-top: -5px;
  324. border-color: transparent transparent #000 transparent;
  325. }
  326. .code-tab {
  327. &::after {
  328. content: '';
  329. position: absolute;
  330. left: 50%;
  331. transform: translateX(-50%);
  332. bottom: 0;
  333. display: block;
  334. width: 0;
  335. height: 2px;
  336. background-color: transparent;
  337. transition: width .3s;
  338. }
  339. &.active::after {
  340. width: calc(100% - 40px);
  341. background-color: #0097FF;
  342. }
  343. }
  344. .code-container {
  345. box-shadow: 0px 3px 35px rgba(129, 149, 200, 0.18);
  346. }
  347. .toast.v-enter, .toast.v-leave-to {
  348. opacity: 0;
  349. bottom: 50px;
  350. }
  351. pre {
  352. code {
  353. font-family: Consolas, Helvetica;
  354. ::v-deep {
  355. .hljs-variable, .statement {
  356. color: #7B563D;
  357. }
  358. .hljs-string, .string {
  359. color: #C0402D;
  360. }
  361. .hljs-keyword, .keyword {
  362. color: #A0459F;
  363. }
  364. .hljs-title, .title {
  365. color: #367AAC;
  366. }
  367. .hljs-comment, .comment {
  368. color: #70A14F;
  369. }
  370. }
  371. }
  372. }
  373. .help::after {
  374. content: '';
  375. position: absolute;
  376. top: -19px;
  377. left: 0;
  378. display: block;
  379. width: 100%;
  380. height: 19px;
  381. background: linear-gradient(90deg, rgba(20, 96, 243, 0.9) 29.22%, rgba(255, 255, 255, 0.1) 100%);
  382. }
  383. @media screen and (max-width: 929px) {
  384. pre::-webkit-scrollbar{
  385. width: 6px;
  386. height: 6px;
  387. }
  388. pre::-webkit-scrollbar-thumb{
  389. background: rgba(255, 255, 255, 0.32);
  390. border-radius:10px;
  391. }
  392. pre::-webkit-scrollbar-corner {
  393. background-color: transparent;
  394. }
  395. }
  396. </style>