vue3 composition-api实现波纹涟漪

有时候,不是因为你没有能力,也不是因为你缺少勇气,只是因为你付出的努力还太少,所以,成功便不会走向你。而你所需要做的,就是坚定你的梦想,你的目标,你的未来,然后以不达目的誓不罢休的那股劲,去付出你的努力,成功就会慢慢向你靠近。

导读:本篇文章讲解 vue3 composition-api实现波纹涟漪,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

接着上一章的制作锦鲤。现在我们要实现水中涟漪。首先我们先创建一个波纹组件。

vue3 composition-api实现波纹涟漪

波纹组件Wave

<template>
  <!-- 显示波纹的组件 -->
  <div
      class="WaveRoot"
      :style="{
      left: `${x - 50}px`,
      top: `${y - 50}px`,
    }"
  />
</template>

<script lang="ts">
import { defineComponent, onMounted } from "vue";
export default defineComponent({
  name: "Wave",
  // x、y 波纹的位置
  props: {
    x: { type: Number, default: 0 },
    y: { type: Number, default: 0 },
  },
  setup(_, ctx) {
    onMounted(() => {
      window.setTimeout(() => {
        ctx.emit("end");
      }, 6000);
    });
  },
});
</script>

<style lang="scss" scoped>
.WaveRoot {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 100px;
  border: 1.8px solid currentColor;
  border-radius: 100%;
  pointer-events: none;
  animation: appear 5s both;
  &::before {
    content: "";
    position: absolute;
    width: 80%;
    height: 80%;
    left: calc(10% - 1px);
    top: calc(10% - 1px);
    border: 1.4px solid currentColor;
    border-radius: 100%;
  }
  &::after {
    content: "";
    position: absolute;
    width: 60%;
    height: 60%;
    left: calc(20% - 1px);
    top: calc(20% - 1px);
    border: 1.2px solid currentColor;
    border-radius: 100%;
  }
}
@keyframes appear {
  0% {
    transform: scale(0);
    opacity: 0;
  }
  10% {
    transform: scale(0.1);
    opacity: 0.3;
  }
  100% {
    transform: scale(2.5);
    opacity: 0;
  }
}
</style>

创建一个多波纹排序的组件waveLayer

组件用来管理波纹和显示涟漪的层

<template>
  <div class="WaveLayerRoot">
    <Wave
        v-for="waveProps in stageState.waveList"
        class="WaveElement"
        :key="waveProps.id"
        :x="waveProps.position.x"
        :y="waveProps.position.y"
        @end="removeWave(waveProps)"
    />
  </div>
</template>

<script lang="ts">
import { defineComponent, reactive} from "vue";
import Wave from "./Wave.vue";
import { Point } from "../core/Point";
import { useMouse } from "../core/useMouse";
import { useClick } from "../core/useClick";
import { useTicker } from "../core/useTicker";
import { WaveModel } from "../core/WaveModel";
/**
 * 波纹状态管理
 */
type LayerState = {
  waveList: WaveModel[];
};
export default defineComponent({
  name: "WaveLayer",
  components: { Wave },
  setup(_, ctx) {
    // 状态
    const stageState = reactive<LayerState>({
      waveList: [],
    });
    // 位置
    const { mousePos: destination } = useMouse();
    // 添加波纹
    const addWave = (x: number, y: number) => {
      const RND = 100;
      const rndX = (Math.random() - 0.5) * RND;
      const rndY = (Math.random() - 0.5) * RND;
      stageState.waveList.push(new WaveModel(new Point(x + rndX, y + rndY)));
    };
    // 移除波纹
    const removeWave = (wave: WaveModel) => {
      stageState.waveList = stageState.waveList.filter((w) => w !== wave);
    };
    
    // 定时增加涟漪,跟背景石头一样
    useTicker(() => {
      if (Math.random() < 0.93) {
        return;
      }
      addWave(destination.x, destination.y);
    }, 100);

    useClick(() => {
      addWave(destination.x, destination.y);
    });
    return {
      stageState,
      addWave,
      removeWave,
    };
  },
});
</script>

<style scoped lang="scss">
.WaveLayerRoot {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  .WaveElement {
    color: rgb(129, 170, 189);
  }
}
</style>

创建一个WaveModel用来管理涟漪位置和数量

import { Point } from "./Point";

let instanseCount = 0;

export class WaveModel {
    readonly id = instanseCount++;
    readonly position: Point;

    constructor(p: Point) {
        this.position = p;
    }
}

使用

<template>
  <!--合成背景、锦鲤和涟漪-->
  <stage-bg class="StageRoot" >
    <FishLayer :maxFish="maxFish" @count-changed="fishCountChanged" />
    <wave-layer />
  </stage-bg>

</template>

<script lang="ts">
import FishLayer from "./FishLayer.vue";
import {defineComponent} from "vue";
import StageBg from "./stageBg.vue";
import WaveLayer from "./waveLayer.vue";
export default defineComponent({
  name: "stageFish",
  components: {WaveLayer, StageBg, FishLayer},
  props: {
    maxFish: { type: Number, default: 50 },
  },
  setup(props,ctx) {
    console.log('33333',props.maxFish)
    //锦鲤数量变化时的事件
    const fishCountChanged = (count: number) => {
      ctx.emit('count-changed', count);
    }
    return {
      fishCountChanged
    }
  }
})
</script>

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/144772.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!