知识库



按索引浏览词汇表

特殊 | A | B | C | D | E | F | G | H | I | J | K | L | M | N | O | P | Q | R | S | T | U | V | W | X | Y | Z | 全部

页: (上一个)   1  2
  全部

运算符

运算符按其功能可分为以下几类:
1、算术运算符(+,-,×,/,%),加,减,乘,除,取余
2、逻辑运算符(&&,||,!),and,or,not,与,或,非
3、关系运算符(>,<,>=,<=),大于,小于,大于等于,小于等于
4、条件运算符(?微笑
表达式为:表达式1?表达式2:表达式3
先求解表达式1,
若其值为真(非0)则将表达式2的值作为整个表达式的取值,
否则(表达式1的值为0)将表达式3的值作为整个表达式的取值。
例如:
(1)max=(a>b)?a:b
就是将a和b二者中较大的一个赋给max。
(2)min=(a<b)?a:b
就是将a和b二者中较小的一个赋给min。

优先级高于赋值、逗号运算符,低于其他运算符。例如:

⑴ m<n ? x : a+3
等价于:(m<n) ?(x) 伤心a+3)
⑵ a++>=10 && b-->20 ? a : b
等价于:(a++>=10 && b-->20) ? a : b
⑶ x=3+a>5 ? 100 : 200
等价于:x= (( 3+a>5 ) ? 100 : 200 )
5、位运算符(~,|,^,&,^~)
6、移位运算符(<<,>>)
7、拼接运算符({ })
8、赋值运算符(=,<=),
9、复合的赋值运算符,又称为带有运算的赋值运算符,也叫赋值缩写。
例如:i=i+j;可表示为 i+=j;这里+=是复合赋值运算符
同样的共有10种这样的运算符,它们是:
+= 加赋值
-= 减赋值
*= 乘赋值
/= 除赋值
%= 求余赋值
&= 按位与赋值
| = 按位或赋值
^= 按位异或赋值
<<= 左移位赋值
>>= 右移位赋值
<> 当右操作数又是一个赋值表达式时,形成多重赋值表达式。例如:
i=j=0; //结果i、j的值都为0
构成复合赋值表达式的一般形式
变量 双目运算符=表达式
它等效于
变量=变量 运算符 表达式
例如:
a+=5 等价于a=a+5
x*=y+7 等价于x=x*(y+7)
r%=p 等价于r=r%p

标签:

随机

随机不只是 Math.random —— 前端噪声应用

腾讯CDC 736阅读 2019-07-18

在了解噪声之前,我对随机的认识,仅仅停留在 Math.random。它很有用,比如 H5 里的简单抽奖程序,或者随机选取一张卡片… 而最近工作中需要实现一些的随机图像效果,让我发现这个函数能做的事十分有限。之后我偶然了解到噪声这一种随机形式,它很完美的解决了我的问题。于是我想写这一篇文章,希望可以让一些前端同学,特别是工作上涉及较多效果还原的前端同学了解噪声,或许在这之后,你会对设计师设计稿上这些随意元素,有更多的想法。

设计师经常会在他们的设计中添加一些随意元素,这是一种很棒的设计技巧。但是对于前端实现来说,这类设计元素的还原大多数情况会让我们感到无能为力,因为基础 Api 提供的都是规律的几何形状(圆,矩形等…),常常最后,这些效果都只好妥协使用切图还原,我们不能做更多优化,更不能通过增加动画表现更多的设计想法,这一直是大多数同学前端还原的空白领域。

 

设计稿中的随意元素

上面这些图片都是从一些真实设计稿中截取的,其中很容易找到我所说的随机元素,它们给设计增添神秘感和科技感,但是它们好像很难用传统的前端设计还原技巧制作。而这些,恰恰非常适合使用噪声来实现。

噪声算法经过多年发展已经非常成熟,而且有很多种分类 Perlin噪声, Simplex噪声,Wavelet噪声,本篇文章里边出现的噪声默认指的是 Perlin 噪声,不会深入介绍具体噪声算法,主要目的是向没有接触过这个领域的前端同学作一个启发式的介绍。

随机的线

先来解决一个简单的问题:画出一根随意的线。这似乎很简单,我们用 Math.random 生成一系列的点,然后把他们连接起来

随机线1

