bianjiang 1 an în urmă
părinte
comite
6861820e78

BIN
src/assets/audio/balmy_wind.mp3


BIN
src/assets/audio/bright_sunshine.mp3


BIN
src/assets/audio/destiny&hope.mp3


BIN
src/assets/audio/dynamic&energetic.mp3


BIN
src/assets/audio/inspiration_vigour.mp3


BIN
src/assets/audio/inspirational_hope.mp3


BIN
src/assets/audio/inspirational_vitality.mp3


BIN
src/assets/audio/soar_into_the_sky.mp3


BIN
src/assets/audio/soothing&quiet.mp3


BIN
src/assets/audio/spring&autumn.mp3


BIN
src/assets/audio/sunset_in_newyork.mp3


BIN
src/assets/audio/warm_memories.mp3


+ 18 - 0
src/assets/icons/components/IconMusic.tsx

@@ -0,0 +1,18 @@
+
+import { createIcon } from '@queenjs/icons';
+export const IconMusic = createIcon(<svg viewBox="0 0 30 30">
+
+    <g transform="translate(-21833 -3559)">
+        <path fill="none" stroke="#fff" stroke-width="2px"
+            d="M18,32A14,14,0,1,0,4,18,14,14,0,0,0,18,32Z" transform="translate(21830 3556)" />
+        <path stroke-linecap="round" stroke-linejoin="round" fill="none" stroke="#fff"
+            stroke-width="2px" d="M26,14v9.8"
+            transform="translate(21823.4 3553)" />
+        <path stroke-linejoin="round" fill="none" stroke="#fff" stroke-width="2px"
+            d="M14,27.566A2.823,2.823,0,0,1,17.024,25H22.4v3.034A2.823,2.823,0,0,1,19.376,30.6H17.024A2.823,2.823,0,0,1,14,28.034Z"
+            transform="translate(21827 3549.7)" />
+        <path stroke-linejoin="round" stroke-linecap="round" fill="none" stroke="#fff"
+            stroke-width="2px" d="M30.2,14.7,26,14"
+            transform="translate(21823.4 3553)" />
+    </g>
+</svg>)

+ 0 - 1
src/assets/icons/components/IconQueen.tsx

