component.tsx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { IconPlay2 } from "@/assets/icons";
  2. import { useEditor } from "@/modules/editor";
  3. import { css } from "@linaria/core";
  4. import { IconClose } from "@queenjs/icons";
  5. import { Image } from "@queenjs/ui";
  6. import { queenApi, useModal } from "queenjs";
  7. import { defineComponent, reactive, watch } from "vue";
  8. import { string } from "vue-types";
  9. import { useCompData } from ".";
  10. import { View } from "../View";
  11. export const Component = defineComponent({
  12. props: {
  13. compId: string().isRequired,
  14. },
  15. setup(props) {
  16. const { store, actions } = useEditor();
  17. const comp = useCompData(props.compId);
  18. const { value } = comp;
  19. async function pickPack() {
  20. // await controls.pickCtrl.onPickPack();
  21. // value.url =
  22. // "https://www.sku3d.com/share.html?id=6478676ca494a3ea15a6fa82";
  23. }
  24. function showWeb3D() {
  25. if (value.inline) {
  26. state.show3d = true;
  27. } else {
  28. queenApi.dialog(<Iframe3D url={value.url} />, {
  29. fullscreen: true,
  30. closable: false,
  31. });
  32. }
  33. }
  34. const state = reactive({
  35. show3d: false,
  36. });
  37. watch(
  38. () => [value.ratio],
  39. () => {
  40. comp.setH(comp.getW() / value.ratio);
  41. actions.onCompLayoutUpdated(comp);
  42. }
  43. );
  44. return () => {
  45. return (
  46. <View
  47. compId={props.compId}
  48. onDblclick={store.isEditMode ? pickPack : undefined}
  49. >
  50. {state.show3d ? (
  51. <iframe class="w-full h-full border-none" src={value.url} />
  52. ) : (
  53. <>
  54. <Image
  55. class="w-full h-full pointer-events-none object-cover"
  56. size={480}
  57. src={value.poster}
  58. />
  59. <IconPlay2
  60. class={iconCls}
  61. onClick={!store.isEditMode ? showWeb3D : undefined}
  62. />
  63. </>
  64. )}
  65. </View>
  66. );
  67. };
  68. },
  69. });
  70. const Iframe3D = defineComponent({
  71. props: {
  72. url: string().isRequired,
  73. },
  74. setup(props) {
  75. const modal = useModal();
  76. return () => (
  77. <div class="w-full h-full overflow-hidden relative">
  78. <IconClose class={closeCls} onClick={() => modal.cancel()} />
  79. <iframe class="w-full h-full border-none" src={props.url} />
  80. </div>
  81. );
  82. },
  83. });
  84. const iconCls = css`
  85. position: absolute;
  86. top: 50%;
  87. left: 50%;
  88. padding: 15px;
  89. font-size: 50px;
  90. color: #666;
  91. transform: translate(-50%, -50%);
  92. border-radius: 50%;
  93. background-color: rgba(255, 255, 255, 0.7);
  94. `;
  95. const closeCls = css`
  96. position: absolute;
  97. top: 15px;
  98. left: 15px;
  99. font-size: 15px;
  100. color: #666;
  101. padding: 10px;
  102. border-radius: 50%;
  103. background-color: #fff;
  104. @apply shadow;
  105. `;