for (let i = 0; i < POINTCOUNT; i++) {   const y = HEIGHT / 2 + (Math.random() - 0.5) * 2 * MAXOFFSET;   const point = {     x: i * STEP,     y   };   POINTS.push(point); } ... ctx.moveTo(POINTS[0].x, POINTS[0].y);  for (let i = 1; i < POINTS.length; i++) {   const point = POINTS[i];   ctx.lineTo(point.x, point.y); } ctx.stroke(); 

 

但是这没有什么特别的,像是刻意画出来的折线图。直线让我们的图像很生硬,下面我们做点小改良,我们在两个随机点间找两个控制点,用贝塞尔曲线再次将随机点连起来:

随机线2

for (let i = 0; i < POINTS.length - 1; i++) {   const point = POINTS[i];   const nextPoint = POINTS[i + 1];    ctx.bezierCurveTo(     controlPoints[i][1].x,      controlPoints[i][1].y,      controlPoints[i + 1][0].x,      controlPoints[i + 1][0].y,     nextPoint.x,     nextPoint.y   ); } ctx.stroke(); 

 

 

这次自然多了,我们这一步做的事情很关键,虽然这不是噪声算法的本身,但是其中的思想是一样的。上面例子的随机点,我们可以理解为随机特征,单个随机特征是没有意义的。之后我们用直线连接起来,它们整体看起来依然没有联系,但是我们将他们平滑地串联起来之后,它们互相之前形成了一个完整的图案,得到了一种自然的随机效果。这也是我学习完噪声的主观理解——噪声主要解决的问题,就是让互不相关的随机特征,产生某种平滑地过渡或联系。

好,到这里我们停下来,想想大自然,放松一下。想想云、河流、山脉… 这些、都是大自然里各种随机事件,日积月累创造出来的。这里的关键,就是“日积月累”,也就是说不会平白无故地出现一片云、不会突然就出现一条河,他们都是一点一点演变而来的,所以在这些随机事件中是“平滑”变换的。

 

柏林噪声

在现代游戏和影视作品中,已经有能力逼真地还原这些自然元素了。它们并不是也不可能使用大量建模软件制作,而是用代码生成的,这里用到的关键技术,就是噪声算法。这种算法重要的部分,就是在随机特征中的插值算法,在随机特征中间的值能平滑过度,以模拟大自然中这种演变的结果。

Ken Perlin 早在1983年正在参与制作迪士尼的动画电影《TRON》,就是为了实现这种自然的纹理效果,提出了 Perlin 噪声,Perlin 噪声很成功,他也因此获得了奥斯卡科技成果奖。

我们上面例子为了在随机特征间平滑过度使用了贝塞尔曲线,而柏林噪声则使用了更加科学复杂的插值方法:

f(t)=t*t*t*(t*(t*6-15)+10) 

有兴趣可以自行查阅其中实现细节。柏林噪声经过发展演变出了很多变形实现,包括后来柏林噪声的优化版本 simplex 噪声,本文侧重于介绍噪声的使用,下文其中一些实现,默认使用就是柏林噪声。

 

噪声函数的使用

噪声函数的使用方法都是接受一个点,然后返回一个 -1 到 1 的结果,随机特征长度单位为 1,所以在使用噪声函数之前,需要注意单位的转换。
比如,你有一个 1000 x 1000 的画布,想要使用噪声对应每个像素的随机值,那就首先就要定义想应用多少个随机方格,如果应用 n x n 个方格,那在获取随机值之前,就需要对坐标进行转换

scale = 1000 / n;  nx = x / scale; ny = y / scale;  pointRandom = noise2D(nx, ny); 

 

js 实现的噪声工具:
https://github.com/josephg/noisejs
https://github.com/jwagner/simplex-noise.js

随机集

噪声接受相同的参数总是能返回相同的结果,所以通常要预设一个随机集,目的就是为了生成固定的随机特征点,然后平滑的随机结果将在这些随机特征点中插值产生。当中的实现不做讨论,有些噪声工具默认已经设置好了一个随机集,也可以自定义不同的种子来生成不同的随机效果,上一个噪声工具 noisejs 可以这样简单定义即可:

noise.seed(Math.random()); 

一维噪声

一维噪声可以这样简单理解,将随机集分配到 x 轴上整数位上,通过平滑插值函数计算连续变换的随机值。这个说法可能和具体 Perlin 噪声不完全一样,但是基本思路可以这样简单理解