@@ -1,7 +1,6 @@
 
 import { createIcon } from '@queenjs/icons';
 export const IconQueen = createIcon(<svg viewBox="0 0 33 33">
-  
   <g transform="translate(3 2)">
     <path fill="currentColor"
       d="M59.576,345.96h-.73c-.038,0-.076-.011-.115-.013-.318-.021-.637-.026-.953-.065-.432-.053-.864-.12-1.292-.2a12.65,12.65,0,0,1-2.631-.808A13.673,13.673,0,0,1,48.4,340.7a13.508,13.508,0,0,1-2.351-4.538,12.879,12.879,0,0,1-.5-2.532c-.032-.356-.068-.713-.069-1.069-.007-1.638,0-3.277,0-4.915,0-.112.006-.224.015-.335a.634.634,0,0,1,.545-.553c.16-.014.32-.017.481-.017H71.9c.119,0,.239,0,.358,0a.72.72,0,0,1,.367.1.683.683,0,0,1,.315.626c0,1.553,0,3.106,0,4.66a14.366,14.366,0,0,1-.13,1.992,13.314,13.314,0,0,1-.3,1.531,13.718,13.718,0,0,1-11.56,10.2c-.428.054-.861.071-1.292.105C59.633,345.95,59.6,345.956,59.576,345.96Zm-.359-14.652H50.5a.451.451,0,0,0-.45.42,9.764,9.764,0,0,0,.062,1.573,11.238,11.238,0,0,0,.217,1.162A9.033,9.033,0,0,0,53.4,339.3a8.913,8.913,0,0,0,2.774,1.566,9.228,9.228,0,0,0,4.072.461,8.7,8.7,0,0,0,1.242-.229,9.089,9.089,0,0,0,4.8-3.057,8.894,8.894,0,0,0,1.484-2.548,8.7,8.7,0,0,0,.57-2.571c.024-.391.021-.783.03-1.174a.338.338,0,0,0-.007-.065.474.474,0,0,0-.47-.376Q63.555,331.311,59.216,331.308Z"

+ 1 - 0
src/assets/icons/index.ts

@@ -10,6 +10,7 @@ export * from "./components/IconFloatOn";
 export * from "./components/IconLayerDown";
 export * from "./components/IconLayerUp";
 export * from "./components/IconMove";
+export * from "./components/IconMusic";
 export * from "./components/IconQueen";
 export * from "./components/IconResizeY";
 export * from "./components/IconRotate";

+ 16 - 0
src/assets/icons/svg/music.svg

@@ -0,0 +1,16 @@
+<svg viewBox="0 0 30 30">
+
+    <g transform="translate(-21833 -3559)">
+        <path fill="none" stroke="#fff" stroke-width="2px"
+            d="M18,32A14,14,0,1,0,4,18,14,14,0,0,0,18,32Z" transform="translate(21830 3556)" />
+        <path stroke-linecap="round" stroke-linejoin="round" fill="none" stroke="#fff"
+            stroke-width="2px" d="M26,14v9.8"
+            transform="translate(21823.4 3553)" />
+        <path stroke-linejoin="round" fill="none" stroke="#fff" stroke-width="2px"
+            d="M14,27.566A2.823,2.823,0,0,1,17.024,25H22.4v3.034A2.823,2.823,0,0,1,19.376,30.6H17.024A2.823,2.823,0,0,1,14,28.034Z"
+            transform="translate(21827 3549.7)" />
+        <path stroke-linejoin="round" stroke-linecap="round" fill="none" stroke="#fff"
+            stroke-width="2px" d="M30.2,14.7,26,14"
+            transform="translate(21823.4 3553)" />
+    </g>
+</svg>

+ 34 - 17
src/modules/editor/components/CompUI/basicUI/Page/PageForm.tsx

@@ -4,36 +4,53 @@ import FormUI, { ColumnItem } from "@queenjs/components/FormUI";
 import { defineComponent } from "vue";
 import { any } from "vue-types";
 import { createColorOpts } from "../../defines/formOpts/createColorOpts";
-
-const styleColumns: ColumnItem[] = [
-  // {
-  //   label: "内边距",
-  //   dataIndex: "layout.padding",
-  //   component: "Input",
-  // },
-  {
-    label: "背景颜色",
-    dataIndex: "layout.background.color",
-    ...createColorOpts(),
-  },
-];
-
+import { PageMusic } from "./PageMusic";
+import { Select } from "ant-design-vue";
+import { MusicOptions } from "./localMusic";
+const styleColumns = (muisc: string): ColumnItem[] => {
+  return [
+    {
+      label: "背景颜色",
+      dataIndex: "layout.background.color",
+      ...createColorOpts(),
+    },
+    {
+      label: "背景音乐",
+      dataIndex: "value.music",
+      component: Select,
+      props: {
+        class: "w-full",
+        defaultValue: muisc,
+        options: [{ label: "无", value: "" }, ...MusicOptions],
+      },
+    },
+    {
+      dataIndex: "value.music",
+      component: PageMusic,
+      isVisible: (value, data) => data?.value?.music != "",
+    },
+  ];
+};
 export const PageForm = defineComponent({
   props: {
     component: any<DesignComp>().isRequired,
   },
   setup(props) {
-    const { actions } = useEditor();
+    const { actions, helper } = useEditor();
     function changeVal(e: { dataIndex: string; value: any }) {
       actions.updateCompData(props.component, e.dataIndex, e.value);
     }
 
     return () => {
-      const { layout } = props.component;
+      const music = helper.findRootComp()?.value.music || "";
       return (
         <>
           <div>页面样式</div>
-          <FormUI data={layout} columns={styleColumns} onChange={changeVal} />
+          <FormUI
+            data={props.component}
+            columns={styleColumns(music)}
+            onChange={changeVal}
+          />
         </>
       );
     };

+ 222 - 0
src/modules/editor/components/CompUI/basicUI/Page/PageMusic.tsx

@@ -0,0 +1,222 @@
+import { useEditor } from "@/modules/editor";
+import { PauseCircleOutlined, PlayCircleOutlined } from "@ant-design/icons-vue";
+import { css } from "@linaria/core";
+import { Button, Slider } from "ant-design-vue";
+import { defineComponent, reactive, ref, watch } from "vue";
+import { number, bool } from "vue-types";
+import { IconMusic } from "@/assets/icons";
+export const PageMusic = defineComponent({
+  setup(props) {
+    const { store, actions, helper } = useEditor();
+    const state = reactive({
+      playStatus: false,
+      duration: 0,
+      currentTime: 0,
+    });
+    const rootComp = helper.findRootComp();
+
+    const audioRef = ref();
+
+    const playAudio = (status: boolean) => {
+      if (status) {
+        audioRef.value.play();
+      } else {
+        audioRef.value.pause();
+        audioRest();
+      }
+      state.playStatus = status;
+    };
+    watch(
+      () => rootComp?.value.music,
+      () => {
+        audioRest();
+      }
+    );
+    const audioRest = () => {
+      state.playStatus = false;
+      audioRef.value.currentTime = 0;
+    };
+
+    const timeChange = (v: number) => {
+      state.currentTime = v;
+      audioRef.value.currentTime = v;
+    };
+    return () => {
+      const music = rootComp?.value.music;
+      return (
+        <div class={store.isEditMode ? MusicEditStyle : MusicStyle}>
+          {store.isEditMode ? (
+            <AudioPlayer
+              key={music}
+              playStatus={state.playStatus}
+              onStatus={playAudio}
+              onDuration={timeChange}
+              duration={state.duration}
+              currentTime={state.currentTime}
+            />
+          ) : (
+            <div
+              onClick={() => {
+                playAudio(!state.playStatus);
+              }}
+            >
+              <IconMusic />
+            </div>
+          )}
+          {music}
+          <audio
+            controls={false}
+            ref={audioRef}
+            key={music}
+            autoplay={store.isEditMode ? false : true}
+            loop={store.isEditMode ? false : true}
+            onLoadedmetadata={(e: any) => {
+              state.duration = e.target?.duration;
+            }}
+            onTimeupdate={(e: any) => {
+              state.currentTime = e.target.currentTime;
+            }}
+            onEnded={() => {
+              audioRest();
+            }}
+          >
+            <source src={music} type="audio/mpeg" />
+            <p>你的浏览器不支持音频播放</p>
+          </audio>
+        </div>
+      );
+    };
+  },
+});
+
+const AudioPlayer = defineComponent({
+  props: {
+    playStatus: bool(),
+    currentTime: number(),
+    duration: number(),
+  },
+  emits: ["status", "duration"],
+  setup(props, { emit }) {
+    const audioControl = (playStatus: boolean) => {
+      emit("status", playStatus);
+    };
+    const durationChange = (v: any) => {
+      emit("duration", v);
+    };
+    const transTime = (value?: number) => {
+      let time = "";
+      if (!value) {
+        return "00:00";
+      }
+      const h = parseInt(`${value / 3600}`);
+      value %= 3600;
+      let m = parseInt(`${value / 60}`);
+      let s = parseInt(`${value % 60}`);
+      if (h > 0) {
+        time = formatTime(h + ":" + m + ":" + s);
+      } else {
+        time = formatTime(m + ":" + s);
+      }
+
+      return time;
+    };
+    const formatTime = (value: string) => {
+      let time = "";
+      const s = value.split(":");
+      let i = 0;
+      for (; i < s.length - 1; i++) {
+        time += s[i].length === 1 ? "0" + s[i] : s[i];
+        time += ":";
+      }
+      time += s[i].length === 1 ? "0" + s[i] : s[i];
+
+      return time;
+    };
+    return () => {
+      return (
+        <div class={AudioPlayerStyle}>
+          {!props.playStatus ? (
+            <Button
+              type="link"
+              icon={<PlayCircleOutlined style={{ fontSize: "24px" }} />}
+              onClick={() => audioControl(true)}
+            ></Button>
+          ) : (
+            <Button
+              type="link"
+              icon={<PauseCircleOutlined style={{ fontSize: "24px" }} />}
+              onClick={() => audioControl(false)}
+            ></Button>
+          )}
+          <div class={"flex-1 px-10px"}>
+            <Slider
+              disabled={!props.playStatus}
+              tooltipVisible={false}
+              min={0}
+              max={props.duration}
+              value={props.currentTime}
+              onChange={durationChange}
+            ></Slider>
+          </div>
+          <div>
+            {transTime(props.currentTime)}/{transTime(props.duration)}
+          </div>
+        </div>
+      );
+    };
+  },
+});
+const MusicEditStyle = css`
+  flex: 1;
+`;
+const AudioPlayerStyle = css`
+  width: 100%;
+  display: flex;
+  align-items: center;
+
+  /* slider style */
+  .ant-slider-disabled {
+    opacity: 0.7;
+  }
+  .ant-slider-step {
+    background-color: rgba(255, 255, 255, 0.27);
+  }
+  .ant-slider-track {
+    border-radius: 4px;
+    background-color: rgba(255, 255, 255, 1);
+  }
+
+  .ant-slider:not(.ant-slider-disabled):hover {
+    .ant-slider-handle {
+      background-color: @inf-primary-color;
+      &:not(.ant-tooltip-open) {
+        border-color: #fff;
+      }
+    }
+  }
+  .ant-slider {
+    &.ant-slider-disabled {
+      .ant-slider-handle {
+        background-color: #bbb;
+        opacity: 0.8;
+      }
+    }
+  }
+  .ant-slider-handle {
+    width: 8px;
+    border-radius: 2px;
+    border-color: #fff;
+    background-color: #fff;
+  }
+
+  .ant-slider-handle-click-focused {
+    border-color: #fff;
+    background-color: @inf-primary-color;
+  }
+`;
+const MusicStyle = css`
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 999;
+`;

+ 10 - 4
src/modules/editor/components/CompUI/basicUI/Page/component.tsx

@@ -4,6 +4,7 @@ import { useCompData } from ".";
 import { useEditor } from "../../../..";
 import { useCompRef } from "../hooks";
 import { css } from "@linaria/core";
+import { PageMusic } from "./PageMusic";
 
 export const Component = defineComponent({
   props: {
@@ -12,11 +13,15 @@ export const Component = defineComponent({
   setup(props, { slots }) {
     const editor = useEditor();
     const { helper } = editor;
-    const { children, layout } = useCompData(props.compId);
+    const { children, layout, value } = useCompData(props.compId);
     const compRef = useCompRef(props.compId);
 
     return () => (
-      <div ref={compRef} style={helper.createStyle(layout)} class={["!h-auto" , editor.store.isEditMode? pageEditStyle :""]}>
+      <div
+        ref={compRef}
+        style={helper.createStyle(layout)}
+        class={["!h-auto", editor.store.isEditMode ? pageEditStyle : ""]}
+      >
         <div class="relative">
           {slots.Container?.(
             children.default.map((compId) => {
@@ -24,6 +29,7 @@ export const Component = defineComponent({
               return slots.CompItem?.(comp);
             })
           )}
+          {value.music && !editor.store.isEditMode && <PageMusic />}
         </div>
       </div>
     );
@@ -31,5 +37,5 @@ export const Component = defineComponent({
 });
 
 const pageEditStyle = css`
-   box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.4);
-`
+  box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.4);
+`;

+ 50 - 0
src/modules/editor/components/CompUI/basicUI/Page/localMusic.ts

@@ -0,0 +1,50 @@
+export const MusicOptions = [
+  {
+    label: "安静舒缓",
+    value: require("@/assets/audio/soothing&quiet.mp3"),
+  },
+  {
+    label: "和煦的风",
+    value: require("@/assets/audio/balmy_wind.mp3"),
+  },
+  {
+    label: "纽约落日",
+    value: require("@/assets/audio/sunset_in_newyork.mp3"),
+  },
+  {
+    label: "温情回忆",
+    value: require("@/assets/audio/warm_memories.mp3"),
+  },
+  {
+    label: "春华秋实",
+    value: require("@/assets/audio/spring&autumn.mp3"),
+  },
+  {
+    label: "明媚阳光",
+    value: require("@/assets/audio/bright_sunshine.mp3"),
+  },
+  {
+    label: "动感活力",
+    value: require("@/assets/audio/dynamic&energetic.mp3"),
+  },
+  {
+    label: "冲上云霄",
+    value: require("@/assets/audio/soar_into_the_sky.mp3"),
+  },
+  {
+    label: "命运希望",
+    value: require("@/assets/audio/destiny&hope.mp3"),
+  },
+  {
+    label: "励志活力",
+    value: require("@/assets/audio/inspirational_vitality.mp3"),
+  },
+  {
+    label: "励志希望",
+    value: require("@/assets/audio/inspirational_hope.mp3"),
+  },
+  {
+    label: "活力鼓舞",
+    value: require("@/assets/audio/inspiration_vigour.mp3"),
+  },
+];

+ 4 - 3
src/modules/editor/components/Preview/index.tsx

@@ -7,7 +7,8 @@ export default defineComponent({
   setup() {
     const { store, helper } = useEditor();
     const rootRef = useCompRef("root");
-    return () => (
+
+    return () => {
       <div
         ref={rootRef}
         class="overflow-hidden !h-auto"
@@ -20,7 +21,7 @@ export default defineComponent({
           const Comp: any = (CompUI[compKey] || CompUI.Container).Component;
           return Comp && <Comp key={id} compId={id} />;
         })}
-      </div>
-    );
+      </div>;
+    };
   },
 });

+ 8 - 9
src/modules/editor/components/Viewport/Content/index.tsx

@@ -95,6 +95,7 @@ export default defineUI({
                         >
                           {children}
                         </Container>
+
                         {/* {store.currStreamCardId && (
                           <StreamCardTransfer
                             key={store.currStreamCardId + streamCardIndex}
@@ -109,6 +110,7 @@ export default defineUI({
                           !state.draging && (
                             <Transfer key={store.currCompId + streamCardIndex} />
                           )} */}
+
                         {!state.draging && <SelectTransfer />}
                       </>
                     );
@@ -125,16 +127,14 @@ export default defineUI({
                   },
                 }}
               </CompUI.Page.Component>
-
             </div>
-            <canvas class={selectCls}  ref={selectCanvasRef} />
-            
+            <canvas class={selectCls} ref={selectCanvasRef} />
           </div>
           <div class={meatureStyle}>
-             <div class="ruler top" id="rulerTop"></div>
-             <div class="ruler left" id="rulerLeft"></div>
-             <div class="ruler right" id="rulerRight"></div>
-             <div class="ruler bottom" id="rulerBottom"></div>
+            <div class="ruler top" id="rulerTop"></div>
+            <div class="ruler left" id="rulerLeft"></div>
+            <div class="ruler right" id="rulerRight"></div>
+            <div class="ruler bottom" id="rulerBottom"></div>
           </div>
         </div>
       );
@@ -166,7 +166,6 @@ const meatureStyle = css`
   z-index: 1001;
   pointer-events: none;
 
-
   .ruler {
     position: absolute;
     cursor: ns-resize;
@@ -198,4 +197,4 @@ const meatureStyle = css`
     width: 10px;
     cursor: ew-resize;
   }
-`
+`;

+ 1 - 2
src/modules/editor/objects/DesignTemp/creates/createCompStyle.ts

@@ -63,8 +63,6 @@ export function createCompStyle(module: EditorModule, layout: Layout) {
   if (layout.transformMatrix) {
     style.transform = layout.transformMatrix;
     style.transformOrigin = "0 0";
-
-    
   } else {
     const v = parseTransform(transform);
     if (v) style.transform = v;
@@ -75,6 +73,7 @@ export function createCompStyle(module: EditorModule, layout: Layout) {
       style.backgroundColor = layout.background.color;
     }
   }
+
   return style;
 }