像素是怎样练成的(三)

简介: 像素是怎样练成的(三)

其他语言的处理

其实在浏览器中,一共支持四种语言。

image.png

针对JS的处理,需要用到V8等引擎,WebAssembly也是需要做处理的。因为,篇幅有限,这里就不展开描述了。

针对JS的解析过程,可以参考JS执行流程

关于WebAssembly的介绍,可以参考浏览器第四种语言-WebAssembly


{布局|Layout}阶段生成 {不可变fragment树|immutable fragment tree}

在构建完DOM并计算所有样式后,下一步是确定所有元素的视觉几何属性

对于块级元素,我们需要计算一个矩形的坐标,该矩形对应于元素所占据的内容的几何区域

image.png


块元素 和 内联元素

对于前端页面元素而言,一个元素的类型可以隶属于不同的类型。但是,在比较宏观的角度看,元素是否占一行还是可以和文本信息同行显示。可以把元素分成块元素内联元素

块元素

在最简单的情况下,布局按照DOM的顺序,从上到下,依次放置。我们称之为block flow。(单独占一行)

image.png


内联元素

文本节点和类似<span>的内联元素生成{内联框|inline boxes},通常在一行中从左到右流动

image.png

从右到左的内联流动方向则适用于RTL语言,如阿拉伯语希伯来语

image.png


确定字型的大小和位置

{布局|Layout}需要使用ComputedStyle 对象中的{字体|font}信息来测量文本。 (这里再重申一下,ComputedStyle是CSS被解析后的对象)

image.png

{布局|Layout}使用名为HarfBuzz文本整形库来计算每个字形的大小和位置,从而确定文本段的整体宽度。


矩形边界

{布局|Layout}可能会为单个元素计算多种类型的矩形边界。

例如,在出现溢出情况时,布局会计算{边框框盒|border box rect}{布局溢出框盒|layout overflow rect}

image.png

如果节点的溢出是可滚动的,布局还会计算{滚动边界|scroll boundaries}并保留滚动条的空间。

最常见的可滚动DOM节点是文档本身,它是树的根节点。

布局对象的内容可以超出其{边框框盒|border box rect}

image.png

同时,我们还可以设置如何处理超出部分的行为。

overflow:'auto'|'visible'|'hidden';

(是不是很熟悉)


其他复杂的布局情形

对于表格元素或指定将内容分成多列的样式,或者浮动对象使内容围绕其一侧流动,需要更复杂的布局。

image.png

但是,不管布局如何复杂,在布局阶段,有一个亘古不变的规则就是: DOM结构和计算样式值(ComputedStyle)是{布局|Layout}算法的输入

每个流水线阶段都使用前一个阶段的结果


布局行为不同,有不同的布局对象

{布局|Layout}在与DOM链接的单独树(布局树)上进行操作。(也就是说DOM树Layout树有关联,但是不是一个树)

{布局树|Layout Tree}中的节点实现了布局算法。

根据所需的布局行为,有不同的LayoutObject子类。样式更新阶段也会构建布局树。

布局阶段遍历布局树,对每个LayoutObject执行布局操作。

image.png


DOM 节点和布局对象不是一对一的关系

通常情况下,一个DOM节点对应一个LayoutObject。但有时候,一个LayoutObject没有对应的DOM节点。

甚至有可能一个节点有多个LayoutObject(例如,一个内联元素在块级子元素内,并且内联元素之前和之后都有文本)。可以参考下图中<span>inline</span>的布局对象。

image.png

最后,布局树的构建基于FlatTreeTraversal(FlatTreeTraversal在解析DOM的时候,当存在多个DOM树的时候,出现过哈),可以跨越影子DOM边界。


NG 布局引擎

布局引擎正在进行重写。布局树包含了传统布局对象NG布局对象的混合。最终,所有的布局对象将会是NG布局对象。

image.png

在NG中,布局的输入和输出被清晰地分离开来。输出是一个不可变的、可缓存的布局结果

image.png

{NG布局结果|NGLayoutResult}指向描述物理几何结构的{片段树|Fragments Tree}

image.png


实践验证

存在如下的页面结构。

<div style="max-width: 100px">  
  <div style="float: left; padding: 1ex">F</div>  
  <br>The <b>quick brown</b> fox  
  <div style="margin: -60px 0 0 80px">jumps</div>
</div>

最后的呈现效果。

image.png

生成DOM树


image.png


生成Layout树

{布局对象|Layout Object}大多数情况下与DOM元素一对一对应。

但是,在Layout树中也会存在anonymous布局对象,它是为了使其容器只包含块级子元素而创建的

{布局块|LayoutBlock}可以具有块级子元素或内联子元素,但不能同时具有两者。

虽然,文本"quick brown" 存在断行情况,但是它是存在一个LayoutText节点中。

image.png


生成不可变Fragment树

{片段树|Fragment Tree}中,我们可以看到断行的结果以及每个片段的位置和大小

image.png

片段的断行的结果

image.png

片段位置和大小


image.pngimage.png


{绘制|Paint}阶段生成{显示列表|Display List}

通过上述的数据处理,我们已经获取到{布局对象|Layout Object}的几何属性,接下来我们就需要将其绘制处理了。

{绘制记录|Paint Records}绘制操作记录到{显示项|Display Items} 列表中。

绘制操作可以是诸如"在这些坐标上以这种颜色绘制一个矩形"之类的内容。