一维噪声

简单从结果上来讲就是给定一个坐标,你将得到一个随机值,如果给定连续的坐标,你将可以得到连续的随机值,而不是像 Math.random() 那样得到互不相关的错落的值。

一维噪声示例

下面的例子是使用一维噪声制作的一个鸡蛋的效果,先在圆上取固定的等分的点,它们分别通过 noise 获取到一个随机偏移,然后再结合时间,让偏移随着时间平滑地改变:

https://codepen.io/chiunhauyou/pen/LkjvYw

egg

比如下面这个火的效果,火焰尾部摇曳的效果的偏移,就是一维噪声结合时间偏移实现的

https://codepen.io/gnauhca/pen/wxKMEg

fire

一维噪声这种随时间偏移的效果,还可以通过把时间作为二维噪声函数的 y 参数实现。

二维噪声

二维噪声通过定义一个二维的方格,上一步定义的固定的随机集会被分布在这些方格顶点上,而每一个顶点的随机特征是一个梯度向量,然后,计算方格内的点周围四个顶点到方格内一个点(也就是需要求噪声值的点,下图中黄色的点)的向量,用他们与梯度向量点乘,最后使用插值函数进行插值得到该点对应的随机噪声值。

二维噪声1

下面图像是使用 webGL 应用 2D 噪声函数生成的,白色代表 1,黑色代表 -1,这是 5 * 5 方格的效果。这里不用关心 webgl,我们只要关心如何定义适用自己问题的方格,还有获取对应的连续的随机值。

 

二维噪声2

这里侧重的是介绍噪声使用,具体实现方法可以自己点击下面参考链接了解。使用方法很简单:

// 这里除 100 是为了以一百个像素为单位应用一个噪声方格 let randomValue = noise.simplex2(x / 100, y / 100); 

二维噪声示例

噪声函数获取的随机值就很自由了,它可以用来定义各种你需要的变量,比如下面这个例子,平滑地随机值被用作定义粒子的速度向量从而实现既随机又连续的运动效果:

function calculateField() {   for(let x = 0; x < columns; x++) {     for(let y = 0; y < rows; y++) {       let angle = noise.simplex3(x/20, y/20, noiseZ) * Math.PI * 2;       let length = noise.simplex3(x/40 + 40000, y/40 + 40000, noiseZ) * 0.5;       field[x][y].setLength(length);       field[x][y].setAngle(angle);     }   } }

生成向量一个随机角度,和向量长度,这里使用 simplex3 三维噪声实际上第三个参数是被用作二维的偏移量

https://codepen.io/DonKarlssonSan/pen/aLRVbw

二维噪声示例1

如果保留运动痕迹,则可以得到更炫酷的效果

// 使用半透明清楚画布 function drawBackground(alpha) {   ctx.fillStyle = `rgba(0, 0, 0, ${alpha || 0.07})`;   ctx.fillRect(0, 0, w, h); } 

https://codepen.io/DonKarlssonSan/pen/QqzWYj

二维噪声示例2

二维噪声示例(svg)

通过把几个不同频率的 Perlin 噪声相叠加,这项技术叫做分形噪声,可以实现更多纹理,比如水流,山川。
SVG 中有一个这种噪声的滤镜应用,feTurbulence,对比普通我们熟知的 css 滤镜,它很容易被人忽略,但是它却能实现很多意想不到的效果:

<feTurbulence type="turbulence" baseFrequency="0.01 .1" numOctaves="1" result="turbulence" seed="53" /> 
  • numOctaves 噪声叠加数
  • seed 随机种子
  • type 噪声类型

feTurbulence 实际上是在每个像素上应用得到的噪声值,从而得到颜色值,然后可以结合其他滤镜,将这些随机颜色转换成其他随机表现,如像素偏移,可以使用 feTurbulence 滤镜实现一些自然纹理,还有倒影效果。

feTurbulence 滤镜输出

https://codepen.io/yoksel/pen/yqZYbK

二维噪声示例(svg)

https://wow.techbrood.com/fiddle/31650

二维噪声示例(svg)2

这里的噪声叠加在频率和振幅上有一定的约束,它们是自相似的,参考https://thebookofshaders.com/13

三维噪声

