Graphics 与 DisplayObject 的关系
在原生 Canvas 中,其实并没有 DisplayObject 的概念,它只有绘制图像的概念。
大部分的原生绘制图形或图像的 API 一般是这样的:
api(x, y, ...)
例如 rect 就是:ctx.rect(x, y, width, height)。
这类绘制 API 大部分被封装在 CreateJS 的 Graphics 类中,它们有一个共同的特点 ---- 名字都是以 draw 开始,例如:drawRect / drawCircle 。
为什么说是大部分绘制的API被封装在 Grahpics 类中呢?
很简单,Graphics 类处理的是图形绘制,所以也可以说所有的图形绘制 API 被封装在 Graphics 类中。绘制API还有另一个功能 ------ 绘制图像,这个功能被封装在 Bitmap 类中。
我曾经这样觉得:「graphics.draw*(x, y, ...) 的参数 <x, y> 就是 displayObject 的属性 x, y」。但是其实这个想法很容易 就可以验证得到它的错误性:
var rect = new createjs.Shape();
rect.graphics.drawRect(50, 50, 100 100);
stage.addChild(rect);
console.log(rect.x, rect.y);
Graphics 的工作原理
来分析 Graphics 的 drawRect API 源码:
https://www.createjs.com/docs...
https://www.createjs.com/docs...
https://www.createjs.com/docs...
https://www.createjs.com/docs...
代码很简单,如下:
创建一个「Rect 实例」;
「Rect 构造函数」将
drawRect的实现代码挂载在prototype.exec下将「Rect 实例」append 到数组
_activeInstructions中(第四张截图);返回「Graphics」实例
为什么需要一个数组(_activeInstructions)来存储原生指令?
对于矩形、圆形和圆角矩形来说,确实不需要数组来存储指令;但是梯形、三角形等图形没有对应的原生API,此时需要使用绘制线段或孤线(ctx.moveTo/ctx.lineTo/ctx.arc)来组合产生,而数组 _activeInstructions 就是来处理组合图形产生的。
Rect实例有什么作用?
Rect实例是 drawRect 返回的实例,Graphics 里还有其它的 draw* API,它们会返回各自图形的实例,所以可以把 Rect实例和其它实例统称为「基础图形实例」。「基础图形实例」的作用是提供一个修改图形接口。通过第四张截图,可以看到「基础图形实例」最终被挂载在「Graphics 实例」的 command 属性下,也就是说通过「Graphics实例」的 command 可以访问到最新的「基础图形实例」,写一个测试代码如下:
var gcircle = circle.graphics.beginFill("00ff00").drawCircle(0, 0, 10);
circle.x = circle.y = 100;
stage.addChild(circle);
stage.update();
setTimeout(function() {
gcircle.command.radius = 50;
stage.update();
}, 1000);
这个特性在动态绘制图形上是很有用的,不过,它有一个短板:通过 command 属性只能访问到最近的「基础图形实例」。也就是说自定义的组合图形,如果需要访问到对应的「基础图形实例」就需要把绘制过程拆散,举个例子:
// 三角形
var threeangle = new createjs.Shape();
threeangle.graphics.beginFill("00ff00").moveTo(50, 0).lineTo(0, 50).lineTo(100, 50).closePath();
stage.addChild(threeangle);
stage.update();
如果底部两个端点要做动画:
// 三角形
var threeangle = new createjs.Shape();
threeangle.graphics.beginFill("00ff00").moveTo(50, 0);
var p1 = threeangle.graphics.lineTo(0, 50).command;
var p2 = threeangle.graphics.lineTo(100, 50).command;
threeangle.graphics.closePath();
stage.addChild(threeangle);
stage.update();
setTimeout(function() {
p1.y = 100;
stage.update();
}, 1000);
setTimeout(function() {
p2.y = 200;
stage.update();
}, 2000);
Shape 的工作原理
https://www.createjs.com/docs...
Shape 极简单,就是生成一个 DisplayObject 实例,然后在这个实例中挂载一个 Graphics 实例。而它的工作原理(即它的渲染)如下:
https://www.createjs.com/docs...
也就是 Shape 实例的 draw 方法其实是直接调用 Graphics 实例的 draw 方法。
DisplayObject 的工作原理
DisplayObject 的核心功能是处理 DisplayObject 实例的「矩阵转换」(即位移与形变),如下:
https://www.createjs.com/docs...
我在 聊聊 Container 的实现 中介绍了使用原生 Canvas 实现 Container 的原理。其实,Shape 实例也是一个Container,只是 CreateJS 限制了 shape 只能放 Graphics 实例,而且 shape 只能存放一个 Graphics 实例(即shape 下的 graphics 属性),Graphics 实例下存放多个「基础图形实例」。
**如果从嵌套的维度来说 Graphics 与 DisplayObject 的关系是:
Container > Shape > Graphics > Rect/Circle/RoundRect等基础图形**
其实,CreateJS 完全不需要这么实现。像 PIXI 在实现 Graphics 的时候,Graphics 也一个 Container,它可以像一个正常的 DisplayObject 一样被使用,而不用像 CreateJS 一样麻烦。
Graphics 与 DisplayObject 的关系的更多相关文章
- 聊聊 DisplayObject 的x/y/regX/regY/rotation/scale/skew 属性
首先要指出的是:DisplayObject 实例的属性<x, y> 与 graphics.draw*(x, y, ...) 的参数<x, y>没有关系. 在原生的 Canvas ...
- Chromium网页Graphics Layer Tree创建过程分析
在前面一文中.我们分析了网页Render Layer Tree的创建过程.在创建Render Layer的同一时候,WebKit还会为其创建Graphics Layer.这些Graphics Laye ...
- Objective-C路成魔【11-多态性、动态类型和动态绑定】
郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 多态这个其 ...
- 学习java 7.23
学习内容: 前面讲解了如果构建GUI界面,其实就是把一些GUI的组件,按照一定的布局放入到容器中展示就可以了.在实际开发中,除了主界面,还有一类比较重要的内容就是菜单相关组件,可以通过菜单相关组件很方 ...
- Java-GUI编程之绘图
绘图 很多程序如各种小游戏都需要在窗口中绘制各种图形,除此之外,即使在开发JavaEE项目时,有时候也必须"动态"地向客户 端生成各种图形.图表,比如 图形验证码.统计图等,这都需 ...
- DirectX Graphics Infrastructure(DXGI):最佳范例 学习笔记
今天要学习的这篇文章写的算是比较早的了,大概在DX11时代就写好了,当时龙书11版看得很潦草,并没有注意这篇文章,现在看12,觉得是跳不过去的一篇文章,地址如下: https://msdn.micro ...
- Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译
本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...
- Latex中画出函数文件的调用关系拓扑图
流程图,思维导图,拓扑图通常能把我们遇到的一些复杂的关系结构用图形的方式展现出来.在Latex中要想画这样的拓扑图,有一个很好用的绘图工具包 pgf/tikz . 1.pgf/tikz的安装:pgf/ ...
- 《3D Math Primer for Graphics and Game Development》读书笔记1
<3D Math Primer for Graphics and Game Development>读书笔记1 本文是<3D Math Primer for Graphics and ...
随机推荐
- 华山论剑之 PostgreSQL sequence (一)
前言 本文是 sequence 系列继三大数据库 sequence 之华山论剑 (Oracle PostgreSQL MySQL sequence 十年经验总结) 之后的第二篇,主要分享一下 Post ...
- LeetCode-054-螺旋矩阵
螺旋矩阵 题目描述:给你一个 m 行 n 列的矩阵 matrix ,请按照 顺时针螺旋顺序 ,返回矩阵中的所有元素. 示例说明请见LeetCode官网. 来源:力扣(LeetCode) 链接:http ...
- svelte组件:Svelte3自定义Navbar+Tabbr组件|svelte自定义插件
基于Svelte3自定义组件Navbar+Tabbar沉浸式导航条|底部凸起菜单栏 Svelte 一种全新的构建用户界面的框架.当下热门的 Vue 和 React 在浏览器中需要做大量的工作,而 Sv ...
- laravel resource风格
resource 风格 概念 一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...
- ArcMap操作随记(1)
1.用python代码,将属性表中属性进行合并 代码:'ID'+str(!FID!) 2.地类编码与地类的转换 以python为例 显示代码块(预逻辑脚本代码): def getType(value) ...
- Redis pub/sub
list 类型, lpush + rpop 或 lpush + brpop 用作消息队列时,消息只能消费一次,且不支持多个消费者(消息只能消费一次),并且在客户端崩溃时容易丢失消息.而 pub/sub ...
- Hibernate学习笔记(一)-->数据库单表操作
Hibernate框架是一个全ORM映射框架,是一个非常流行的数据库操作框架之一,现在比较流行的还有MyBatis半ORM映射框架 在MyEclipse IDE开发工具中,可以很轻松的搭建Hibern ...
- HTTP 之 Content-Type
Content-Type,内容类型,一般是指网页中存在的Content-Type,用于定义网络文件的类型和网页的编码,决定文件接收方将以什么形式.什么编码读取这个文件,这就是经常看到一些Asp网页点击 ...
- 为什么不建议使用统配符初始化 css 样式
为什么不建议使用统配符初始化 css 样式 * { padding:0; margin:0; } 采用这样的写法好处是写起来很简单,但是通配符,需要把所有的标签都遍历一遍,当网站较大时,样式比较多,这 ...
- Android BLE 蓝牙开发——扫码枪基于BLESSED
一.蓝牙模式HID与BLE 当扫码枪与手机连接时,通常采用的是蓝牙HID(Human Interface Device)模式.本质上是一个把扫码枪作为一个硬件键盘,按照键盘协议把扫码后的结果逐个输入到 ...