Creator小小黑板 | 画板功能实现

请添加图片描述
源码在文末

节点层级
在这里插入图片描述
bg是墨绿色的背景
brush是笔刷,上面有Graphics组件
Color是更改画笔颜色的一堆颜色块的父节点
UI_bg下面有显示笔刷颜色的精灵,选择笔刷或橡皮的按钮
BTN_parent子节点有清空画布按钮,调整画笔和橡皮大小的滑动器

有两个脚本
Main脚本负责绘画
UI脚本负责UI相关
在这里插入图片描述
先写Main脚本,撸一个枚举控制笔刷类型

// 笔刷类型 是画笔还是橡皮
export enum Type {
    brush, 
    eraser,
}

Main脚本的属性

	@property(Node)
    canvas: Node = null!;

    @property({displayName: "黑板背景", tooltip: "黑板背景", type: Node})
    bg: Node = null!;


    @property({displayName: "相机", tooltip: "拍UI的相机", type: CameraComponent})
    camera: CameraComponent = null!;


    @property({displayName: "笔刷", tooltip: "笔刷节点", type: GraphicsComponent})
    brush: GraphicsComponent = null!;

    // 类型 默认是画笔
    type = Type.brush;

    // 画笔的颜色和线宽
    brush_color: Color = Color.WHITE;
    brush_width: number = 5;

    // 橡皮的颜色和大小
    eraser_color: Color = null!;
    eraser_width: number = 20;

绘画使用Graphics实现,官方文档提供的接口如下
在这里插入图片描述
先用moveTo移动路径到指定点,再用lineTo添加新点,最后用stroke方法绘制,就可以画出一条线了
举个小例子

	onLoad () {
        this.brush.moveTo(0, 0);
        this.brush.lineTo(200, 0);
        this.brush.stroke();
    }

这就是画完的结果
在这里插入图片描述

了解完了怎么用Graphics画一条线,接下来实现手指滑动绘画

给canvas绑定触摸事件,把触点转到节点坐标系后传入对应的API。最后还要设置橡皮颜色为黑板背景的颜色,橡皮的实现原理就是画和背景颜色(墨绿色)一样的线条出来遮挡住之前画的内容

	onLoad () {
        let self = this;

        // 给canvas绑定开始触摸事件
        this.canvas.on(SystemEventType.TOUCH_START, function (event: EventTouch) {
            let point = self.PointToNode(event.getLocation(), self.camera, self.canvas);
            let x = point.x;
            let y = point.y;

            // 设置路径起点
            self.brush.moveTo(x, y);

        }, this);

        // 给canvas绑定触摸移动事件
        this.canvas.on(SystemEventType.TOUCH_MOVE, function (event: EventTouch) {
            let point = self.PointToNode(event.getLocation(), self.camera, self.canvas);
            let x = point.x;
            let y = point.y;

            // 设置直线路径
            self.brush.lineTo(x, y);
            // 绘制所有路径
            self.brush.stroke();

        }, this);

        // 设置橡皮颜色为黑板背景的颜色
        this.eraser_color = this.bg.getComponent(SpriteComponent)!.color;
    }
	// 通过触摸得到的点转为节点坐标下
    PointToNode (point: Vec2, camera: CameraComponent, node: Node): Vec2 {
        let point_world = camera.screenToWorld(new Vec3(point.x, point.y));
        let point_result = node.getComponent(UITransformComponent)!.convertToNodeSpaceAR(point_world);
        return(new Vec2(point_result.x, point_result.y));
    }

每帧更新笔刷的颜色和粗细

	update () {
        // 如果是画笔
        if (this.type == Type.brush) {
            // 设置颜色和线宽
            this.brush.strokeColor = this.brush_color;
            this.brush.lineWidth = this.brush_width;
        }
        // 如果是橡皮 
        else if (this.type == Type.eraser) {
            // 设置颜色和大小
            this.brush.strokeColor = this.eraser_color;
            this.brush.lineWidth = this.eraser_width;
        }
    }

这就是Main脚本的全部代码了,已经可以画画了,但是不能调节颜色和粗细什么的,这些UI还都是摆设
在这里插入图片描述

接下来写UI代码相关逻辑
创建脚本取名UI

在最上面导入Main脚本

// 导入main脚本
import main, { Type } from "./Main";

声明需要用的属性

	@property({displayName: "笔刷", tooltip: "笔刷", type: GraphicsComponent})
    brush: GraphicsComponent = null!;

    @property({displayName: "当前颜色", tooltip: "当前画笔 / 橡皮的颜色", type: SpriteComponent})
    cur_color: SpriteComponent = null!;

    @property({displayName: "设置画笔颜色块的父节点", tooltip: "设置画笔颜色的颜色块的父节点", type: Node})
    color_parent: Node = null!;

    @property({displayName: "Main脚本所在节点", tooltip: "Main脚本所在节点", type: main})
    main: main = null!;

    @property({displayName: "画笔宽度滑动器", tooltip: "画笔宽度滑动器", type: SliderComponent})
    brush_width_sl: SliderComponent = null!;

    @property({displayName: "橡皮大小滑动器", tooltip: "橡皮大小滑动器", type: SliderComponent})
    eraser_width_sl: SliderComponent = null!;

修改画笔颜色的逻辑
在onLoad给每个设置颜色的颜色块绑定触摸事件,点击颜色块就设置画笔颜色为颜色块的精灵颜色

	onLoad () {
        let self = this;

        // 给每个颜色块绑定事件
        for (let i = 0; i < this.color_parent.children.length; i++) {
            this.color_parent.children[i].on(SystemEventType.TOUCH_START, function () {
                // 设置笔刷颜色
                let color = self.color_parent.children[i].getComponent(SpriteComponent)!.color;
                self.main.brush_color = color;
            }, this);
        }
    }

在这里插入图片描述
每帧更新显示当前颜色块精灵的颜色
根据滑动器设置画笔粗细和橡皮大小
在这里插入图片描述
在这里插入图片描述

	update () {
        // 当前颜色为笔刷颜色
        this.cur_color.color = this.brush.strokeColor;

        // 如果滑动器数值过小就手动设置线宽和大小,如果不就正常设置
        if (this.brush_width_sl.progress <= 0.01 || this.eraser_width_sl.progress <= 0.01) {
            this.main.brush_width = 0.1 * 15;
            this.main.eraser_width = 0.1 * 30;
            return;
        }
        this.main.brush_width = this.brush_width_sl.progress * 15;
        this.main.eraser_width = this.eraser_width_sl.progress * 30;
    }

最后封装三个方法绑定到按钮上

	// 清除所有绘制专用函数
    onbtn_clear () {
        this.brush.clear();
    }

    // 笔刷模式专用函数
    set_brush () {
        this.main.type = Type.brush;
    }

    // 橡皮模式专用函数
    set_eraser () {
        this.main.type = Type.eraser;
    }

在这里插入图片描述

大功告成

源码:https://gitee.com/propertygame/cocos-creator3.x-demos/tree/master/SmallBlackboard
技术交流Q群:1130122408
更多内容请关注微信公众号
请添加图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值