MyPoems.vue 6.8 KB
<!--
 * 设计1
  -->
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import { useQuasar, copyToClipboard } from 'quasar';
import { useMessage } from 'src/common/hooks';
import { myCloneDeep, getRandomInt, isEmpty } from 'src/common/utils';
import { poems } from '../config';
import { QMediaPlayer } from '@quasar/quasar-ui-qmediaplayer';

const defaultStyle = {
  backgroundImage: 'linear-gradient(to top, #a18cd1 0%, #fbc2eb 100%)',
  color: 'white',
};

const $q = useQuasar();
const { info } = useMessage();

// const textcolor = ref('#ffffff');
// const getTextColor = computed(() => {
//   return {
//     // color: 'inherit',
//     color: textcolor.value,
//   };
// });
const source = ref(require('../media/羽肿-花火が瞬く夜に.mp3'));
const isPlaying = ref(false);
const carouselRef = ref<any>(null);
const slide = ref('100');

onMounted(() => {
  rightClick();
});

function getStyle(data: any) {
  let obj = {} as any;
  if (!isEmpty(data.style)) {
    for (const key in data.style) {
      obj[key] = data.style[key];
    }
  } else {
    obj = myCloneDeep(defaultStyle);
  }
  return obj;
}

function leftClick(data: any) {
  let str = '';
  for (const item of data.content) {
    str += item + '\r\n';
  }
  if (data.author) {
    str += data.author;
  }
  copyToClipboard(str)
    .then(() => {
      info('复制成功');
    })
    .catch(() => {
      // fail
    });
}

function rightClick() {
  const keyList = poems.map((item: any) => item.key);
  const max = keyList.length;

  getValueKey(keyList, max);
}

function getValueKey(keyList: any, max: number) {
  const randomIndex = getRandomInt(0, max);
  const valueKey = keyList[randomIndex];

  if (valueKey === slide.value) {
    getValueKey(keyList, max);
  } else {
    slide.value = valueKey;
  }
}

function toggle() {
  const target = carouselRef.value.$el;
  $q.fullscreen
    .toggle(target)
    .then(() => {
      // success!
    })
    .catch((err) => {
      alert(err);
      // uh, oh, error!!
      // console.error(err)
    });
}

function onPaused() {
  isPlaying.value = false;
}
function onPlaying() {
  isPlaying.value = true;
}
</script>
<template>
  <div class="box container-height">
    <!-- 
      arrows
      navigation
      :autoplay="8000"
     -->
    <q-carousel
      v-model="slide"
      transition-prev="fade"
      transition-next="fade"
      :transition-duration="1500"
      :autoplay="8000"
      animated
      infinite
      height="100%"
      ref="carouselRef"
    >
      <q-carousel-slide
        :name="item.key"
        class="my-carousel-slide"
        v-for="item in poems"
        :key="item.key"
      >
        <div class="content" :style="getStyle(item)">
          <section
            title="鼠标左键复制,右键切换"
            @click="leftClick(item)"
            @contextmenu.prevent="rightClick()"
          >
            <!-- 
              :style="getTextColor"
             -->
            <p v-for="(contentItem, index) in item.content" :key="index">
              {{ contentItem }}
            </p>
            <p class="author" v-if="item.author">
              {{ item.author }}
            </p>
          </section>
        </div>
      </q-carousel-slide>

      <template v-slot:control>
        <q-carousel-control position="top-right" :offset="[18, 18]">
          <q-btn
            round
            flat
            :icon="$q.fullscreen.isActive ? 'fullscreen_exit' : 'fullscreen'"
            :title="$q.fullscreen.isActive ? '退出全屏' : '全屏'"
            @click="toggle"
          />
        </q-carousel-control>

        <!-- 
          style="left: 50%; transform: translateX(-50px); width: 100px"
         -->
        <q-carousel-control
          position="top"
          :offset="[0, 18]"
          style="left: 50%; transform: translateX(-140px); width: 280px"
        >
          <div>
            <!-- 
              autoplay
              width: 100px;
              min-width: 100px !important;
              dense
             -->
            <q-media-player
              class="my-media-player"
              type="audio"
              dense
              loop
              hide-volume-btn
              no-video
              :source="source"
              style="
                border-radius: 20px;
                width: 280px;
                min-width: 280px !important;
                --mediaplayer-background: #dfdbca;
                --mediaplayer-background-dark: #dfdbca;
                --mediaplayer-color: #306e8a;
                --mediaplayer-color-dark: #306e8a;
              "
              @paused="onPaused"
              @playing="onPlaying"
            >
              <template #play>
                <q-btn
                  round
                  flat
                  :icon="
                    isPlaying
                      ? 'fa-solid fa-compact-disc'
                      : 'bi-play-circle-fill'
                  "
                  :class="{ 'rotate-animate': isPlaying }"
                  style="
                    font-size: 1rem;
                    padding: 4px;
                    min-width: 40px;
                    max-width: 40px;
                    min-height: 40px;
                    max-height: 40px;
                  "
                />
              </template>

              <!-- <template #positionSlider> </template> -->
              <!-- <template #durationTime></template> -->
            </q-media-player>
          </div>
        </q-carousel-control>
      </template>
    </q-carousel>
  </div>
  <!-- <div class="text z-top">
    <q-input filled v-model="textcolor" class="my-input">
      <template v-slot:append>
        <q-icon name="colorize" class="cursor-pointer">
          <q-popup-proxy cover transition-show="scale" transition-hide="scale">
            <q-color v-model="textcolor" />
          </q-popup-proxy>
        </q-icon>
      </template>
    </q-input>
  </div> -->
</template>

<style lang="scss" scoped>
// .text {
//   position: fixed;
//   top: 10px;
//   left: 10px;
//   box-sizing: border-box;
// }
@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.box {
  box-sizing: border-box;
  overflow: hidden;
}
.my-carousel-slide {
  padding: 0;
}
.content {
  box-sizing: border-box;
  height: 100%;
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  font-family: '华文中宋', '新宋体', '楷体';
  p {
    font-size: 24px;
  }
  .author {
    font-size: 15px;
    text-align: right;
  }
}

.rotate-animate {
  animation: rotate 3s linear infinite;
}
:deep(.my-media-player
    .q-media__controls
    .q-slider
    .q-slider__track-container
    .q-slider__track) {
  color: #306e8a;
}
:deep(.my-media-player
    .q-media__controls
    .q-slider
    .q-slider__track-container
    .q-slider__track
    .q-slider__thumb) {
  color: #306e8a;
}
</style>