鼠标移动淡入淡出Canvas小球效果_TS版本

简介: 使用TypeScript重新实现鼠标移动产生淡入淡出Canvas小球效果。涉及到TS的数据类型、泛型定义、函数与接口定义、类的实现及作为接口的使用,以及枚举类型。通过定义Ball类实现小球的属性和行为,使用事件监听鼠标移动并创建小球实例,然后使用requestAnimationFrame实现动画效果。

最近在学习TS,所以将去年写的鼠标移动淡入淡出Canvas小球效果_特炫又以ts的形式再重新写一遍,让自己记得更牢固。
在这里插入图片描述

从下面的小案例中可以学到

1.ts中的数据类型
2.泛型的定义
3.函数的定义
4.接口的定义
5.类的定义、类实现接口
6.类作为接口的使用
7.枚举以及枚举的特点

按照代码的顺序展开介绍:

首先我们需要准备一个html,我们引入一个js文件(这个js文件为ts文件转义之后的)。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>小球淡入淡出TS</title>
    <style>
        html,
        body {
    
            width: 100%;
            height: 100%;
        }
        canvas{
    
                background: black;
            }
       </style>
</head>
<body>
   <canvas id="canvas" width="100%" height="100%"></canvas>
   <script src="./ts1.js"></script>
</body>

上面主要做的是引入js,创建一个canvas元素,给定宽高和默认的背景颜色。

下面我们开始书写ts文件:

1.获取元素:
/**
 * ts实现 小球单独淡出
 */

// 获取canvas标签
let canvas: HTMLCanvasElement = <HTMLCanvasElement>(
  document.getElementById("canvas")
);
window.onresize = canvasOnresize;
//页面大小改变 canvans大小改变
function canvasOnresize(): void {
   
  canvas.width = document.getElementsByTagName("body")[0].clientWidth;
  canvas.height = document.getElementsByTagName("body")[0].clientHeight;
}
//初始化canvas的高度 宽度 跟随页面的大小
canvasOnresize();

上面做的就是初始化操作,获取元素,将onresize事件重新,为了canvas大小可以随浏览器client大小不断变化。

2.创建小球的类:
//初始化画笔
let ctx = canvas.getContext("2d");
//颜色数组
enum colorList {
   
  "red"=2,
  "green",
  "yellow",
  "blue",
  "black",
  "#ccc"
}
interface BallInterFace {
   
  x: number; //横轴坐标
  y: number; //纵轴坐标
  color: string; //随机生成颜色
  xv: number; //x轴的分散速度
  yv: number; //y轴的分散速度
  Alpha1: number; //开始透明度
  Alpha2: number; //结束透明度
  update: () => void;
  move: () => void;
  mathRandom: (a: number, b: number) => void;
}
class Ball implements BallInterFace {
   
  x: number; //横轴坐标
  y: number; //纵轴坐标
  color: string; //随机生成颜色
  xv: number; //x轴的分散速度
  yv: number; //y轴的分散速度
  Alpha1: number; //开始透明度
  Alpha2: number; //结束透明度
  constructor(x: number, y: number) {
   
    this.x = x;
    this.y = y;
    this.color = colorList[Math.floor(this.mathRandom(2, 8))];
    this.xv = this.mathRandom(-5, 5);
    this.yv = this.mathRandom(-5, 5);
    this.Alpha1 = 1;
    this.Alpha2 = 0.85;
  }
  //生成小球
  update = function(): void {
   
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.x, this.y, 30, 0, Math.PI * 2, false);
    ctx.fill();
    ctx.closePath();
  };
  //小球移动
  move = function(): void {
   
    this.Alpha1 *= this.Alpha2;
    ctx.globalAlpha = this.Alpha1;
    this.x += this.xv;
    this.y += this.yv;
  };
  //随机生成 随机数
  mathRandom = function(min: number, max: number): number {
   
    return (max - min) * Math.random() + min;
  };
}

😊上面使用到了枚举 enum,用来获取小球的颜色。
枚举可以参考这篇文章:typeScript进阶(12)_枚举类型
🤔上面使用到了接口,来定义类的形状。
可以参考这两篇文章:typeScript基础(5)_对象的类型-interfaces接口typeScript进阶(13)_类与注意事项(八项特性)

3.事件动画:
//装Ball对象的数组
let ballList: Array<Ball> = [];
// canvas  2  鼠标移动
canvas.addEventListener("mousemove", function(e) {
   
  ballList.push(new Ball(e.clientX, e.clientY));
});
//1  触发事件
changeBall();
function changeBall(): void {
   
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // 最多共存100个小球
  if (ballList.length > 100) {
   
    ballList.splice(1);
  }
  //循环Ball实例上方法
  ballList.map(item => {
   
    item.update();
    item.move();
  });
  //按照电脑最优状态执行定动画效果
  requestAnimationFrame(changeBall);
}

上面主要做的事情是:
将鼠标移动的点位收集,并创建Ball实例,定时移动位置。

🤣上面使用到泛型:let ballList: Array<Ball> = [];
这里将Ball作为了一种类型;是ts中类的一种特性。
泛型可以参考这篇文章:typeScript进阶(14)_泛型和注意事项

总体思路就是:

1.获取canvas元素;
2.使用canvas画笔实现生成小球的方法;
3.将小球的属性和方法在类中定义好;
4.通过鼠标移动事件捕捉实践对象中的鼠标坐标;
5.鼠标坐标作为每一个新生成小球的坐标,然后随机向各个方向不同速度移动,由x方向和y方向的数值控制,随后改变的就是透明度;
6.使用window自带的动画方法进行循环函数。控制小球数量,不然多的话会造成页面卡顿。
😃上面的Ball类,我们也可以通过抽象类中的抽象方法来约束这个类,而不是直接使用interFace接口,
因为抽象类中的抽象方法在派生类中是必须实现的
到此就实现了上面的动画效果。

