mirror of
https://github.com/google/blockly.git
synced 2026-01-07 09:00:11 +01:00
* fix(build): Restore erroneously-deleted filter function This was deleted in PR #7406 as it was mainly being used to filter core/ vs. test/mocha/ deps into separate deps files - but it turns out also to be used for filtering error messages too. Oops. * refactor(tests): Migrate advanced compilation test to ES Modules * refactor(build): Migrate main.js to TypeScript This turns out to be pretty straight forward, even if it would cause crashing if one actually tried to import this module instead of just feeding it to Closure Compiler. * chore(build): Remove goog.declareModuleId calls Replace goog.declareModuleId calls with a comment recording the former module ID for posterity (or at least until we decide how to reformat the renamings file. * chore(tests): Delete closure/goog/* For the moment we still need something to serve as base.js for the benefit of closure-make-deps, so we keep a vestigial base.js around, containing only the @provideGoog declaration. * refactor(build): Remove vestigial base.js By changing slightly the command line arguments to closure-make-deps and closure-calculate-chunks the need to have any base.js is eliminated. * chore: Typo fix for PR #7415
266 lines
6.4 KiB
TypeScript
266 lines
6.4 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright 2019 Google LLC
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
// Former goog.module ID: Blockly.utils.colour
|
|
|
|
/**
|
|
* The richness of block colours, regardless of the hue.
|
|
* Must be in the range of 0 (inclusive) to 1 (exclusive).
|
|
*/
|
|
let hsvSaturation = 0.45;
|
|
|
|
/**
|
|
* Get the richness of block colours, regardless of the hue.
|
|
*
|
|
* @returns The current richness.
|
|
* @internal
|
|
*/
|
|
export function getHsvSaturation(): number {
|
|
return hsvSaturation;
|
|
}
|
|
|
|
/**
|
|
* Set the richness of block colours, regardless of the hue.
|
|
*
|
|
* @param newSaturation The new richness, in the range of 0 (inclusive) to 1
|
|
* (exclusive)
|
|
* @internal
|
|
*/
|
|
export function setHsvSaturation(newSaturation: number) {
|
|
hsvSaturation = newSaturation;
|
|
}
|
|
|
|
/**
|
|
* The intensity of block colours, regardless of the hue.
|
|
* Must be in the range of 0 (inclusive) to 1 (exclusive).
|
|
*/
|
|
let hsvValue = 0.65;
|
|
|
|
/**
|
|
* Get the intensity of block colours, regardless of the hue.
|
|
*
|
|
* @returns The current intensity.
|
|
* @internal
|
|
*/
|
|
export function getHsvValue(): number {
|
|
return hsvValue;
|
|
}
|
|
|
|
/**
|
|
* Set the intensity of block colours, regardless of the hue.
|
|
*
|
|
* @param newValue The new intensity, in the range of 0 (inclusive) to 1
|
|
* (exclusive)
|
|
* @internal
|
|
*/
|
|
export function setHsvValue(newValue: number) {
|
|
hsvValue = newValue;
|
|
}
|
|
|
|
/**
|
|
* Parses a colour from a string.
|
|
* .parse('red') = '#ff0000'
|
|
* .parse('#f00') = '#ff0000'
|
|
* .parse('#ff0000') = '#ff0000'
|
|
* .parse('0xff0000') = '#ff0000'
|
|
* .parse('rgb(255, 0, 0)') = '#ff0000'
|
|
*
|
|
* @param str Colour in some CSS format.
|
|
* @returns A string containing a hex representation of the colour, or null if
|
|
* can't be parsed.
|
|
*/
|
|
export function parse(str: string | number): string | null {
|
|
str = `${str}`.toLowerCase().trim();
|
|
let hex = names[str];
|
|
if (hex) {
|
|
// e.g. 'red'
|
|
return hex;
|
|
}
|
|
hex = str.substring(0, 2) === '0x' ? '#' + str.substring(2) : str;
|
|
hex = hex[0] === '#' ? hex : '#' + hex;
|
|
if (/^#[0-9a-f]{6}$/.test(hex)) {
|
|
// e.g. '#00ff88'
|
|
return hex;
|
|
}
|
|
if (/^#[0-9a-f]{3}$/.test(hex)) {
|
|
// e.g. '#0f8'
|
|
return ['#', hex[1], hex[1], hex[2], hex[2], hex[3], hex[3]].join('');
|
|
}
|
|
const rgb = str.match(/^(?:rgb)?\s*\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/);
|
|
if (rgb) {
|
|
// e.g. 'rgb(0, 128, 255)'
|
|
const r = Number(rgb[1]);
|
|
const g = Number(rgb[2]);
|
|
const b = Number(rgb[3]);
|
|
if (r >= 0 && r < 256 && g >= 0 && g < 256 && b >= 0 && b < 256) {
|
|
return rgbToHex(r, g, b);
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Converts a colour from RGB to hex representation.
|
|
*
|
|
* @param r Amount of red, int between 0 and 255.
|
|
* @param g Amount of green, int between 0 and 255.
|
|
* @param b Amount of blue, int between 0 and 255.
|
|
* @returns Hex representation of the colour.
|
|
*/
|
|
export function rgbToHex(r: number, g: number, b: number): string {
|
|
const rgb = (r << 16) | (g << 8) | b;
|
|
if (r < 0x10) {
|
|
return '#' + (0x1000000 | rgb).toString(16).substr(1);
|
|
}
|
|
return '#' + rgb.toString(16);
|
|
}
|
|
|
|
/**
|
|
* Converts a colour to RGB.
|
|
*
|
|
* @param colour String representing colour in any colour format ('#ff0000',
|
|
* 'red', '0xff000', etc).
|
|
* @returns RGB representation of the colour.
|
|
*/
|
|
export function hexToRgb(colour: string): number[] {
|
|
const hex = parse(colour);
|
|
if (!hex) {
|
|
return [0, 0, 0];
|
|
}
|
|
|
|
const rgb = parseInt(hex.substr(1), 16);
|
|
const r = rgb >> 16;
|
|
const g = (rgb >> 8) & 255;
|
|
const b = rgb & 255;
|
|
|
|
return [r, g, b];
|
|
}
|
|
|
|
/**
|
|
* Converts an HSV triplet to hex representation.
|
|
*
|
|
* @param h Hue value in [0, 360].
|
|
* @param s Saturation value in [0, 1].
|
|
* @param v Brightness in [0, 255].
|
|
* @returns Hex representation of the colour.
|
|
*/
|
|
export function hsvToHex(h: number, s: number, v: number): string {
|
|
let red = 0;
|
|
let green = 0;
|
|
let blue = 0;
|
|
if (s === 0) {
|
|
red = v;
|
|
green = v;
|
|
blue = v;
|
|
} else {
|
|
const sextant = Math.floor(h / 60);
|
|
const remainder = h / 60 - sextant;
|
|
const val1 = v * (1 - s);
|
|
const val2 = v * (1 - s * remainder);
|
|
const val3 = v * (1 - s * (1 - remainder));
|
|
switch (sextant) {
|
|
case 1:
|
|
red = val2;
|
|
green = v;
|
|
blue = val1;
|
|
break;
|
|
case 2:
|
|
red = val1;
|
|
green = v;
|
|
blue = val3;
|
|
break;
|
|
case 3:
|
|
red = val1;
|
|
green = val2;
|
|
blue = v;
|
|
break;
|
|
case 4:
|
|
red = val3;
|
|
green = val1;
|
|
blue = v;
|
|
break;
|
|
case 5:
|
|
red = v;
|
|
green = val1;
|
|
blue = val2;
|
|
break;
|
|
case 6:
|
|
case 0:
|
|
red = v;
|
|
green = val3;
|
|
blue = val1;
|
|
break;
|
|
}
|
|
}
|
|
return rgbToHex(Math.floor(red), Math.floor(green), Math.floor(blue));
|
|
}
|
|
|
|
/**
|
|
* Blend two colours together, using the specified factor to indicate the
|
|
* weight given to the first colour.
|
|
*
|
|
* @param colour1 First colour.
|
|
* @param colour2 Second colour.
|
|
* @param factor The weight to be given to colour1 over colour2.
|
|
* Values should be in the range [0, 1].
|
|
* @returns Combined colour represented in hex.
|
|
*/
|
|
export function blend(
|
|
colour1: string,
|
|
colour2: string,
|
|
factor: number,
|
|
): string | null {
|
|
const hex1 = parse(colour1);
|
|
if (!hex1) {
|
|
return null;
|
|
}
|
|
const hex2 = parse(colour2);
|
|
if (!hex2) {
|
|
return null;
|
|
}
|
|
const rgb1 = hexToRgb(hex1);
|
|
const rgb2 = hexToRgb(hex2);
|
|
const r = Math.round(rgb2[0] + factor * (rgb1[0] - rgb2[0]));
|
|
const g = Math.round(rgb2[1] + factor * (rgb1[1] - rgb2[1]));
|
|
const b = Math.round(rgb2[2] + factor * (rgb1[2] - rgb2[2]));
|
|
return rgbToHex(r, g, b);
|
|
}
|
|
|
|
/**
|
|
* A map that contains the 16 basic colour keywords as defined by W3C:
|
|
* https://www.w3.org/TR/2018/REC-css-color-3-20180619/#html4
|
|
* The keys of this map are the lowercase "readable" names of the colours,
|
|
* while the values are the "hex" values.
|
|
*/
|
|
export const names: {[key: string]: string} = {
|
|
'aqua': '#00ffff',
|
|
'black': '#000000',
|
|
'blue': '#0000ff',
|
|
'fuchsia': '#ff00ff',
|
|
'gray': '#808080',
|
|
'green': '#008000',
|
|
'lime': '#00ff00',
|
|
'maroon': '#800000',
|
|
'navy': '#000080',
|
|
'olive': '#808000',
|
|
'purple': '#800080',
|
|
'red': '#ff0000',
|
|
'silver': '#c0c0c0',
|
|
'teal': '#008080',
|
|
'white': '#ffffff',
|
|
'yellow': '#ffff00',
|
|
};
|
|
|
|
/**
|
|
* Convert a hue (HSV model) into an RGB hex triplet.
|
|
*
|
|
* @param hue Hue on a colour wheel (0-360).
|
|
* @returns RGB code, e.g. '#5ba65b'.
|
|
*/
|
|
export function hueToHex(hue: number): string {
|
|
return hsvToHex(hue, hsvSaturation, hsvValue * 255);
|
|
}
|