三维噪声实际上就只是在二维噪声基础上又增加一个纬度,定义一个三维的随机顶点集,在三维方格当中的三维坐标,将会对应得到一个噪声值,同样也是连续的。

三维噪声获取的随机值可以转换成一个三维点在其法向向量方向的偏移,从而实现一种随机的起伏变形。在 webGL 当中,这一步这通常在顶点着色器当中完成,顶点着色器会对所有定义的顶点执行:

float addLength = maxLength * cn(normalize(position) * 2.9 + time * 0.9); // 计算随机值 vec3 newPosition = position + normal * addLength; // 转换为法向向量方向上的偏移值 

https://codepen.io/gnauhca/pen/RyNZBx?

三维噪声1

在片元着色器中,则可以应用使用噪声制作纹理:

https://codepen.io/timseverien/pen/bWXvxE

三维噪声2

就像之前提到的噪声被设计出来的一开始的目的,就是应用在影视/游戏作品当中模拟自然效果的,所以,使用 webGL 制作海洋,山川这种效果,也自然不在话下:
https://codepen.io/matikbird/pen/xVvqWQ

三维噪声3

三维噪声4

当然这不仅需要熟练使用噪声,还需要掌握 webGL,虽然一开始我们介绍了噪声在 canvas/svg 中的使用方法,但是,现在 webGL 已经被电脑端手机端浏览器广泛支持,结合 webGL ,噪声能发挥它更大价值。

结语

噪声的应用十分广泛,是图形学领域的重要知识,在三维程序扮演重要的角色。但是噪声不是三维图形领域的专属,学习使用噪声,在 canvas svg css 这些基础的前端技术上应用,也能实现一些意想不到的效果,当某一天设计师又输出了一个类似这种随机特征的效果图,不妨直接找到设计师沟通。说不定这些效果,就是用某个图像处理软件使用噪声生成的。如果获取到生成的参数,在前端也是有可能实现的,通过结合时间偏移,说不定就能实现一个很棒的动画。

参考资料
https://blog.csdn.net/qq_34302921/article/details/80849139
https://codepen.io/DonKarlssonSan/post/particles-in-simplex-noise-flow-field
https://thebookofshaders.com/13/?lan=ch



颜色

以下教程来自于由 Daniel Shiffman 篇写的《 Learning Processing 》(原文英文),并由 Morgan Kaufmann 出版,© 2008 Elsevier Inc。版权所有。此教程由 Kelly Chang 移植成 P5 代码。如果您发现任何错误或有任何评论,请联络我们。

颜色

在数码世界中,当我们要介绍一个颜色时,我们需要有一定的精确度。单纯说 “嘿,你能把那圆形变成蓝绿色吗?” 并不足够。在这,颜色可以被定义为在一个范围内的数字。让我们从最简单的范例开始:黑白色或灰渐色。0 为纯黑色,255 为纯白色。在两者之间任何数字 – 50、87、162、209 等等 – 都是介于黑与白之间的灰色。

grayscale.svg

只要在任何东西被画在画布上之前使用 stroke() 及 fill() 函数,我们能设置任何图形的颜色。我们也能使用 background() 函数来设定窗口的背景颜色。如下范例。

background(255);    // 设置背景颜色为白色
stroke(0);          // 设置外线颜色为黑色
fill(150);          // 设置填充色为灰色
rect(50,50,75,100); // 绘制四方形

使用 noStroke() 及 noFill() 函数将会分别去除外线色灰填充色。我们直觉上可能会以为 “stroke(0) ” 表示没有外线,可是我们必须记得 0 在这并不代表“无”,然而是代表黑色。此外,我们必须记得不要同时去除 noStroke() 及 noFill() 不然不会有任何图形出现在画布上!

以此同时,如果我们绘制两个图形,p5.js 将会使用最近(代码内从上至下)所定义的外线色及填充色值。

RGB 颜色值

您还记得手指绘画吗?选择混合三原色,我们能混合出任何颜色。同时混合所有颜色的结果是个浑浊的褐色。添加越多颜料,给颜色将会变得更暗。数码颜色也是使用三原色的混合来构造新的颜色的,但是它和颜料的混合原理不一样。首先,其原色为:红、绿、蓝(也为 RGB 颜色,Red、Green、Blue)。而当您在混合荧幕上的颜色时,您将混合的是光而不是颜料,因此它的混合原理并不一样。