ts部分全部代码
/*
 * @Descripttion:
 * @version:
 * @Author: ZhangJunQing
 * @Date: 2022-03-08 14:54:03
 * @LastEditors: ZhangJunQing
 * @LastEditTime: 2022-04-08 15:33:16
 */

/**
 * ts实现 小球单独淡出
 */

// 获取canvas标签
let canvas: HTMLCanvasElement = <HTMLCanvasElement>(
  document.getElementById("canvas")
);
window.onresize = canvasOnresize;
//页面大小改变 canvans大小改变
function canvasOnresize(): void {
   
  canvas.width = document.getElementsByTagName("body")[0].clientWidth;
  canvas.height = document.getElementsByTagName("body")[0].clientHeight;
}
//初始化canvas的高度 宽度 跟随页面的大小
canvasOnresize();
//生成小圆
//初始化画笔
let ctx = canvas.getContext("2d");
//颜色数组
enum colorList {
   
  "red"=2,
  "green",
  "yellow",
  "blue",
  "black",
  "#ccc"
}
interface BallInterFace {
   
  x: number; //横轴坐标
  y: number; //纵轴坐标
  color: string; //随机生成颜色
  xv: number; //x轴的分散速度
  yv: number; //y轴的分散速度
  Alpha1: number; //开始透明度
  Alpha2: number; //结束透明度
  update: () => void;
  move: () => void;
  mathRandom: (a: number, b: number) => void;
}
class Ball implements BallInterFace {
   
  x: number; //横轴坐标
  y: number; //纵轴坐标
  color: string; //随机生成颜色
  xv: number; //x轴的分散速度
  yv: number; //y轴的分散速度
  Alpha1: number; //开始透明度
  Alpha2: number; //结束透明度
  constructor(x: number, y: number) {
   
    this.x = x;
    this.y = y;
    this.color = colorList[Math.floor(this.mathRandom(2, 8))];
    this.xv = this.mathRandom(-5, 5);
    this.yv = this.mathRandom(-5, 5);
    this.Alpha1 = 1;
    this.Alpha2 = 0.85;
  }
  //生成小球
  update = function(): void {
   
    ctx.save();
    ctx.beginPath();
    ctx.fillStyle = this.color;
    ctx.arc(this.x, this.y, 30, 0, Math.PI * 2, false);
    ctx.fill();
    ctx.closePath();
  };
  //小球移动
  move = function(): void {
   
    this.Alpha1 *= this.Alpha2;
    ctx.globalAlpha = this.Alpha1;
    this.x += this.xv;
    this.y += this.yv;
  };
  //随机生成 随机数
  mathRandom = function(min: number, max: number): number {
   
    return (max - min) * Math.random() + min;
  };
}

//装Ball对象的数组
let ballList: Array<Ball> = [];
// canvas  2  鼠标移动
canvas.addEventListener("mousemove", function(e) {
   
  ballList.push(new Ball(e.clientX, e.clientY));
});
//1  触发事件
changeBall();
function changeBall(): void {
   
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  // 最多共存100个小球
  if (ballList.length > 100) {
   
    ballList.splice(1);
  }
  //循环Ball实例上方法
  ballList.map(item => {
   
    item.update();
    item.move();
  });
  //按照电脑最优状态执行定动画效果
  requestAnimationFrame(changeBall);
}

六卿

见贤思齐焉,见不贤内自省

个人见解,不对之处还请斧正。

目录
相关文章
|
2月前
|
前端开发 JavaScript
鼠标移动淡入淡出Canvas小球效果_特炫
本文通过HTML和JavaScript代码示例展示了如何实现鼠标移动时在Canvas上生成彩色小球并具有淡入淡出效果的动画,涉及Canvas的尺寸调整、小球对象的创建、颜色随机化、透明度变化和动画循环渲染等技术点。
34 1
鼠标移动淡入淡出Canvas小球效果_特炫
|
1月前
|
前端开发
ThreeJs通过canvas和Sprite添加标签
这篇文章介绍了在Three.js中利用Canvas和Sprite实现动态文本标签的方法,使得标签可以跟随模型并在3D空间中始终保持面向摄像机。
47 0
ThreeJs通过canvas和Sprite添加标签
|
4月前
|
前端开发
如何在页面中画一个canvas,然后在居中位置写上蓝色‘Hello Canvas‘,并加上文字描边 * @type {HTMLElement}
如何在页面中画一个canvas,然后在居中位置写上蓝色‘Hello Canvas‘,并加上文字描边 * @type {HTMLElement}
|
4月前
|
移动开发 前端开发 HTML5
Canvas画布之100个小球弹射源码
Canvas画布之100个小球弹射源码
|
6月前
transform实现按钮边框旋转效果
transform实现按钮边框旋转效果
|
前端开发
CSS transform实现按钮边框旋转效果
CSS transform实现按钮边框旋转效果
131 1
|
前端开发
【CSS动画02--卡片旋转3D】
【CSS动画02--卡片旋转3D】
|
图形学
Unity【DoTween】- 如何使Transform Tween动画序列可编辑
Unity【DoTween】- 如何使Transform Tween动画序列可编辑
493 0
Unity【DoTween】- 如何使Transform Tween动画序列可编辑
Qt-QML-给我的导航条写一个动画-State-Transition
上篇中,我已经写出一个导航条的,虽然太丑了,不过功能是有了,这次我将要给我的导航条加一个动画,先看下演示效果
178 0
Qt-QML-给我的导航条写一个动画-State-Transition