[pixi.js] 入门简单案例 简易时钟

老实说pixi虽然之前拿来做个几个简单的游戏,但是是好久前的了,又忘了,现在算是重新入门。
官网版本已经更新到v8去了,而react相关的pixi库pixi-react 虽然支持react18 但还是v6-v7的版本,既然已经看了v8的文档,那就没必要等pixi-react了,直接照着pixi文档撸吧。

先拉个react的vite脚手架下来(vue react都无所谓,基本上用不到框架或者库的api),在我的理解里,pixi每时每刻都是在内部进行不停的渲染绘制,所以跟react的render无关,同样也不需要vue的响应式视图。基本上如果更改了pixi元素的属性,下一帧就给你绘制出来了。

步入正题

安装pixi.js

pnpm add pixi.js

顺便装个gsap动画库吧

pnpm add gsap

按照官网文档初始化pixi

import { Application, Renderer, Graphics, Container, Point } from "pixi.js";
...
const ctx = useRef<HTMLDivElement | null>(null);

async function init() {
	const app = new Application();
	await app.init({
		background: '#fff',
		width: 400,
		height: 400,
	});
	return Promise.resolve(app);
}

useEffect(() => {
	init().then((app) => {
		// 把pixi挂载到页面上
		ctx.current?.appendChild(app.canvas);
	});
}, [])

return (<div className={clock.container} ref={ctx}></div>)

接下来开始绘制时钟的基本轮廓

function drwaClock(app: Application<Renderer>) {
    const clock = new Container();
    // 秒钟
    const secondContainer = new Container();
    // 分钟
    const minter = new Container();
    // 小时
    const hours = new Container();

    clock.addChild(hours);
    clock.addChild(minter);
    clock.addChild(secondContainer);
    const circle = new Graphics();
    circle
      .circle(app.screen.width / 2, app.screen.height / 2, 100)
      .fill("#33333350")
      .stroke({ width: 10, color: "#FFD5AE" });
    clock.addChild(circle);
    const second = new Graphics().rect(0, 0, 3, 100).fill("#000");
    secondContainer.addChild(second);
    // 设置矩形的旋转点为其宽度中心点和高度的85%
    second.pivot.set(1.5, 85);
    // 为围绕重点渲染 需要改变矩形的位置便于旋转效果
    second.position.set(app.screen.width / 2 + 1.5, app.screen.height / 2);
    // second.rotation = 6 * (Math.PI / 180);
    const positionPiovt = second.toGlobal(new Point(1.5, 85));
    // 矩形的中心点创建一个圆
    const pivotCircle = new Graphics().circle(0, 0, 4).fill("#FFD5AE").stroke({ width: 2, color: "#000" });
    pivotCircle.position.set(positionPiovt.x, positionPiovt.y);
    secondContainer.addChild(pivotCircle);
    // 添加分钟指针
    const min = new Graphics().rect(0, 0, 4, 80).fill("#333");
    min.pivot.set(2, 65);
    min.position.set(app.screen.width / 2 + 2, app.screen.height / 2);
    minter.addChild(min);

    // 添加时钟指针
    const hour = new Graphics().rect(0, 0, 4, 60).fill("#111");
    hour.pivot.set(2, 45);
    hour.position.set(app.screen.width / 2 + 2, app.screen.height / 2);
    hours.addChild(hour);

    const date = new Date();
    // 1s是6° 即 6 * (Π/180)
    const seconds = date.getSeconds();
    second.rotation = seconds * 6 * (Math.PI / 180);
    min.rotation = date.getMinutes() * 6 * (Math.PI / 180);
    hour.rotation = date.getHours() * 6 * (Math.PI / 180);
    const calibration = addCalibration(app);
    clock.addChild(calibration);

    app.stage.addChild(clock);
    app.ticker.add((delte) => {
      second.rotation += 6 * (Math.PI / 180) * (delte.deltaTime / 60);
      if (second.rotation >= Math.PI * 2) {
        second.rotation %= Math.PI * 2;
        gsap.to(min, {
          rotation: `+= ${6 * (Math.PI / 180)}`,
        });
      }
      if (min.rotation >= Math.PI * 2) {
        min.rotation %= Math.PI * 2;
        gsap.to(hour, {
          rotation: `+= ${6 * (Math.PI / 180)}`,
        });
      }
      if (hour.rotation >= Math.PI * 2) {
        hour.rotation %= Math.PI * 2;
      }
    });
  }

这里添加了时钟分钟和秒钟以及时钟的边框,在ticker里每秒钟转动6°,超过360°时重新开始计算,并设置分钟转动6°;

下面添加时钟的刻度addCalibration

// 刻度
  function addCalibration(app: Application<Renderer>) {
    const calibration = new Container();
    const zero = new Graphics().rect(0, 0, 4, 12).fill("#000");
    zero.position.set(app.screen.width / 2, app.screen.height / 2 - 105);
    calibration.addChild(zero);

    const three = new Graphics().rect(0, 0, 4, 12).fill("#000");
    three.rotation = Math.PI / 2;
    three.position.set(app.screen.width / 2 + 105, app.screen.height / 2);
    calibration.addChild(three);

    const six = new Graphics().rect(0, 0, 4, 12).fill("#000");
    six.pivot.set(2, 12);
    six.position.set(app.screen.width / 2, app.screen.height / 2 + 105);
    calibration.addChild(six);

    const nine = new Graphics().rect(0, 0, 4, 12).fill("#000");
    nine.rotation = Math.PI / 2;
    nine.pivot.set(2, 12);
    nine.position.set(app.screen.width / 2 - 105, app.screen.height / 2);
    calibration.addChild(nine);

    return calibration;
  }

时间关系 就不把剩下的刻度标出来了,最终效果为
在这里插入图片描述

相关推荐

  1. 反射应用简单案例

    2024-06-07 17:06:04       28 阅读
  2. Cesium简单案例

    2024-06-07 17:06:04       29 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-07 17:06:04       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-07 17:06:04       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-07 17:06:04       87 阅读
  4. Python语言-面向对象

    2024-06-07 17:06:04       96 阅读

热门阅读

  1. 扯什么蛋,c++ 当然就是整个计算机科学

    2024-06-07 17:06:04       28 阅读
  2. Python语言字母:深度解析与魅力探索

    2024-06-07 17:06:04       29 阅读
  3. 小抄 20240607

    2024-06-07 17:06:04       28 阅读
  4. .NET 使用Automapper映射 Record类型

    2024-06-07 17:06:04       26 阅读
  5. 每天一个数据分析题(三百四十七)

    2024-06-07 17:06:04       25 阅读
  6. C#实现定时执行+线程

    2024-06-07 17:06:04       24 阅读
  7. SP16139 CODCHESS - Naya Shatranj (New Chess) 题解

    2024-06-07 17:06:04       30 阅读
  8. Spring Boot 使用 AES 加密详解

    2024-06-07 17:06:04       31 阅读
  9. 数据结构--查找的基本概念

    2024-06-07 17:06:04       35 阅读
  10. 在 DE2-115 开发板上使用 Chisel 编写流水灯程序

    2024-06-07 17:06:04       31 阅读
  11. 如何评价GPT-4o?

    2024-06-07 17:06:04       30 阅读
  12. 栈 数组和链表实现

    2024-06-07 17:06:04       31 阅读