likes
comments
collection
share

Pixijs 教你画出对话框

作者站长头像
站长
· 阅读数 20

前言

在前端需求中,会要实现一些非常规的形状,在 dom 中我们可以使用一些黑科技去实现,那么当整个项目大部分是使用 pixijs 实现的时候,这些形状就要我们手动绘制了

需求

在 pixijs 中实现一个对话框。(pixijs 是一个 canvas 的库)

Pixijs  教你画出对话框

当时一看到这个,我就觉得轻轻松松拿下,但是后来发现没我想的那么简单,如果对实现不感兴趣可以直接跳转到文章最后查看最终代码~

分析

我们如何去画这个弹幕呢?这个弹幕是个非常规图形,我们可以切割点,将其变成一个几个点连接起来的图形

Pixijs  教你画出对话框

按照逆时针旋转,我们切割出 7 个点,两两点直接组合起来就是一个常规的线,大家应该都会画了吧?AB形成的是一个半圆,gf 形成的也是半圆。剩下的都是直线,如何画半圆和直线呢?这里我们用到了arcTo API 和 lineToAPI

实现

我们这里用的是 PIXI.Graphics ,这个是 PIXI 中专门用来画形状的

const graphics = new Graphics()

初始化

我们先画一个黑色的边框,然后把里面填充成白色,初始位置为(0,0)

graphics.lineStyle(1,0x000000,1); 
graphics.beginFill(0xffffff); 
graphics.moveTo(0,0);

画半圆

A点我们定为(0,0),那么到达B点,假设B点是(0,50),如何在 AB 之间画一条半圆呢?

我这里是使用了arcTo去画了两个二分之一的半圆,为什么没有选择 arc 呢,使用arc之后,我发现画出来闭合会有问题。

这里我们以 50 作为半径,代码如下:

// 画 1/2 个半圆 
graphics.arcTo(-50,0,-50,50,50); 
// 再画 1/2 个半圆 
graphics.arcTo(-50, 50 * 2, 0, 50 * 2, 50)

arcTo用法

arcTo接受两个点,一个是切点,一个是第二个点。

切点是A点和第二个点做切点的点(-50,0)

第二个点就是AB中间的终点(-50,50)

Pixijs  教你画出对话框 以此类推,第二个半圆对应的点两个点分别是(-50,100)和(0,100)

Pixijs  教你画出对话框

画直线

lineTo 接受一个终点的坐标点,我们这里是C点,假设BC之前的长度为80,ce之间的距离为20

graphics.lineTo(80, 50 * 2)

以此类推,画cd

graphics.lineTo(80 + 10, 2 * 50 + 10 * 2)

画de

graphics.lineTo(80 + 10 * 2, 50 * 2)

画ef

graphics.lineTo(80 * 2 + 10 * 2, 50 * 2)

画半圆

以此类推,我们再来画fg

graphics.arcTo(80 * 2 + 10 * 2 + 50, 2 * 50, 80 * 2 + 2 * 10 + 50, 50, 50)
graphics.arcTo(80 * 2 + 10 * 2 + 50, 0, 80 * 2 + 2 * 10, 0, 50)

结束

最后,我们回归到原点,结束绘制

graphics.lineTo(0, 0) graphics.endFill()

最终代码

为了保证对话框的大小可以进行调整,我们可以将一些参数抽离出来

const graphics = new Graphics();
const LINEHEIGHT = 80
const  R = 50
const ANGLE_R = 10
graphics.lineStyle(1,0x000000,1);
graphics.beginFill(0xffffff);
graphics.moveTo(0,0);
graphics.arcTo(-R,0,-R,R,R);
graphics.arcTo(-R, R * 2, 0, R * 2, R)
graphics.lineTo(LINEHEIGHT, R * 2)
graphics.lineTo(LINEHEIGHT + ANGLE_R, 2 * R + ANGLE_R * 2)
graphics.lineTo(LINEHEIGHT + ANGLE_R * 2, R * 2)
graphics.lineTo(LINEHEIGHT * 2 + ANGLE_R * 2, R * 2)
graphics.arcTo(LINEHEIGHT * 2 + ANGLE_R * 2 + R, 2 * R, LINEHEIGHT * 2 + 2 * ANGLE_R + R, R, R)
graphics.arcTo(LINEHEIGHT * 2 + ANGLE_R * 2 + R, 0, LINEHEIGHT * 2 + 2 * ANGLE_R, 0, R)

总结

面对一些不规则的图形,我们可以用一些线去把这些图形给画出来

转载自:https://juejin.cn/post/7393311009761181715
评论
请登录