Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

canvas:摸得着的动画 #3

Open
dk-plus opened this issue Apr 23, 2022 · 0 comments
Open

canvas:摸得着的动画 #3

dk-plus opened this issue Apr 23, 2022 · 0 comments

Comments

@dk-plus
Copy link
Owner

dk-plus commented Apr 23, 2022

你在凝望深渊的时候,深渊也在凝望你。——Who(你猜

这也是交互吗?

什么叫交互

看电影是交互吗?不是,你的行为影响不了画面(你把屏幕砸坏的行为除外

玩游戏是交互吗?是的,你能控制游戏角色的行为。

你的行为,比如移动鼠标、敲下键盘、在摄像头前摇摇头、喊一声Siri,通过输入设备能对画面产生变化的,就叫交互。

事件与监听

你的特定行为能被电脑感知,是因为触发(emit)了特定事件,同时电脑有监听(on)这一事件,并执行针对这一事件发生后的对应操作(callback)。

你移动鼠标,画面就会有个鼠标跟着你的行为移动;

你点击图标,画面上的图标就会是选中状态;

你拿着鼠标抠脚,画面根本不会有什么反应,因为它没有监听你用鼠标抠脚这种事件。

虽然我举的这个例子很荒谬,但你不能否认只要有对应的输入设备,就能监听到这种行为,就像《国产凌凌漆》所说的那样。

image-20220423142631787

鼠标事件获取交互数据

我们拿鼠标事件举例,简单讲讲鼠标与屏幕的交互。

鼠标事件的目的大多数是根据事件类型(按下、松开、移动)获取所在的位置(x,y)。

mousedown
mouseup
mouseenter
mouseleave
mouseout
mouseover
...

试下在任意一个网页的控制台输入并运行window.onmousedown = console.log,再点击网页的任意位置,就会输出以下信息:

我截取了部分即便是非程序员也多少能看得懂的属性

altKey: true // 是否同时按下alt键
button: 0 // 左键、滚轮键or右键
ctrlKey: false // 是否同时按下ctrl键
shiftKey: false // 是否同时按下shift键
x: 852
y: 180
  1. x、y就是鼠标位置,用于判断点是否在形状之内,比如有没有选中图标
  2. button就是按键类型,玩CS的右键瞄准、左键攻击
  3. 点鼠标的时候同时点击ctrl能选中多个文件

除了鼠标事件以外,还有其他输入设备产生交互的事件,比如键盘(keydown、keyup)、触控屏(touchstart、touchend),这些事件存在的意义就是让我们了解用户交互行为的详细信息,然后写一些对应的操作,比如动画。

交互对数据的影响

如果数据也符合牛顿第一定律,那么数据一开始是静止的,它发生变化一定是受到了外力的作用,这个外力就是交互。

image-20220423220851685

交互会触发事件,事件记录当时的交互数据,交互数据和其他数据之间会有运算。

  1. 移动鼠标,鼠标的位置(x,y)必然变化,属于交互数据的变化
  2. 画面有一个按钮,属于其他数据
  3. 鼠标来到按钮上,两者之间的运算得出一个结果:isIntersected: true,这就是交互对数据的影响

你喜欢怎么表达这个运算结果都可以,温柔点,你可以让按钮变色;粗暴点,你可以让它爆炸。

image-20220423220700393

数据的变化引起的动画

画面的本质是数据,数据发生变化,画面随之变化。

我们遵循以下规则:

  1. 交互->数据,通过交互改变数据
  2. 数据->绘制,根据当前的数据绘制画面

也就是说,交互不直接调用绘制函数,第1条是本篇文章的核心,第2条是上一篇的核心,数据静止就是静态画面,数据变化就变成了动画。

实践

上一篇,我们写了一个简单的二维运动,我们在这个二维运动的基础上加入鼠标交互:圆心在鼠标方圆五百里内(换算一下就是100px,当然这是我瞎扯的)的粒子变大

获取交互数据

这里的交互数据是鼠标位置,设一个全局变量mouse

const mouse = {
	x: 0;
	y: 0;
}

监听鼠标移动事件,移动时更新mouse

window.addEventListener('mousemove', (e) => {
  mouse.x = e.x;
  mouse.y = e.y;
});

通过交互更新数据

沿用上一篇文章的结构,粒子类有个update函数,在这里更新交互带来的数据影响。

在此增加minRmaxR作为粒子变大变小的极值。

class Particle {
	...
  update() {
  	...
  	// 勾股定理,两点距离<100,粒子变大,否则变小
    if (Math.sqrt((mouse.x - this.x) ** 2 + (mouse.y - this.y) ** 2) <= 100) {
      if (this.r < this.maxR) {
        this.r += 1;
      }
    } else if (this.r > this.minR) {
      this.r -= 1;
    }

    this.x += this.dx;
    this.y += this.dy;
    this.draw();
  }
}

效果如下:

1

如果你觉得这个不是很有趣,不妨看看下面这个效果:

  1. 鼠标松开的时候做抛体运动
  2. 鼠标按下的时候做向心加速运动

1

可以提前思考一下这个效果怎么实现,如无意外,后两篇就是介绍向量和力的可视化了。

つづく

本文简单贴了几张周星驰电影的截图介绍并实现了交互事件在canvas中的运用,喜欢的朋友可以点个赞,也欢迎大家关注dkplus公众号,没东西写的时候说不定就开始画画了。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant