IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 三月,和她一起看一次樱花吧(vue实现樱花漫天效果) -> 正文阅读

[JavaScript知识库]三月,和她一起看一次樱花吧(vue实现樱花漫天效果)

1 前言

去年三月

她的长发在风中随樱花起舞

难以忘怀的不止是樱花
更是她的笑靥

此时此刻

恰如彼时彼刻;

希望各位能与命中注定的他或她,在樱花雨中来一场邂逅;

2 樱花雨实现

2.1 环境

  • 开发工具:vscode;

  • 开发框架:vue;

  • 语言:JavaScript+html

2.2 效果

效果如图所示:

在这里插入图片描述

2.3 源码与源图

代码如下所示:

sakura.vue:

<template>
  <div id="page">
    <canvas ref="canvas_sakura" id="canvas_sakura" class="bg-sakura"></canvas>
  </div>
</template>
<script>
import { Sakura, SakuraList } from "./sakura.js";

export default {
  data() {
    return {
      sakuraNum: 100, //页面樱花数量 (添加)
      limitTimes: -1, //樱花坠落循环次数
      limitArray: []
    };
  },
  created() {
    this.initParams();
  },
  mounted() {
    // 初始化页面参数与对象
    this.initSakura();
    this.initSakuraList();
    // 页面开始坠落樱花
    this.startSakura();
  },
  methods: {
    // 初始化循环数组
    initParams() {
      for (let index = 0; index < this.sakuraNum; index++) {
        this.limitArray[index] = this.limitTimes;
      }
    },
    initSakura() {
      const img = new Image();
      img.src = require("./imgs/sakura.png"); //图片路径使用require才能获取
      // 绘制樱花
      const _this = this;
      Sakura.prototype.draw = function(cxt) {
        cxt.save();
        const xc = (40 * this.s) / 4;
        cxt.translate(this.x, this.y);
        cxt.rotate(this.r);
        cxt.drawImage(img, 0, 0, 100 * this.s, 100 * this.s); //context.drawImage(img,x,y,width,height);
        cxt.restore();
      };

      // 修改樱花位置,模拟飘落.
      Sakura.prototype.update = function() {
        this.x = this.fn.x(this.x, this.y);
        this.y = this.fn.y(this.y, this.y);
        this.r = this.fn.r(this.r);

        // 如果樱花越界, 重新调整位置
        if (
          this.x > window.innerWidth ||
          this.x < 0 ||
          this.y > window.innerHeight ||
          this.y < 0
        ) {
          // 如果樱花不做限制
          if (_this.limitArray[this.idx] == -1) {
            this.r = _this.getRandom("fnr");
            if (Math.random() > 0.4) {
              this.x = _this.getRandom("x");
              this.y = 0;
              this.s = _this.getRandom("s");
              this.r = _this.getRandom("r");
            } else {
              this.x = window.innerWidth;
              this.y = _this.getRandom("y");
              this.s = _this.getRandom("s");
              this.r = _this.getRandom("r");
            }
          }
          // 否则樱花有限制
          else {
            if (_this.limitArray[this.idx] > 0) {
              this.r = _this.getRandom("fnr");
              if (Math.random() > 0.4) {
                this.x = _this.getRandom("x");
                this.y = 0;
                this.s = _this.getRandom("s");
                this.r = _this.getRandom("r");
              } else {
                this.x = window.innerWidth;
                this.y = _this.getRandom("y");
                this.s = _this.getRandom("s");
                this.r = _this.getRandom("r");
              }
              // 该越界的樱花限制数减一
              _this.limitArray[this.idx]--;
            }
          }
        }
      };
    },
    initSakuraList() {
      SakuraList.prototype.push = function(sakura) {
        this.list.push(sakura);
      };

      // list update 方法
      SakuraList.prototype.update = function() {
        for (let i = 0, len = this.list.length; i < len; i++) {
          this.list[i].update();
        }
      };

      // list draw 方法
      SakuraList.prototype.draw = function(cxt) {
        for (let i = 0, len = this.list.length; i < len; i++) {
          this.list[i].draw(cxt);
        }
      };
      SakuraList.prototype.get = function(i) {
        return this.list[i];
      };
      SakuraList.prototype.size = function() {
        return this.list.length;
      };
    },
    // 位置随机策略
    getRandom(option) {
      let ret, random;
      switch (option) {
        case "x":
          ret = Math.random() * window.innerWidth;
          break;
        case "y":
          ret = Math.random() * window.innerHeight;
          break;
        case "s":
          ret = Math.random();
          break;
        case "r":
          ret = Math.random() * 6;
          break;
        case "fnx":
          random = Math.random() - 0.3;
          ret = function(x, y) {
            return x + 0.5 * random - 1.7;
          };
          break;
        case "fny":
          random = 5 + Math.random() * 0.7;
          ret = function(x, y) {
            return y + random;
          };
          break;
        case "fnr":
          random = Math.random() * 0.03;
          ret = function(r) {
            return r + random;
          };
          break;
      }
      return ret;
    },

    // 樱花入口
    startSakura() {
      const requestAnimationFrame =
        window.requestAnimationFrame ||
        window.mozRequestAnimationFrame ||
        window.webkitRequestAnimationFrame ||
        window.msRequestAnimationFrame ||
        window.oRequestAnimationFrame;
      const canvas = this.$refs.canvas_sakura;
      canvas.height = window.innerHeight;
      canvas.width = window.innerWidth;
      const cxt = canvas.getContext("2d");
      const sakuraList = new SakuraList();
      // sakuraNum 樱花个数
      for (let i = 0; i < this.sakuraNum; i++) {
        const randomX = this.getRandom("x");
        const randomY = this.getRandom("y");
        const randomR = this.getRandom("r");
        const randomS = this.getRandom("s");
        const randomFnx = this.getRandom("fnx"); //x轴移动速度
        const randomFny = this.getRandom("fny"); //y轴移动速度
        const randomFnR = this.getRandom("fnr"); //转动速度
        const sakura = new Sakura(
          randomX,
          randomY,
          randomS,
          randomR,
          {
            x: randomFnx,
            y: randomFny,
            r: randomFnR
          },
          i
        );

        sakura.draw(cxt);

        sakuraList.push(sakura);
      }
      let stop = requestAnimationFrame(function f() {
        // console.log("111");
        cxt.clearRect(0, 0, canvas.width, canvas.height);
        // 修改樱花位置逻辑
        sakuraList.update();
        // 画出修改后的樱花
        sakuraList.draw(cxt);
        // 递归 修改位置, 画出修改后的樱花
        stop = requestAnimationFrame(f);
      });
    }
  }
};
</script>
<style scoped>
.bg-sakura {
  background-image: url("../../../assets/images/sakuraTree01.jpeg");
  background-size: 100%;
}
</style>

sakura.js:

// 定义樱花, idx 是修改添加的
export const Sakura = function(x, y, s, r, fn, idx) {
  this.x = x;
  this.y = y;
  this.s = s;
  this.r = r;
  this.fn = fn;
  this.idx = idx;
};

export const SakuraList = function() {
  this.list = [];
};

代码中用到的源图:樱花漫天特效源图

2.4 踩坑

  1. vue中对象this作用域以及对this重命名;
  2. 画布大小需要进行动态设置;
  3. vue中使用图片对象时,需要使用require读取图片路径才可生效;
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2022-03-16 22:12:45  更:2022-03-16 22:12:48 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:46:23-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码