对于每个{布局对象|Layout Object}可能会有多个{显示项|Display Items},对应着其不同的视觉呈现部分,如背景、前景、轮廓等等。

image.png


按照层叠顺序进行元素绘制

层叠顺序

这里多啰嗦几句,在CSS重点概念精讲中我们介绍过,关于层叠上下文和层叠顺序,这里我们只是做简单的知识介绍,如果想了解更多,可以参考之前的文章。

{层叠顺序|Stacking Order}表示元素发生层叠时有着特定的垂直显示顺序

一旦普通元素具有层叠上下文,其层叠顺序就会变高

分两种情况

  1. 如果层叠上下文元素不依赖z-index数值,则其层叠顺序是z-index:auto
  • 可看成z-index:0
  1. 如果层叠上下文元素依赖z-index数值,则其层叠顺序由z-index值决定

image.png


按照层叠顺序进行页面绘制

按正确的顺序绘制元素非常重要,这样它们在重叠时才能正确叠放。绘制顺序可以通过样式来控制。

绘制顺序是按照层叠顺序,而不是DOM顺序

image.png

可以看到,虽然yellow的DOM顺序在green的DOM之前,但是在绘制到页面上时,yellowgreen的上面。(yellowZ轴大)


每个绘制过程都是对层叠上下文的单独遍历

甚至有可能一个元素部分在另一个元素前面,部分在后面。这是因为绘制过程分为多个阶段,每个绘制阶段都会对子树单独遍历。

存在如下的页面结构:

<section class="container">
  <div id="green"></div>
  <div id="blue"></div>
</section>

对应的样式如下:

#green {
    position: relative;
    background-color: green;
    height:200px;
    width:300px;
  }
#blue {
    position: absolute;
    top: 20px;
    left: 30px;
    width: 200px; 
    height: 100px; 
    background-color: blue;
    border: 5px solid black;
  }
#green::before {
    content: "绿色元素的文案信息";
    position: absolute;
    top: 20px;
    left: 10px;
    z-index: 2;
    color:white;
    font-weight: 700;
  }

在不考虑,CSS3其他特殊属性的情况下,当元素设置了z-index,就会生成一个层叠上下文,并且每个绘制阶段都是对层叠上下文的单独遍历

image.png


实践验证

存在如下的页面结果。

<style> #p {  
  position: absolute; padding: 2px;  
  width: 50px; height: 20px; 
  left: 25px; top: 25px;  
  border: 4px solid purple;  
  background-color: lightgrey;
} </style>
<div id=p> pixels </div>
呈现的效果如下: image.png
相关文章
|
7月前
|
Serverless C语言 C++
【数学建模】利用C语言来实现 太阳赤纬 太阳高度角 太阳方位角 计算和求解分析 树木树冠阴影面积与种植间距的编程计算分析研究
【数学建模】利用C语言来实现 太阳赤纬 太阳高度角 太阳方位角 计算和求解分析 树木树冠阴影面积与种植间距的编程计算分析研究
111 1
|
5月前
|
Web App开发 存储 前端开发
像素是怎样练成的(一)
像素是怎样练成的(一)
|
5月前
|
存储 Web App开发 缓存
像素是怎样练成的(四)
像素是怎样练成的(四)
|
5月前
|
Web App开发 XML JavaScript
像素是怎样练成的(二)
像素是怎样练成的(二)
|
8月前
|
机器学习/深度学习 传感器 算法
基于matlab绘制水中声波的吸收曲线
基于matlab绘制水中声波的吸收曲线
143.Mandelbrot分形图案
143.Mandelbrot分形图案
60 0
|
传感器 编解码 关系型数据库
Google Earth Engine——Arctic北极DEM是一个数字表面模型(DSM),描绘了包括植被、树冠、建筑物和其他人造表面特征在内的第一回的高程值,2米/5米分辨率
Google Earth Engine——Arctic北极DEM是一个数字表面模型(DSM),描绘了包括植被、树冠、建筑物和其他人造表面特征在内的第一回的高程值,2米/5米分辨率
289 0
Google Earth Engine——Arctic北极DEM是一个数字表面模型(DSM),描绘了包括植被、树冠、建筑物和其他人造表面特征在内的第一回的高程值,2米/5米分辨率
|
机器学习/深度学习 编解码 自然语言处理
谷歌像素递归超分辨率研究:怎么消灭低分辨率图像马赛克
最近,谷歌发布了一种把低分辨率图像复原为高分辨率图像的方法,参见机器之心文章《学界 | 谷歌新论文提出像素递归超分辨率:利用神经网络消灭低分辨率图像马赛克》。与最先进的方法相比,这篇论文提出了一种端到端的框架来完成超分辨率任务。它由两个卷积神经网络组成,一个是描述低分辨率图像骨架的优先网络(prior network),一个是用于优化细节特征的调节网络(conditioning network)。这种方法强调了细节特征恢复上的提升,并以概率范式(probabilistic paradigm)的形式提升了其理论。机器之心在本文中对相关研究《Pixel Recursive Super Resolu
358 0
谷歌像素递归超分辨率研究:怎么消灭低分辨率图像马赛克
彩铅练习:蓝色花朵
今天画了一朵蓝色的花,就是使用蓝色填充,力度不同,出来的效果也是不同的。 图片发自简书App
936 0