rgb.jpg

  • 红 + 绿 = 黄
  • 红 + 蓝 = 紫
  • 绿 + 蓝 = 青(蓝绿色)
  • 红 + 绿 + 蓝 = 白
  • 无色 = 黑

这假设所有色颜色都为最亮的亮度,但是您也能同时使用一系列的颜色值,因此一些红加上一些绿再加上一些蓝将等于灰,而一点红加上一点蓝将等于深紫色。虽然这可能需要一点时间来习惯,随着您编程及使用 RGB 颜色值来试验的经验越多,您会对它越熟悉,就如使用您的手指来混合颜色一样。当然您不能单纯说 “混合一些红与一点蓝”,您必须提供确切的数值。就如灰渐值,个别颜色的值也是由介于 0(不使用任何该颜色)与 255(完全使用该颜色)之间,而他们的顺序为红(R)、绿(G)及蓝(B)。通过更多的试验您将会对 RGB 颜色更加熟悉,不过接下来我们将介绍一些使用常用颜色的代码。

颜色透明度

除了个别颜色的红、绿、蓝值之外,我们也能提供多一个可选性的值,此值被称为该颜色的 “alpha” 值。Alpha 代表透明度,当您要绘制多个重叠部分透视的图形时,透明度在这就特别有用。一个图像的 alpha 值有时也会被称为该图像的 “alpha channel”。

我们必须记得像素并不是真的透明的,这单纯是个使用混合颜色所达成的便利错觉。p5.js 在幕后将会使用该颜色的数值再加上一定百分率的另外一个颜色,创作出混合颜色的视觉错觉。(如果您有兴趣编程一个 “粉色镜片”,您可以从这开始。)

Alpha 值也是介于 0 与 255 之间,0 代表完全透明而 255 代表完全不透明。

自定义颜色值范围

介于 0 与 255 之间的 RGB 颜色值并不是 p5.js 唯一定义颜色的方法,事实上,我们能使用多种方法来定义颜色。比如说,您可能比较偏向于使用 0 至 100(如百分比)来定义颜色。为此您可以使用 colorMode().


      colorMode(RGB,100);
      

以上函数表示:“OK,我们要使用红、绿、蓝值来定义颜色。而他们的值将介于 0 至 100 之间。

虽然一般上这么做不会提供任何便利,您可以为个别颜色值提供不同的数值范围:


      colorMode(RGB,100,500,10,255);
      

这时此函数表示:“红色值将会是介于 0 至 100 之间,绿色值将会是介于 0 至 500 之间,蓝色值将会是介于 0 至 10 之间,而 alpha 至将会是介于 0 至 255 之间。

最后,虽然您通常在编程时只需要用到 RGB 色值,您也能使用 HSB(色调、饱和度及亮度)模式来定义颜色。简单来说,HSB 色值使用方法如下:

hsb.png
  • 色调—色调值,默认上介于 0 至 360 之间。
  • 饱和度—该颜色的饱和度,默认上介于 0 至 100 之间。
  • 亮度—该颜色的亮度,默认上介于 0 至 100 之间。

使用函数 colorMode() 您就能设定您自选的数字范围。有些人会比较偏好使用介于 0 至 360 之间的数值来定义色调(就如色轮的 360 度一样)及 0 至 100 之间的数值来定义饱和度及亮度(介于 0% 至 100%)。



颜色模式RGB+HSL+HSB

▶️运行示例代码

RGB原理

RGB色彩模式是工业界的一种颜色标准,是通过对红(R)、绿(G)、蓝(B)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,RGB即代表红、绿、蓝三个通道的颜色,这个标准几乎包括了人类视力所能感知的所有颜色,是目前运用最广的颜色系统之一。

RGB是从颜色发光的原理来设定的,当它们的光相互叠合的时候,色彩相混,而亮度却等于两者亮度之总和,越混合亮度越高,即加法混合。

红、绿、蓝三个颜色通道每种色各分为256阶亮度,当三色灰度数值相同时,产生不同灰度值的灰色调,即三色灰度都为0时,是最暗的黑色调;三色灰度都为255时,是最亮的白色调。


HSL原理

HSL色彩模式是工业界的另一种颜色标准,是通过对色相(H)、饱和度(S)、明度(L)三个颜色通道的变化以及它们相互之间的叠加来得到各式各样的颜色的,HSL即是代表色相,饱和度,明度三个通道的颜色。


