【30分钟学完】canvas动画|游戏基础(extra1):颜色那些事
前言
本篇主要讲解关于计算机颜色系统的概念,后续结合一些canvas的应用。因为是“你不知道也没关系”的边缘知识,所以作为本系列教程的扩展,没有兴趣的同学可以跳过。
开始我们万紫千红的故事吧!
本人能力有限,欢迎牛人共同讨论,批评指正。
先从老朋友CSS讲起
我们熟悉的CSS风格颜色表示方式,大体有下面几种,canvas大体是直接沿用这些写法的,但最后包含透明度的写法有些许不同。
#RRGGBB:十六进制格式,红绿蓝分别用两位十六进制数表示。#RGB:简写的十六进制格式,转换成6位格式时会重复三原色,例如#fb0->#ffbb00。rgb(R,G,B):函数表达式,三原色分别由0~255的整数值表示。rgba(R,G,B,A):包含透明度的函数表达式,其中alpha参数为0~1,需要指定透明度的颜色必须使用该格式。
作为前端人员平时用得很多,但你可能会一脸懵逼之前自己写的颜色字符串居然是十六进制?
待我细细道来。这里的R即是红色(red),G即是绿色(green),B即是蓝色(blue),这三个是显示器普遍使用的三基色,属于叠加型原色,百科摘录如下。
【科普】原色是指不能透过其他颜色的混合调配而得出的“基本色”。
以不同比例将原色混合,可以产生出其他的新颜色。以数学的向量空间来解释色彩系统,则原色在空间内可作为一组基底向量,并且能组合出一个“色彩空间”。由于人类肉眼有三种不同颜色的感光体,因此所见的色彩空间通常可以由三种基本色所表达,这三种颜色被称为“三原色”。一般来说叠加型的三原色是红色、绿色、蓝色(又称三基色,用于电视机、投影仪等显示设备);而消减型的三原色是品红色、黄色、青色(用于书本、杂志等的印刷)。
解密颜色值
每一个颜色都是由三基色叠加合成,所以我们需要告诉计算机这各个基色的比例(浓度),将这个比例量化就是一个0~255的整数,也可说是256个级别,越大即表示各种原色更多(更浓)。
【PS】至于为什么是256个级别?
是因为计算机中每个原色用8位二进制(0或1)表示,也就是2的8次方共256。
每个颜色都是256个级别,那它的组合的可能就有256*256*256=16777216,换句话说,一个颜色用24位二进制表示,换算成十进制就是0~16777215。
这里你应该可以看懂上面CSS颜色表示方式前三个的含义了吧,至于rgba(R,G,B,A)多加入了A,表示透明度,这个是扩展版的32位颜色系统,多了一个额外的8位二进制表示透明度的级别,CSS将它简化成0~1表示。
- *
举个例子吧!
以#FF55F3这个颜色为例进行讲解。(0x开头表示十六进制数,js中不区分大小写,至于不知道什么是十六进制的,请自行百度)
红色是0xFF,绿色是0x55,蓝色0xF3。
转换成十进制:红色是255,绿色是85,蓝色是243。也就是说这个数值和rgb(255,85,243)写法是等价的。
【PS】简便的转换方法,直接在控制台打印即可,比如
console.log(0xF3);,js默认输出十进制表示的字符串。
颜色合成
颜色理论学得差不多了,现在来看看合成,已知三原色的值,要如何用代码合成一个颜色呢?
以上面说的#FF55F3为例,现在已知的是各个颜色值,下面提供两种做法:
1、得到rgb(R,G,B)格式
直接利用js数字转换为字符串时默认是十进制的特性。
let r = 0xFF;
let g = 0x55;
let b = 0xF3;
let color = `rgb(${r},${g},${b})`;
2、得到#RRGGBB格式
一个24位的颜色值,二进制即:RRRRRRRRGGGGGGGGBBBBBBBB
红色值左移16位,绿色左移8位,将三者做“或”就能得到合成的24位颜色值,再转成16进制字符串即可。
0xFF << 16 = 111111110000000000000000
0x55 << 08 = 000000000101010100000000
0xF3 = 000000000000000011110011
OR = 111111110101010111110011
//省略跟前面一样的...
let color = `#${(r << 16 | g << 8 | b).toString(16)}`;
颜色分解
合成学完了,现在考虑一下如何用代码分解颜色,也就是把一个颜色分离出红、绿、蓝。rgb(R,G,B)格式就说了,切字符串就能得到。
重点讨论#RRGGBB格式,其实就是第二种合成方法的逆过程,右移后“与“操作,简单来说就是把想要的颜色值所在的位置移动到末尾,再用“与”0xFF剔除其他颜色。
还是以#FF55F3为例,现已知这个字符串,要求分解出三基色的值。
- 切除“#”号得到16进制字符串;
- 红色:右移16位,与0xFF做“与”操作;
- 绿色:右移8位,与0xFF做“与”操作;
- 蓝色:直接与0xFF做“与”操作。
let color = parseInt('#FF55F3'.slice(1), 16);
let r = color >> 16 & 0xFF
let g = color >> 8 & 0xFF
let b = color & 0xFF
以绿色提取过程为例:
0xFF55F3 = 111111110101010111110011
0xFF55F3 >> 8 = 000000001111111101010101
0xFF = 000000000000000011111111
AND = 000000000000000001010101
封装颜色工具
当然,上面的合成、分解代码都是基本理论的应用,实际项目中使用会为了健壮性封装成更加合理的工具,可以参考我们工具类utils.js中的colorToRGB()和parseColor()两个函数。
- colorToRGB()用于将
#RRGGBB格式或任意数字,转换成rgb(R,G,B)或rgba(R,G,B,A); - parseColor()用于将
#RRGGBB格式转成数字,将数字转成#RRGGBB格式。
【30分钟学完】canvas动画|游戏基础(extra1):颜色那些事的更多相关文章
- 【30分钟学完】canvas动画|游戏基础(2):从零开始画画
前言 上篇主要是理论的概述,本篇会多些实践,来讲讲canvas的基础用法,并包含一些基础三角函数的应用,推荐没有canvas基础的朋友阅读,熟悉的朋友可以跳过. 本人能力有限,欢迎牛人共同讨论,批评指 ...
- 【30分钟学完】canvas动画|游戏基础(1):理论先行
前言 本文虽说是基础教程,但这是相对动画/游戏领域来说,在前端领域算是中级教程了,不适合前端小白或萌新.阅读前请确保自己对前端三大件(JavaScript+CSS+HTML)的基础已经十分熟悉,而且有 ...
- 【30分钟学完】canvas动画|游戏基础(extra1-1):美图我也行
前言 本文是接续系列教程的extra1,主要是介绍颜色系统在canvas中的应用. 本来是与extra1一起成文的,因为segmentfault莫名其妙的字数限制bug只能分割放送了. canvas操 ...
- 【30分钟学完】canvas动画|游戏基础(7):动量守恒与多物体碰撞
前言 一路沿着本系列教程学习的朋友可能会发现,前面教程中都尽量避免提及质量的概念,很多运动概念也时刻提醒大家这不是真实的物体运动.因为真实的物体运动其实跟质量都是密不可分的,而且质量的引入自然必须提及 ...
- 【30分钟学完】canvas动画|游戏基础(4):边界与碰撞
前言 本系列前几篇中常出现物体跑到画布外的情况,本篇就是为了解决这个问题. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 越界检测 假定物体是个圆形,如图其圆心坐标即是物 ...
- 【30分钟学完】canvas动画|游戏基础(6):坐标旋转探究
前言 本篇主要讲坐标旋转及其应用,这是编程动画必不可少的技术. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 坐标旋转 模拟场景:已知一个中心点(centerX,cent ...
- 【30分钟学完】canvas动画|游戏基础(5):重力加速度与模拟摩擦力
前言 解决运动和碰撞问题后,我们为了让运动环境更加自然,需要加入一些环境因子,比如常见的重力加速度和模拟摩擦力. 阅读本篇前请先打好前面的基础. 本人能力有限,欢迎牛人共同讨论,批评指正. 重力加速度 ...
- 30分钟学玩转RabbitMQ
最近在学习RabbitMQ,在网上找了不少资料发现都特高端.动辄集群部署,分布式架构什么的,对于一个初学者实在不够友好.心想求人不如求自己,为什么不自己整理一套资料呢?于是<30分钟学玩转Rab ...
- 3分钟学完Python,直接从入门到精通
作为帅气小编,我已经把python一些模块的甩在这儿了qwq,只要你拿到这些干货,包你玩转python,直接冲向"大佬"的段位,如果已经学了C或者C++或者说如果你需要你的一段关键 ...
随机推荐
- WPF图标拾取器
<Grid x:Name="LayoutRoot"> <Border BorderBrush="> <Border.Effect> & ...
- 三十七:数据库之SQLAlchemy外建之多对多关系
准备工作 from sqlalchemy import create_engine, Column, Integer, String, Float, Text, ForeignKeyfrom sqla ...
- 手机端 video 视频自动播放方法
//创建一个video标签 var __video = $("#video").appendTo('.i-i-video'); //设置视频文件地址 __video.attr('s ...
- qrcode-reader——二维码识别
JavaScript QRCode reader for HTML5 enabled browser 参考资料1:[https://www.npmjs.com/package/qrcode-reade ...
- 关于JS的prototype详解
JavaScript面向对象 构造函数和原型链 首先,我们要先了解一下类的概念,JavaScript 本身是一种面向对象的语言,它所涉及的元素根据其属性的不同都依附于某一个特定的类.我们所常见的类包括 ...
- 解密Go语言之 pprof
相信很多人都听过“雷神 3”关于性能优化的故事.在一个 3D 游戏引擎的源码里,John Carmack 将 1/sqrt(x) 这个函数的执行效率优化到了极致. 一般我们使用二分法,或者牛顿迭代法计 ...
- 【github】git常用命令和node项目
这是之前在本地搞的一个小东西.因为之前电脑经常会很卡.后来发现任务管理器中多了两个不知名的进程:chromgpu.exe和flrefox.exe 乍一看以为和chrome和firefox两个浏览器有关 ...
- Matlab学习笔记1—MATLAB基础知识
1.1 MATLAB系统环境 1.MATLAB操作界面的组成 (1)MATLAB主窗口 (2)命令行窗口:命令行窗口用于输入命令并显示命令的执行结果. (3) 当前文件夹窗口 如何设置当前文件夹呢? ...
- 【VS开发】解决位图缩放失真
当用以下函数加载一张位图时,当窗口发生重绘更改大小时,位图将失真: CBitmap bitmap; bitmap.LoadBitmap(IDB_BITMAP2); BITMAP bmp; bit ...
- Akka系列(七):Actor持久化之Akka persistence
前言.......... 我们在使用Akka时,会经常遇到一些存储Actor内部状态的场景,在系统正常运行的情况下,我们不需要担心什么,但是当系统出错,比如Actor错误需要重启,或者内存溢出,亦或者 ...