Home Reference Source Repository

js/SpriteKit/SKColor.js

  1. 'use strict'
  2.  
  3. import NSObject from '../ObjectiveC/NSObject'
  4. //import NSColorSpaceModel from '../AppKit/NSColorSpaceModel'
  5.  
  6. /**
  7. * An object that stores color data and sometimes opacity (that is, alpha value).
  8. * @access public
  9. * @extends {NSObject}
  10. * @see https://developer.apple.com/documentation/uikit/uicolor
  11. */
  12. export default class SKColor extends NSObject {
  13. static get _propTypes() {
  14. return {
  15. $constructor: (propNames, propValues) => {
  16. if(typeof propValues.NSColorSpace !== 'undefined'){
  17. // initialize for NSColor
  18. /*
  19. const buf = propValues.NSRGB || propValues.NSWhite
  20. const ascii = buf.toString('ascii')
  21. const values = ascii.split(' ')
  22. const space = propValues.NSColorSpace - 1
  23. switch(space){
  24. case NSColorSpaceModel.gray:
  25. break
  26. case NSColorSpaceModel.RGB: {
  27. const r = parseFloat(values[0])
  28. const g = parseFloat(values[1])
  29. const b = parseFloat(values[2])
  30. const a = 1.0
  31. console.log(`NSColor -> SKColor: r:${r} g:${g} b:${b} a:${a}`)
  32. return new SKColor(r, g, b, a)
  33. }
  34. case NSColorSpaceModel.CMYK:
  35. if(propValues.NSWhite){
  36. const w = parseFloat(values[0])
  37. return new SKColor(w, w, w, 1.0)
  38. }
  39. break
  40. case NSColorSpaceModel.LAB:
  41. break
  42. case NSColorSpaceModel.deviceN:
  43. break
  44. case NSColorSpaceModel.indexed:
  45. break
  46. case NSColorSpaceModel.patterned:
  47. break
  48. }
  49. console.error(`unknown color space: ${propValues.NSColorSpace}`)
  50. throw new Error(`unknown color space: ${propValues.NSColorSpace}`)
  51. */
  52. if(typeof propValues.NSRGB !== 'undefined'){
  53. const ascii = propValues.NSRGB.toString('ascii')
  54. const values = ascii.split(' ')
  55. const r = parseFloat(values[0])
  56. const g = parseFloat(values[1])
  57. const b = parseFloat(values[2])
  58. const a = 1.0
  59. //console.log(`NSColor -> SKColor NSRGB: r:${r} g:${g} b:${b} a:${a}`)
  60. //if(propValues.NSColorSpace === 1){
  61. // return new SKColor(1, 1, 1, 1)
  62. //}
  63. return new SKColor(r, g, b, a)
  64. }else if(typeof propValues.NSWhite !== 'undefined'){
  65. const ascii = propValues.NSWhite.toString('ascii')
  66. const values = ascii.split(' ')
  67. const w = parseFloat(values[0])
  68. const a = 1.0
  69. //console.log(`NSColor -> SKColor NSWhite: r:${w} g:${w} b:${w} a:${a}`)
  70. return new SKColor(w, w, w, a)
  71. }
  72.  
  73. console.error('unknown color space')
  74. throw new Error('unknown color space')
  75. }
  76.  
  77. // TODO: implement
  78. return new SKColor()
  79. },
  80. // for NSColor
  81. NSRGB: ['bytes', null],
  82. NSWhite: ['bytes', null],
  83. NSComponents: ['bytes', null],
  84. NSColorSpace: ['integer', null],
  85. NSCustomColorSpace: ['NSColorSpace', null]
  86. }
  87. }
  88.  
  89. /**
  90. * @access private
  91. * @param {Buffer} data -
  92. * @param {number} [offset = 0] -
  93. * @param {boolean} [bigEndian = false] -
  94. * @returns {SKColor}
  95. */
  96. static _initWithData(data, offset = 0, bigEndian = false) {
  97. const instance = new SKColor()
  98. if(bigEndian){
  99. instance.red = data.readFloatBE(offset + 0)
  100. instance.green = data.readFloatBE(offset + 4)
  101. instance.blue = data.readFloatBE(offset + 8)
  102. instance.alpha = data.readFloatBE(offset + 12)
  103. }else{
  104. instance.red = data.readFloatLE(offset + 0)
  105. instance.green = data.readFloatLE(offset + 4)
  106. instance.blue = data.readFloatLE(offset + 8)
  107. instance.alpha = data.readFloatLE(offset + 12)
  108. }
  109. return instance
  110. }
  111.  
  112. // Initializers
  113.  
  114. /**
  115. *
  116. * @access public
  117. * @constructor
  118. * @param {number} red -
  119. * @param {number} green -
  120. * @param {number} blue -
  121. * @param {number} alpha -
  122. * @see https://developer.apple.com/documentation/uikit/uicolor/1625015-init
  123. */
  124. constructor(red, green, blue, alpha) {
  125. super()
  126.  
  127. /**
  128. * @type {number}
  129. */
  130. this.red = red
  131.  
  132. /**
  133. * @type {number}
  134. */
  135. this.green = green
  136.  
  137. /**
  138. * @type {number}
  139. */
  140. this.blue = blue
  141.  
  142. /**
  143. * @type {number}
  144. */
  145. this.alpha = alpha
  146. }
  147.  
  148. // Creating a Color Object with a Predefined Color
  149.  
  150. /**
  151. * A color object in the sRGB color space whose grayscale value is 0.0 and whose alpha value is 1.0.
  152. * @type {SKColor}
  153. * @desc
  154. * @see https://developer.apple.com/documentation/uikit/uicolor/1621929-black
  155. */
  156. static get black() {
  157. return new SKColor(0.0, 0.0, 0.0, 1.0)
  158. }
  159.  
  160. /**
  161. * A color object whose RGB values are 0.0, 0.0, and 1.0 and whose alpha value is 1.0.
  162. * @type {SKColor}
  163. * @desc
  164. * @see https://developer.apple.com/documentation/uikit/uicolor/1621947-blue
  165. */
  166. static get blue() {
  167. return new SKColor(0.0, 0.0, 1.0, 1.0)
  168. }
  169.  
  170. /**
  171. * A color object whose RGB values are 0.6, 0.4, and 0.2 and whose alpha value is 1.0.
  172. * @type {SKColor}
  173. * @desc
  174. * @see https://developer.apple.com/documentation/uikit/uicolor/1621950-brown
  175. */
  176. static get brown() {
  177. return new SKColor(0.6, 0.4, 0.2, 1.0)
  178. }
  179.  
  180. /**
  181. * A color object whose grayscale and alpha values are both 0.0.
  182. * @type {SKColor}
  183. * @desc
  184. * @see https://developer.apple.com/documentation/uikit/uicolor/1621945-clear
  185. */
  186. static get clear() {
  187. return new SKColor(0.0, 0.0, 0.0, 0.0)
  188. }
  189.  
  190. /**
  191. * A color object whose RGB values are 0.0, 1.0, and 1.0 and whose alpha value is 1.0.
  192. * @type {SKColor}
  193. * @desc
  194. * @see https://developer.apple.com/documentation/uikit/uicolor/1621942-cyan
  195. */
  196. static get cyan() {
  197. return new SKColor(0.0, 1.0, 1.0, 1.0)
  198. }
  199.  
  200. /**
  201. * A color object whose grayscale value is 1/3 and whose alpha value is 1.0.
  202. * @type {SKColor}
  203. * @desc
  204. * @see https://developer.apple.com/documentation/uikit/uicolor/1621952-darkgray
  205. */
  206. static get darkGray() {
  207. const third = 1.0 / 3.0
  208. return new SKColor(third, third, third, 1.0)
  209. }
  210.  
  211. /**
  212. * A color object whose grayscale value is 0.5 and whose alpha value is 1.0.
  213. * @type {SKColor}
  214. * @desc
  215. * @see https://developer.apple.com/documentation/uikit/uicolor/1621941-gray
  216. */
  217. static get gray() {
  218. return new SKColor(0.5, 0.5, 0.5, 1.0)
  219. }
  220.  
  221. /**
  222. * A color object whose RGB values are 0.0, 1.0, and 0.0 and whose alpha value is 1.0.
  223. * @type {SKColor}
  224. * @desc
  225. * @see https://developer.apple.com/documentation/uikit/uicolor/1621946-green
  226. */
  227. static get green() {
  228. return new SKColor(0.0, 1.0, 0.0, 1.0)
  229. }
  230.  
  231. /**
  232. * A color object whose grayscale value is 2/3 and whose alpha value is 1.0.
  233. * @type {SKColor}
  234. * @desc
  235. * @see https://developer.apple.com/documentation/uikit/uicolor/1621932-lightgray
  236. */
  237. static get lightGray() {
  238. const twoThirds = 2.0 / 3.0
  239. return new SKColor(twoThirds, twoThirds, twoThirds, 1.0)
  240. }
  241.  
  242. /**
  243. * A color object whose RGB values are 1.0, 0.0, and 1.0 and whose alpha value is 1.0.
  244. * @type {SKColor}
  245. * @desc
  246. * @see https://developer.apple.com/documentation/uikit/uicolor/1621934-magenta
  247. */
  248. static get magenta() {
  249. return new SKColor(1.0, 0.0, 1.0, 1.0)
  250. }
  251.  
  252. /**
  253. * A color object whose RGB values are 1.0, 0.5, and 0.0 and whose alpha value is 1.0.
  254. * @type {SKColor}
  255. * @desc
  256. * @see https://developer.apple.com/documentation/uikit/uicolor/1621956-orange
  257. */
  258. static get orange() {
  259. return new SKColor(1.0, 0.5, 0.0, 1.0)
  260. }
  261.  
  262. /**
  263. * A color object whose RGB values are 0.5, 0.0, and 0.5 and whose alpha value is 1.0.
  264. * @type {SKColor}
  265. * @desc
  266. * @see https://developer.apple.com/documentation/uikit/uicolor/1621923-purple
  267. */
  268. static get purple() {
  269. return new SKColor(0.5, 0.0, 0.5, 1.0)
  270. }
  271. /**
  272. * A color object whose RGB values are 1.0, 0.0, and 0.0 and whose alpha value is 1.0.
  273. * @type {SKColor}
  274. * @desc
  275. * @see https://developer.apple.com/documentation/uikit/uicolor/1621924-red
  276. */
  277. static get red() {
  278. return new SKColor(1.0, 0.0, 0.0, 1.0)
  279. }
  280.  
  281. /**
  282. * A color object whose grayscale value is 1.0 and whose alpha value is 1.0.
  283. * @type {SKColor}
  284. * @desc
  285. * @see https://developer.apple.com/documentation/uikit/uicolor/1621920-white
  286. */
  287. static get white() {
  288. return new SKColor(1.0, 1.0, 1.0, 1.0)
  289. }
  290.  
  291. /**
  292. * A color object whose RGB values are 1.0, 1.0, and 0.0 and whose alpha value is 1.0.
  293. * @type {SKColor}
  294. * @desc
  295. * @see https://developer.apple.com/documentation/uikit/uicolor/1621953-yellow
  296. */
  297. static get yellow() {
  298. return new SKColor(1.0, 1.0, 0.0, 1.0)
  299. }
  300.  
  301. // Creating a Custom UIColor Object in a Specific Color Space
  302.  
  303. /**
  304. * Initializes and returns a color object using the specified opacity and grayscale values.
  305. * @access public
  306. * @param {number} white - The grayscale value of the color object. On applications linked for iOS 10 or later, the color is specified in an extended color space, and the input value is never clamped. On earlier versions of iOS, white values below 0.0 are interpreted as 0.0, and values above 1.0 are interpreted as 1.0.
  307. * @param {number} alpha - The opacity value of the color object, specified as a value from 0.0 to 1.0. Alpha values below 0.0 are interpreted as 0.0, and values above 1.0 are interpreted as 1.0
  308. * @returns {void}
  309. * @desc On applications linked on iOS 10 or later, the input parameters are not clamped. On earlier versions of iOS, values below 0.0 are interpreted as 0.0, and values above 1.0 are interpreted as 1.0.
  310. * @see https://developer.apple.com/documentation/uikit/uicolor/1621944-init
  311. */
  312. //init(white, alpha) {
  313. //}
  314.  
  315. // Creating a UIColor Object from another Representation of Color
  316.  
  317. /**
  318. * Creates and returns a color object that has the same color space and component values as the receiver, but has the specified alpha component.
  319. * @access public
  320. * @param {number} alpha - The opacity value of the new color object, specified as a value from 0.0 to 1.0. Alpha values below 0.0 are interpreted as 0.0, and values above 1.0 are interpreted as 1.0
  321. * @returns {SKColor} -
  322. * @desc A subclass with explicit opacity components should override this method to return a color with the specified alpha.
  323. * @see https://developer.apple.com/documentation/uikit/uicolor/1621922-withalphacomponent
  324. */
  325. withAlphaComponent(alpha) {
  326. return new SKColor(this.red, this.green, this.blue, alpha)
  327. }
  328.  
  329. // Creating a UIColor Object that Draws Using a Pattern
  330.  
  331. /**
  332. * Initializes and returns a color object using the specified Quartz color reference.
  333. * @access public
  334. * @param {Image} image - The image to use when creating the pattern color.
  335. * @returns {void}
  336. * @desc You can use pattern colors to set the fill or stroke color just as you would a solid color. During drawing, the image in the pattern color is tiled as necessary to cover the given area. By default, the phase of the returned color is 0, which causes the top-left corner of the image to be aligned with the drawing origin. To change the phase, make the color the current color and then use the setPatternPhase(_:) function to change the phase.
  337. * @see https://developer.apple.com/documentation/uikit/uicolor/1621933-init
  338. */
  339. initPatternImage(image) {
  340. }
  341.  
  342. // Setting the Graphics Context’s Drawing Color
  343.  
  344. /**
  345. * Sets the color of subsequent stroke and fill operations to the color that the receiver represents.
  346. * @access public
  347. * @returns {void}
  348. * @desc If you subclass UIColor, you must implement this method in your subclass. Your custom implementation should modify both the stroke and fill color in the current graphics context by setting them both to the color represented by the receiver.
  349. * @see https://developer.apple.com/documentation/uikit/uicolor/1621928-set
  350. */
  351. set() {
  352. }
  353.  
  354. /**
  355. * Sets the color of subsequent fill operations to the color that the receiver represents.
  356. * @access public
  357. * @returns {void}
  358. * @desc If you subclass UIColor, you must implement this method in your subclass. Your custom implementation should modify the fill color in the current graphics context by setting it to the color represented by the receiver.
  359. * @see https://developer.apple.com/documentation/uikit/uicolor/1621926-setfill
  360. */
  361. setFill() {
  362. }
  363.  
  364. /**
  365. * Sets the color of subsequent stroke operations to the color that the receiver represents.
  366. * @access public
  367. * @returns {void}
  368. * @desc If you subclass UIColor, you must implement this method in your subclass. Your custom implementation should modify the stroke color in the current graphics context by setting it to the color represented by the receiver.
  369. * @see https://developer.apple.com/documentation/uikit/uicolor/1621948-setstroke
  370. */
  371. setStroke() {
  372. }
  373.  
  374. // Retrieving Color Information
  375.  
  376. /**
  377. * Returns the components that make up the color in the HSB color space.
  378. * @access public
  379. * @returns {Object} -
  380. * @property {number} color.hue - On return, the hue component of the color object. On applications linked for iOS 10 or later, the hue component is specified in an extended range color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  381. * @property {number} color.saturation - On return, the saturation component of the color object. On applications linked for iOS 10 or later, the saturation component is specified in an extended range color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  382. * @property {number} color.brightness - On return, the brightness component of the color object. On applications linked for iOS 10 or later, the brightness component is specified in an extended range color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  383. * @property {number} color.alpha - On return, the opacity component of the color object, specified as a value between 0.0 and 1.0.
  384. * @desc If the color is in a compatible color space, the color is converted into the HSB color space and its components are returned to your application. If the color is not in a compatible color space, the parameters are unchanged.
  385. * @see https://developer.apple.com/documentation/uikit/uicolor/1621949-gethue
  386. */
  387. getHSBA() {
  388. // TODO: implement
  389. const color = {
  390. hue: 0,
  391. saturation: 0,
  392. brightness: 0,
  393. alpha: 0
  394. }
  395. return color
  396. }
  397.  
  398. /**
  399. * Returns the components that make up the color in the RGB color space.
  400. * @access public
  401. * @param {number} red -
  402. * @param {number} green -
  403. * @param {number} blue -
  404. * @param {number} alpha -
  405. * @returns {Object} -
  406. * @property {number} color.red - On return, the red component of the color object. On applications linked for iOS 10 or later, the red component is specified in an extended range sRGB color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  407. * @property {number} color.green - On return, the green component of the color object. On applications linked for iOS 10 or later, the green component is specified in an extended range sRGB color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  408. * @property {number} color.blue - On return, the blue component of the color object. On applications linked for iOS 10 or later, the blue component is specified in an extended range sRGB color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  409. * @property {number} color.alpha - On return, the opacity component of the color object, specified as a value between 0.0 and 1.0.
  410. * @desc If the color is in a compatible color space, the color is converted into RGB format and its components are returned to your application. If the color is not in a compatible color space, the parameters are unchanged.
  411. * @see https://developer.apple.com/documentation/uikit/uicolor/1621919-getred
  412. */
  413. getRGBA(red, green, blue, alpha) {
  414. const color = {
  415. red: this.red,
  416. green: this.green,
  417. blue: this.blue,
  418. alpha: this.alpha
  419. }
  420. return color
  421. }
  422.  
  423. /**
  424. * Returns the grayscale components of the color.
  425. * @access public
  426. * @param {?UnsafeMutablePointer<CGFloat>} white - On return, the grayscale component of the color object. On applications linked for iOS 10 or later, the grayscale component is specified in an extended range gray color space and can have any value. Values between 0.0 and 1.0 are inside the sRGB color gamut. On earlier versions of iOS, the specified value is always between 0.0 and 1.0.
  427. * @param {?UnsafeMutablePointer<CGFloat>} alpha - On return, the opacity component of the color object, specified as a value between 0.0 and 1.0.
  428. * @returns {boolean} -
  429. * @desc If the color is in a compatible color space, the color is converted into grayscale format and returned to your application. If the color is not in a compatible color space, the parameters are unchanged.
  430. * @see https://developer.apple.com/documentation/uikit/uicolor/1621927-getwhite
  431. */
  432. //getWhite(white, alpha) {
  433. // return false
  434. //}
  435.  
  436. /**
  437. * HTML color representation
  438. * @access public
  439. * @type {string}
  440. */
  441. get htmlColor() {
  442. const r = Math.round(this.red * 255)
  443. const g = Math.round(this.green * 255)
  444. const b = Math.round(this.blue * 255)
  445. return `rgba(${r}, ${g}, ${b}, ${this.alpha})`
  446. }
  447.  
  448. /**
  449. * HTML color representation
  450. * @access public
  451. * @type {string}
  452. */
  453. get hexColor() {
  454. const r = Math.round(this.red * 255).toString(16)
  455. const g = Math.round(this.green * 255).toString(16)
  456. const b = Math.round(this.blue * 255).toString(16)
  457. return `#${r}${g}${b}`
  458. }
  459.  
  460. /**
  461. * @access private
  462. * @returns {SKColor} -
  463. */
  464. _copy() {
  465. return new SKColor(this.red, this.green, this.blue, this.alpha)
  466. }
  467.  
  468. /**
  469. * @access private
  470. * @param {SKColor} c -
  471. * @param {number} rate -
  472. * @returns {SKColor} -
  473. */
  474. _lerp(c, rate) {
  475. const r = new SKColor()
  476. r.red = this.red + rate * (c.red - this.red)
  477. r.green = this.green + rate * (c.green - this.green)
  478. r.blue = this.blue + rate * (c.blue - this.blue)
  479. r.alpha = this.alpha + rate * (c.alpha - this.alpha)
  480. return r
  481. }
  482.  
  483. zero() {
  484. return new SKColor(0, 0, 0, 0)
  485. }
  486.  
  487. /**
  488. * @access public
  489. * @param {SKColor} c -
  490. * @returns {SKColor} -
  491. */
  492. add(c) {
  493. const r = new SKColor()
  494. r.red = this.red + c.red
  495. r.green = this.green + c.green
  496. r.blue = this.blue + c.blue
  497. r.alpha = this.alpha + c.alpha
  498. return r
  499. }
  500.  
  501. /**
  502. * @access public
  503. * @param {SKColor} c -
  504. * @returns {SKColor} -
  505. */
  506. sub(c) {
  507. const r = new SKColor()
  508. r.red = this.red - c.red
  509. r.green = this.green - c.green
  510. r.blue = this.blue - c.blue
  511. r.alpha = this.alpha - c.alpha
  512. return r
  513. }
  514.  
  515. /**
  516. * @access private
  517. * @param {number} val -
  518. * @returns {number} -
  519. */
  520. _srgbToLinear(val) {
  521. if(val <= 0.04045){
  522. return val / 12.92
  523. }
  524. return Math.pow((val + 0.055) / 1.055, 2.4)
  525. }
  526.  
  527. /**
  528. * @access private
  529. * @param {number} val -
  530. * @returns {number} -
  531. */
  532. _linearToSrgb(val) {
  533. if(val <= 0.0031308){
  534. return val * 12.92
  535. }
  536. return 1.055 * Math.pow(val, 1.0 / 2.4)
  537. }
  538.  
  539. /**
  540. * @access public
  541. * @returns {SKColor} -
  542. */
  543. srgbToLinear() {
  544. const r = new SKColor()
  545. r.red = this._srgbToLinear(this.red)
  546. r.green = this._srgbToLinear(this.green)
  547. r.blue = this._srgbToLinear(this.blue)
  548. r.alpha = this.alpha
  549. return r
  550. }
  551.  
  552. /**
  553. * @access public
  554. * @returns {SKColor} -
  555. */
  556. linearToSrgb() {
  557. const r = new SKColor()
  558. r.red = this._linearToSrgb(this.red)
  559. r.green = this._linearToSrgb(this.green)
  560. r.blue = this._linearToSrgb(this.blue)
  561. r.alpha = this.alpha
  562. return r
  563. }
  564.  
  565. /**
  566. * @access public
  567. * @returns {number[]} -
  568. */
  569. floatArray() {
  570. return [this.red, this.green, this.blue, this.alpha]
  571. }
  572.  
  573. /**
  574. * @access public
  575. * @returns {Float32Array} -
  576. */
  577. float32Array() {
  578. return new Float32Array([this.red, this.green, this.blue, this.alpha])
  579. }
  580. }