HSL的H(hue)分量,代表的是人眼所能感知的颜色范围,这些颜色分布在一个平面的色相环上,取值范围是0°到360°的圆心角,每个角度可以代表一种颜色。色相值的意义在于,我们可以在不改变光感的情况下,通过旋转色相环来改变颜色。在实际应用中,我们需要记住色相环上的六大主色,用作基本参照:360°/0°红、60°黄、120°绿、180°青、240°蓝、300°洋红,它们在色相环上按照60°圆心角的间隔排列。




HSL的S(saturation)分量,指的是色彩的饱和度,它用0%至100%的值描述了相同色相、明度下色彩纯度的变化。数值越大,颜色中的灰色越少,颜色越鲜艳,呈现一种从灰度到纯色的变化。


HSL的L(lightness)分量,指的是色彩的明度,作用是控制色彩的明暗变化。它同样使用了0%至100%的取值范围。数值越小,色彩越暗,越接近于黑色;数值越大,色彩越亮,越接近于白色。



HSB(HSV)原理

HSB又称HSV,表示一种颜色模式:在HSB模式中,H(hues)表示色相,S(saturation)表示饱和度,B(brightness)表示亮度HSB模式对应的媒介是人眼。

色相(H,hue):在0~360°的标准色轮上,色相是按位置度量的。在通常的使用中,色相是由颜色名称标识的,比如红、绿或橙色。黑色和白色无色相。

饱和度(S,saturation):表示色彩的纯度,为0时为灰色。白、黑和其他灰色色彩都没有饱和度的。在最大饱和度时,每一色相具有最纯的色光。取值范围0~100%。

亮度(B,brightness或V,value):是色彩的明亮度。为0时即为黑色。最大亮度是色彩最鲜明的状态。取值范围0~100%。



HSB(HSV)和HSL区别

HSB 和 HSL 在字面意思上是一样的:

H指的是色相(Hue),就是颜色的名称,例如‘红色’、‘蓝色’等。

S指的是饱和度(Saturation),即颜色的纯度。

L(Lightness)和B(Brightness)是明度,颜色的明亮程度。

在原理和表现上,HSL和HSB中的H(色相)完全一致,但二者的S(饱和度)不一样,L和B(明度)也不一样。

HSB中的S控制纯色中混入白色的量,值越大,白色越少,颜色越纯;

HSB中的B控制纯色中混入黑色的量,值越大,黑色越少,明度越高。

HSL中的S和黑白没有关系,饱和度不控制颜色中混入黑白的多寡;

HSL中的L控制纯色中的混入的黑白两种颜色。

实际应用场景中,Photoshop和Affinity Designer的拾色器。两者分别使用了HSB和HSL颜色模型,两个拾色器都是X轴表示饱和度,越往右,饱和度越高;Y轴表示明度,越往上明度越高。



Photoshop的HSB颜色模型拾色器,如下图所示,HSB的B(明度)控制纯色中混入黑色的量,越往上,值越大,黑色越少,颜色明度越高。


如下图所示,HSB的S(饱和度)控制纯色中混入白色的量,越往右,值越大,白色越少,颜色纯度越高。


Affinity Designer的HSL颜色模型拾色器,如下图所示,Y轴明度轴,从下至上,混入的黑色逐渐减少,直到50%位置处完全没有黑色,也没有白色,纯度达到最高。继续往上走,纯色混入的白色逐渐增加,到达最高点为纯白色,明度最高。


HSL和HSB(HSV)最大的差别是对于白色的理解,HSL当L达到最大时是白色,与饱和度S无关,所以可以理解此处的亮度L其实指的是白的量,白的量越多就越白,越亮越白比较像大自然的光。HSB(HSV)饱和度最低的时候是白色。明度B(V)改变只会改变颜色与颜色对比时的明暗关系。所以这里的饱和度S,可以理解为是彩色的量,彩色的量为0了,就自然是白色的。饱和度越高颜色越鲜明。



RGB空间和HSL空间


左为 RGB 空间,右为 HSL 空间


RGB到HSL或HSV的转换



HSL到RGB的转换




HSB(HSV)到RGB转换



HSL/V/B在各种环境下的取值范围






页: (上一个)   1  2
  全部