jquery.jscolor.js 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857
  1. var jscolor = {
  2. dir: ROOT_PATH + '/static/images/jscolor/',
  3. bindClass: 'color',
  4. binding: true,
  5. preloading: true,
  6. install: function() {
  7. jscolor.addEvent(window, 'load', jscolor.init)
  8. },
  9. init: function() {
  10. if (jscolor.binding) {
  11. jscolor.bind()
  12. }
  13. if (jscolor.preloading) {
  14. jscolor.preload()
  15. }
  16. },
  17. getDir: function() {
  18. if (!jscolor.dir) {
  19. var detected = jscolor.detectDir();
  20. jscolor.dir = detected !== false ? detected: 'jscolor/'
  21. }
  22. return jscolor.dir
  23. },
  24. detectDir: function() {
  25. var base = location.href;
  26. var e = document.getElementsByTagName('base');
  27. for (var i = 0; i < e.length; i += 1) {
  28. if (e[i].href) {
  29. base = e[i].href
  30. }
  31. }
  32. var e = document.getElementsByTagName('script');
  33. for (var i = 0; i < e.length; i += 1) {
  34. if (e[i].src && /(^|\/)jscolor\.js([?#].*)?$/i.test(e[i].src)) {
  35. var src = new jscolor.URI(e[i].src);
  36. var srcAbs = src.toAbsolute(base);
  37. srcAbs.path = srcAbs.path.replace(/[^\/]+$/, '');
  38. srcAbs.query = null;
  39. srcAbs.fragment = null;
  40. return srcAbs.toString()
  41. }
  42. }
  43. return false
  44. },
  45. bind: function() {
  46. var matchClass = new RegExp('(^|\\s)(' + jscolor.bindClass + ')\\s*(\\{[^}]*\\})?', 'i');
  47. var e = document.getElementsByTagName('input');
  48. for (var i = 0; i < e.length; i += 1) {
  49. var m;
  50. if (!e[i].color && e[i].className && (m = e[i].className.match(matchClass))) {
  51. var prop = {};
  52. if (m[3]) {
  53. try {
  54. prop = (new Function('return (' + m[3] + ')'))()
  55. } catch(eInvalidProp) {}
  56. }
  57. e[i].color = new jscolor.color(e[i], prop)
  58. }
  59. }
  60. },
  61. preload: function() {
  62. for (var fn in jscolor.imgRequire) {
  63. if (jscolor.imgRequire.hasOwnProperty(fn)) {
  64. jscolor.loadImage(fn)
  65. }
  66. }
  67. },
  68. images: {
  69. pad: [181, 101],
  70. sld: [16, 101],
  71. cross: [15, 15],
  72. arrow: [7, 11]
  73. },
  74. imgRequire: {},
  75. imgLoaded: {},
  76. requireImage: function(filename) {
  77. jscolor.imgRequire[filename] = true
  78. },
  79. loadImage: function(filename) {
  80. if (!jscolor.imgLoaded[filename]) {
  81. jscolor.imgLoaded[filename] = new Image();
  82. jscolor.imgLoaded[filename].src = jscolor.getDir() + filename
  83. }
  84. },
  85. fetchElement: function(mixed) {
  86. return typeof mixed === 'string' ? document.getElementById(mixed) : mixed
  87. },
  88. addEvent: function(el, evnt, func) {
  89. if (el.addEventListener) {
  90. el.addEventListener(evnt, func, false)
  91. } else if (el.attachEvent) {
  92. el.attachEvent('on' + evnt, func)
  93. }
  94. },
  95. fireEvent: function(el, evnt) {
  96. if (!el) {
  97. return
  98. }
  99. if (document.createEvent) {
  100. var ev = document.createEvent('HTMLEvents');
  101. ev.initEvent(evnt, true, true);
  102. el.dispatchEvent(ev)
  103. } else if (document.createEventObject) {
  104. var ev = document.createEventObject();
  105. el.fireEvent('on' + evnt, ev)
  106. } else if (el['on' + evnt]) {
  107. el['on' + evnt]()
  108. }
  109. },
  110. getElementPos: function(e) {
  111. var e1 = e,
  112. e2 = e;
  113. var x = 0,
  114. y = 0;
  115. if (e1.offsetParent) {
  116. do {
  117. x += e1.offsetLeft;
  118. y += e1.offsetTop
  119. }
  120. while (e1 = e1.offsetParent)
  121. }
  122. while ((e2 = e2.parentNode) && e2.nodeName.toUpperCase() !== 'BODY') {
  123. x -= e2.scrollLeft;
  124. y -= e2.scrollTop
  125. }
  126. return [x, y]
  127. },
  128. getElementSize: function(e) {
  129. return [e.offsetWidth, e.offsetHeight]
  130. },
  131. getRelMousePos: function(e) {
  132. var x = 0,
  133. y = 0;
  134. if (!e) {
  135. e = window.event
  136. }
  137. if (typeof e.offsetX === 'number') {
  138. x = e.offsetX;
  139. y = e.offsetY
  140. } else if (typeof e.layerX === 'number') {
  141. x = e.layerX;
  142. y = e.layerY
  143. }
  144. return {
  145. x: x,
  146. y: y
  147. }
  148. },
  149. getViewPos: function() {
  150. if (typeof window.pageYOffset === 'number') {
  151. return [window.pageXOffset, window.pageYOffset]
  152. } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
  153. return [document.body.scrollLeft, document.body.scrollTop]
  154. } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
  155. return [document.documentElement.scrollLeft, document.documentElement.scrollTop]
  156. } else {
  157. return [0, 0]
  158. }
  159. },
  160. getViewSize: function() {
  161. if (typeof window.innerWidth === 'number') {
  162. return [window.innerWidth, window.innerHeight]
  163. } else if (document.body && (document.body.clientWidth || document.body.clientHeight)) {
  164. return [document.body.clientWidth, document.body.clientHeight]
  165. } else if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
  166. return [document.documentElement.clientWidth, document.documentElement.clientHeight]
  167. } else {
  168. return [0, 0]
  169. }
  170. },
  171. URI: function(uri) {
  172. this.scheme = null;
  173. this.authority = null;
  174. this.path = '';
  175. this.query = null;
  176. this.fragment = null;
  177. this.parse = function(uri) {
  178. var m = uri.match(/^(([A-Za-z][0-9A-Za-z+.-]*)(:))?((\/\/)([^\/?#]*))?([^?#]*)((\?)([^#]*))?((#)(.*))?/);
  179. this.scheme = m[3] ? m[2] : null;
  180. this.authority = m[5] ? m[6] : null;
  181. this.path = m[7];
  182. this.query = m[9] ? m[10] : null;
  183. this.fragment = m[12] ? m[13] : null;
  184. return this
  185. };
  186. this.toString = function() {
  187. var result = '';
  188. if (this.scheme !== null) {
  189. result = result + this.scheme + ':'
  190. }
  191. if (this.authority !== null) {
  192. result = result + '//' + this.authority
  193. }
  194. if (this.path !== null) {
  195. result = result + this.path
  196. }
  197. if (this.query !== null) {
  198. result = result + '?' + this.query
  199. }
  200. if (this.fragment !== null) {
  201. result = result + '#' + this.fragment
  202. }
  203. return result
  204. };
  205. this.toAbsolute = function(base) {
  206. var base = new jscolor.URI(base);
  207. var r = this;
  208. var t = new jscolor.URI;
  209. if (base.scheme === null) {
  210. return false
  211. }
  212. if (r.scheme !== null && r.scheme.toLowerCase() === base.scheme.toLowerCase()) {
  213. r.scheme = null
  214. }
  215. if (r.scheme !== null) {
  216. t.scheme = r.scheme;
  217. t.authority = r.authority;
  218. t.path = removeDotSegments(r.path);
  219. t.query = r.query
  220. } else {
  221. if (r.authority !== null) {
  222. t.authority = r.authority;
  223. t.path = removeDotSegments(r.path);
  224. t.query = r.query
  225. } else {
  226. if (r.path === '') {
  227. t.path = base.path;
  228. if (r.query !== null) {
  229. t.query = r.query
  230. } else {
  231. t.query = base.query
  232. }
  233. } else {
  234. if (r.path.substr(0, 1) === '/') {
  235. t.path = removeDotSegments(r.path)
  236. } else {
  237. if (base.authority !== null && base.path === '') {
  238. t.path = '/' + r.path
  239. } else {
  240. t.path = base.path.replace(/[^\/]+$/, '') + r.path
  241. }
  242. t.path = removeDotSegments(t.path)
  243. }
  244. t.query = r.query
  245. }
  246. t.authority = base.authority
  247. }
  248. t.scheme = base.scheme
  249. }
  250. t.fragment = r.fragment;
  251. return t
  252. };
  253. function removeDotSegments(path) {
  254. var out = '';
  255. while (path) {
  256. if (path.substr(0, 3) === '../' || path.substr(0, 2) === './') {
  257. path = path.replace(/^\.+/, '').substr(1)
  258. } else if (path.substr(0, 3) === '/./' || path === '/.') {
  259. path = '/' + path.substr(3)
  260. } else if (path.substr(0, 4) === '/../' || path === '/..') {
  261. path = '/' + path.substr(4);
  262. out = out.replace(/\/?[^\/]*$/, '')
  263. } else if (path === '.' || path === '..') {
  264. path = ''
  265. } else {
  266. var rm = path.match(/^\/?[^\/]*/)[0];
  267. path = path.substr(rm.length);
  268. out = out + rm
  269. }
  270. }
  271. return out
  272. }
  273. if (uri) {
  274. this.parse(uri)
  275. }
  276. },
  277. color: function(target, prop) {
  278. this.required = true;
  279. this.adjust = true;
  280. this.hash = false;
  281. this.caps = true;
  282. this.slider = true;
  283. this.valueElement = target;
  284. this.styleElement = target;
  285. this.onImmediateChange = null;
  286. this.hsv = [0, 0, 1];
  287. this.rgb = [1, 1, 1];
  288. this.minH = 0;
  289. this.maxH = 6;
  290. this.minS = 0;
  291. this.maxS = 1;
  292. this.minV = 0;
  293. this.maxV = 1;
  294. this.pickerOnfocus = true;
  295. this.pickerMode = 'HSV';
  296. this.pickerPosition = 'bottom';
  297. this.pickerSmartPosition = true;
  298. this.pickerButtonHeight = 20;
  299. this.pickerClosable = false;
  300. this.pickerCloseText = 'Close';
  301. this.pickerButtonColor = 'ButtonText';
  302. this.pickerFace = 10;
  303. this.pickerFaceColor = 'ThreeDFace';
  304. this.pickerBorder = 1;
  305. this.pickerBorderColor = 'ThreeDHighlight ThreeDShadow ThreeDShadow ThreeDHighlight';
  306. this.pickerInset = 1;
  307. this.pickerInsetColor = 'ThreeDShadow ThreeDHighlight ThreeDHighlight ThreeDShadow';
  308. this.pickerZIndex = 10000;
  309. for (var p in prop) {
  310. if (prop.hasOwnProperty(p)) {
  311. this[p] = prop[p]
  312. }
  313. }
  314. this.hidePicker = function() {
  315. if (isPickerOwner()) {
  316. removePicker()
  317. }
  318. };
  319. this.showPicker = function() {
  320. if (!isPickerOwner()) {
  321. var tp = jscolor.getElementPos(target);
  322. var ts = jscolor.getElementSize(target);
  323. var vp = jscolor.getViewPos();
  324. var vs = jscolor.getViewSize();
  325. var ps = getPickerDims(this);
  326. var a,
  327. b,
  328. c;
  329. switch (this.pickerPosition.toLowerCase()) {
  330. case 'left':
  331. a = 1;
  332. b = 0;
  333. c = -1;
  334. break;
  335. case 'right':
  336. a = 1;
  337. b = 0;
  338. c = 1;
  339. break;
  340. case 'top':
  341. a = 0;
  342. b = 1;
  343. c = -1;
  344. break;
  345. default:
  346. a = 0;
  347. b = 1;
  348. c = 1;
  349. break
  350. }
  351. var l = (ts[b] + ps[b]) / 2;
  352. if (!this.pickerSmartPosition) {
  353. var pp = [tp[a], tp[b] + ts[b] - l + l * c]
  354. } else {
  355. var pp = [ - vp[a] + tp[a] + ps[a] > vs[a] ? ( - vp[a] + tp[a] + ts[a] / 2 > vs[a] / 2 && tp[a] + ts[a] - ps[a] >= 0 ? tp[a] + ts[a] - ps[a] : tp[a]) : tp[a], -vp[b] + tp[b] + ts[b] + ps[b] - l + l * c > vs[b] ? ( - vp[b] + tp[b] + ts[b] / 2 > vs[b] / 2 && tp[b] + ts[b] - l - l * c >= 0 ? tp[b] + ts[b] - l - l * c: tp[b] + ts[b] - l + l * c) : (tp[b] + ts[b] - l + l * c >= 0 ? tp[b] + ts[b] - l + l * c: tp[b] + ts[b] - l - l * c)]
  356. }
  357. drawPicker(pp[a], pp[b])
  358. }
  359. };
  360. this.importColor = function() {
  361. if (!valueElement) {
  362. this.exportColor()
  363. } else {
  364. if (!this.adjust) {
  365. if (!this.fromString(valueElement.value, leaveValue)) {
  366. styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
  367. styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
  368. styleElement.style.color = styleElement.jscStyle.color;
  369. this.exportColor(leaveValue | leaveStyle)
  370. }
  371. } else if (!this.required && /^\s*$/.test(valueElement.value)) {
  372. valueElement.value = '';
  373. styleElement.style.backgroundImage = styleElement.jscStyle.backgroundImage;
  374. styleElement.style.backgroundColor = styleElement.jscStyle.backgroundColor;
  375. styleElement.style.color = styleElement.jscStyle.color;
  376. this.exportColor(leaveValue | leaveStyle)
  377. } else if (this.fromString(valueElement.value)) {} else {
  378. this.exportColor()
  379. }
  380. }
  381. };
  382. this.exportColor = function(flags) {
  383. if (! (flags & leaveValue) && valueElement) {
  384. var value = this.toString();
  385. if (value == "ffffff") {
  386. value = ""
  387. }
  388. if (this.caps) {
  389. value = value.toUpperCase()
  390. }
  391. if (this.hash) {
  392. value = '#' + value
  393. }
  394. valueElement.value = value
  395. }
  396. if (! (flags & leaveStyle) && styleElement) {
  397. styleElement.style.backgroundImage = "none";
  398. styleElement.style.backgroundColor = '#' + this.toString();
  399. styleElement.style.color = 0.213 * this.rgb[0] + 0.715 * this.rgb[1] + 0.072 * this.rgb[2] < 0.5 ? '#FFF': '#000'
  400. }
  401. if (! (flags & leavePad) && isPickerOwner()) {
  402. redrawPad()
  403. }
  404. if (! (flags & leaveSld) && isPickerOwner()) {
  405. redrawSld()
  406. }
  407. };
  408. this.fromHSV = function(h, s, v, flags) {
  409. if (h !== null) {
  410. h = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, h))
  411. }
  412. if (s !== null) {
  413. s = Math.max(0.0, this.minS, Math.min(1.0, this.maxS, s))
  414. }
  415. if (v !== null) {
  416. v = Math.max(0.0, this.minV, Math.min(1.0, this.maxV, v))
  417. }
  418. this.rgb = HSV_RGB(h === null ? this.hsv[0] : (this.hsv[0] = h), s === null ? this.hsv[1] : (this.hsv[1] = s), v === null ? this.hsv[2] : (this.hsv[2] = v));
  419. this.exportColor(flags)
  420. };
  421. this.fromRGB = function(r, g, b, flags) {
  422. if (r !== null) {
  423. r = Math.max(0.0, Math.min(1.0, r))
  424. }
  425. if (g !== null) {
  426. g = Math.max(0.0, Math.min(1.0, g))
  427. }
  428. if (b !== null) {
  429. b = Math.max(0.0, Math.min(1.0, b))
  430. }
  431. var hsv = RGB_HSV(r === null ? this.rgb[0] : r, g === null ? this.rgb[1] : g, b === null ? this.rgb[2] : b);
  432. if (hsv[0] !== null) {
  433. this.hsv[0] = Math.max(0.0, this.minH, Math.min(6.0, this.maxH, hsv[0]))
  434. }
  435. if (hsv[2] !== 0) {
  436. this.hsv[1] = hsv[1] === null ? null: Math.max(0.0, this.minS, Math.min(1.0, this.maxS, hsv[1]))
  437. }
  438. this.hsv[2] = hsv[2] === null ? null: Math.max(0.0, this.minV, Math.min(1.0, this.maxV, hsv[2]));
  439. var rgb = HSV_RGB(this.hsv[0], this.hsv[1], this.hsv[2]);
  440. this.rgb[0] = rgb[0];
  441. this.rgb[1] = rgb[1];
  442. this.rgb[2] = rgb[2];
  443. this.exportColor(flags)
  444. };
  445. this.fromString = function(hex, flags) {
  446. var m = hex.match(/^\W*([0-9A-F]{3}([0-9A-F]{3})?)\W*$/i);
  447. if (!m) {
  448. return false
  449. } else {
  450. if (m[1].length === 6) {
  451. this.fromRGB(parseInt(m[1].substr(0, 2), 16) / 255, parseInt(m[1].substr(2, 2), 16) / 255, parseInt(m[1].substr(4, 2), 16) / 255, flags)
  452. } else {
  453. this.fromRGB(parseInt(m[1].charAt(0) + m[1].charAt(0), 16) / 255, parseInt(m[1].charAt(1) + m[1].charAt(1), 16) / 255, parseInt(m[1].charAt(2) + m[1].charAt(2), 16) / 255, flags)
  454. }
  455. return true
  456. }
  457. };
  458. this.toString = function() {
  459. return ((0x100 | Math.round(255 * this.rgb[0])).toString(16).substr(1) + (0x100 | Math.round(255 * this.rgb[1])).toString(16).substr(1) + (0x100 | Math.round(255 * this.rgb[2])).toString(16).substr(1))
  460. };
  461. function RGB_HSV(r, g, b) {
  462. var n = Math.min(Math.min(r, g), b);
  463. var v = Math.max(Math.max(r, g), b);
  464. var m = v - n;
  465. if (m === 0) {
  466. return [null, 0, v]
  467. }
  468. var h = r === n ? 3 + (b - g) / m: (g === n ? 5 + (r - b) / m: 1 + (g - r) / m);
  469. return [h === 6 ? 0: h, m / v, v]
  470. }
  471. function HSV_RGB(h, s, v) {
  472. if (h === null) {
  473. return [v, v, v]
  474. }
  475. var i = Math.floor(h);
  476. var f = i % 2 ? h - i: 1 - (h - i);
  477. var m = v * (1 - s);
  478. var n = v * (1 - s * f);
  479. switch (i) {
  480. case 6:
  481. case 0:
  482. return [v, n, m];
  483. case 1:
  484. return [n, v, m];
  485. case 2:
  486. return [m, v, n];
  487. case 3:
  488. return [m, n, v];
  489. case 4:
  490. return [n, m, v];
  491. case 5:
  492. return [v, m, n]
  493. }
  494. }
  495. function removePicker() {
  496. delete jscolor.picker.owner;
  497. document.getElementsByTagName('body')[0].removeChild(jscolor.picker.boxB)
  498. }
  499. function drawPicker(x, y) {
  500. if (!jscolor.picker) {
  501. jscolor.picker = {
  502. box: document.createElement('div'),
  503. boxB: document.createElement('div'),
  504. pad: document.createElement('div'),
  505. padB: document.createElement('div'),
  506. padM: document.createElement('div'),
  507. sld: document.createElement('div'),
  508. sldB: document.createElement('div'),
  509. sldM: document.createElement('div'),
  510. btn: document.createElement('div'),
  511. btnS: document.createElement('span'),
  512. btnT: document.createTextNode(THIS.pickerCloseText)
  513. };
  514. for (var i = 0, segSize = 4; i < jscolor.images.sld[1]; i += segSize) {
  515. var seg = document.createElement('div');
  516. seg.style.height = segSize + 'px';
  517. seg.style.fontSize = '1px';
  518. seg.style.lineHeight = '0';
  519. jscolor.picker.sld.appendChild(seg)
  520. }
  521. jscolor.picker.sldB.appendChild(jscolor.picker.sld);
  522. jscolor.picker.box.appendChild(jscolor.picker.sldB);
  523. jscolor.picker.box.appendChild(jscolor.picker.sldM);
  524. jscolor.picker.padB.appendChild(jscolor.picker.pad);
  525. jscolor.picker.box.appendChild(jscolor.picker.padB);
  526. jscolor.picker.box.appendChild(jscolor.picker.padM);
  527. jscolor.picker.btnS.appendChild(jscolor.picker.btnT);
  528. jscolor.picker.btn.appendChild(jscolor.picker.btnS);
  529. jscolor.picker.box.appendChild(jscolor.picker.btn);
  530. jscolor.picker.boxB.appendChild(jscolor.picker.box)
  531. }
  532. var p = jscolor.picker;
  533. p.box.onmouseup = p.box.onmouseout = function() {
  534. target.focus()
  535. };
  536. p.box.onmousedown = function() {
  537. abortBlur = true
  538. };
  539. p.box.onmousemove = function(e) {
  540. if (holdPad || holdSld) {
  541. holdPad && setPad(e);
  542. holdSld && setSld(e);
  543. if (document.selection) {
  544. document.selection.empty()
  545. } else if (window.getSelection) {
  546. window.getSelection().removeAllRanges()
  547. }
  548. dispatchImmediateChange()
  549. }
  550. };
  551. p.padM.onmouseup = p.padM.onmouseout = function() {
  552. if (holdPad) {
  553. holdPad = false;
  554. jscolor.fireEvent(valueElement, 'change')
  555. }
  556. };
  557. p.padM.onmousedown = function(e) {
  558. switch (modeID) {
  559. case 0:
  560. if (THIS.hsv[2] === 0) {
  561. THIS.fromHSV(null, null, 1.0)
  562. };
  563. break;
  564. case 1:
  565. if (THIS.hsv[1] === 0) {
  566. THIS.fromHSV(null, 1.0, null)
  567. };
  568. break
  569. }
  570. holdPad = true;
  571. setPad(e);
  572. dispatchImmediateChange()
  573. };
  574. p.sldM.onmouseup = p.sldM.onmouseout = function() {
  575. if (holdSld) {
  576. holdSld = false;
  577. jscolor.fireEvent(valueElement, 'change')
  578. }
  579. };
  580. p.sldM.onmousedown = function(e) {
  581. holdSld = true;
  582. setSld(e);
  583. dispatchImmediateChange()
  584. };
  585. var dims = getPickerDims(THIS);
  586. p.box.style.width = dims[0] + 'px';
  587. p.box.style.height = dims[1] + 'px';
  588. p.boxB.style.position = 'absolute';
  589. p.boxB.style.clear = 'both';
  590. p.boxB.style.left = x + 'px';
  591. p.boxB.style.top = y + 'px';
  592. p.boxB.style.zIndex = THIS.pickerZIndex;
  593. p.boxB.style.border = THIS.pickerBorder + 'px solid';
  594. p.boxB.style.borderColor = THIS.pickerBorderColor;
  595. p.boxB.style.background = THIS.pickerFaceColor;
  596. p.pad.style.width = jscolor.images.pad[0] + 'px';
  597. p.pad.style.height = jscolor.images.pad[1] + 'px';
  598. p.padB.style.position = 'absolute';
  599. p.padB.style.left = THIS.pickerFace + 'px';
  600. p.padB.style.top = THIS.pickerFace + 'px';
  601. p.padB.style.border = THIS.pickerInset + 'px solid';
  602. p.padB.style.borderColor = THIS.pickerInsetColor;
  603. p.padM.style.position = 'absolute';
  604. p.padM.style.left = '0';
  605. p.padM.style.top = '0';
  606. p.padM.style.width = THIS.pickerFace + 2 * THIS.pickerInset + jscolor.images.pad[0] + jscolor.images.arrow[0] + 'px';
  607. p.padM.style.height = p.box.style.height;
  608. p.padM.style.cursor = 'crosshair';
  609. p.sld.style.overflow = 'hidden';
  610. p.sld.style.width = jscolor.images.sld[0] + 'px';
  611. p.sld.style.height = jscolor.images.sld[1] + 'px';
  612. p.sldB.style.display = THIS.slider ? 'block': 'none';
  613. p.sldB.style.position = 'absolute';
  614. p.sldB.style.right = THIS.pickerFace + 'px';
  615. p.sldB.style.top = THIS.pickerFace + 'px';
  616. p.sldB.style.border = THIS.pickerInset + 'px solid';
  617. p.sldB.style.borderColor = THIS.pickerInsetColor;
  618. p.sldM.style.display = THIS.slider ? 'block': 'none';
  619. p.sldM.style.position = 'absolute';
  620. p.sldM.style.right = '0';
  621. p.sldM.style.top = '0';
  622. p.sldM.style.width = jscolor.images.sld[0] + jscolor.images.arrow[0] + THIS.pickerFace + 2 * THIS.pickerInset + 'px';
  623. p.sldM.style.height = p.box.style.height;
  624. try {
  625. p.sldM.style.cursor = 'pointer'
  626. } catch(eOldIE) {
  627. p.sldM.style.cursor = 'hand'
  628. }
  629. function setBtnBorder() {
  630. var insetColors = THIS.pickerInsetColor.split(/\s+/);
  631. var pickerOutsetColor = insetColors.length < 2 ? insetColors[0] : insetColors[1] + ' ' + insetColors[0] + ' ' + insetColors[0] + ' ' + insetColors[1];
  632. p.btn.style.borderColor = pickerOutsetColor
  633. }
  634. p.btn.style.display = THIS.pickerClosable ? 'block': 'none';
  635. p.btn.style.position = 'absolute';
  636. p.btn.style.left = THIS.pickerFace + 'px';
  637. p.btn.style.bottom = THIS.pickerFace + 'px';
  638. p.btn.style.padding = '0 15px';
  639. p.btn.style.height = '18px';
  640. p.btn.style.border = THIS.pickerInset + 'px solid';
  641. setBtnBorder();
  642. p.btn.style.color = THIS.pickerButtonColor;
  643. p.btn.style.font = '12px sans-serif';
  644. p.btn.style.textAlign = 'center';
  645. try {
  646. p.btn.style.cursor = 'pointer'
  647. } catch(eOldIE) {
  648. p.btn.style.cursor = 'hand'
  649. }
  650. p.btn.onmousedown = function() {
  651. THIS.hidePicker()
  652. };
  653. p.btnS.style.lineHeight = p.btn.style.height;
  654. switch (modeID) {
  655. case 0:
  656. var padImg = 'hs.png';
  657. break;
  658. case 1:
  659. var padImg = 'hv.png';
  660. break
  661. }
  662. p.padM.style.backgroundImage = "url('" + jscolor.getDir() + "cross.gif')";
  663. p.padM.style.backgroundRepeat = "no-repeat";
  664. p.sldM.style.backgroundImage = "url('" + jscolor.getDir() + "arrow.gif')";
  665. p.sldM.style.backgroundRepeat = "no-repeat";
  666. p.pad.style.backgroundImage = "url('" + jscolor.getDir() + padImg + "')";
  667. p.pad.style.backgroundRepeat = "no-repeat";
  668. p.pad.style.backgroundPosition = "0 0";
  669. redrawPad();
  670. redrawSld();
  671. jscolor.picker.owner = THIS;
  672. document.getElementsByTagName('body')[0].appendChild(p.boxB)
  673. }
  674. function getPickerDims(o) {
  675. var dims = [2 * o.pickerInset + 2 * o.pickerFace + jscolor.images.pad[0] + (o.slider ? 2 * o.pickerInset + 2 * jscolor.images.arrow[0] + jscolor.images.sld[0] : 0), o.pickerClosable ? 4 * o.pickerInset + 3 * o.pickerFace + jscolor.images.pad[1] + o.pickerButtonHeight: 2 * o.pickerInset + 2 * o.pickerFace + jscolor.images.pad[1]];
  676. return dims
  677. }
  678. function redrawPad() {
  679. switch (modeID) {
  680. case 0:
  681. var yComponent = 1;
  682. break;
  683. case 1:
  684. var yComponent = 2;
  685. break
  686. }
  687. var x = Math.round((THIS.hsv[0] / 6) * (jscolor.images.pad[0] - 1));
  688. var y = Math.round((1 - THIS.hsv[yComponent]) * (jscolor.images.pad[1] - 1));
  689. jscolor.picker.padM.style.backgroundPosition = (THIS.pickerFace + THIS.pickerInset + x - Math.floor(jscolor.images.cross[0] / 2)) + 'px ' + (THIS.pickerFace + THIS.pickerInset + y - Math.floor(jscolor.images.cross[1] / 2)) + 'px';
  690. var seg = jscolor.picker.sld.childNodes;
  691. switch (modeID) {
  692. case 0:
  693. var rgb = HSV_RGB(THIS.hsv[0], THIS.hsv[1], 1);
  694. for (var i = 0; i < seg.length; i += 1) {
  695. seg[i].style.backgroundColor = 'rgb(' + (rgb[0] * (1 - i / seg.length) * 100) + '%,' + (rgb[1] * (1 - i / seg.length) * 100) + '%,' + (rgb[2] * (1 - i / seg.length) * 100) + '%)'
  696. }
  697. break;
  698. case 1:
  699. var rgb,
  700. s,
  701. c = [THIS.hsv[2], 0, 0];
  702. var i = Math.floor(THIS.hsv[0]);
  703. var f = i % 2 ? THIS.hsv[0] - i: 1 - (THIS.hsv[0] - i);
  704. switch (i) {
  705. case 6:
  706. case 0:
  707. rgb = [0, 1, 2];
  708. break;
  709. case 1:
  710. rgb = [1, 0, 2];
  711. break;
  712. case 2:
  713. rgb = [2, 0, 1];
  714. break;
  715. case 3:
  716. rgb = [2, 1, 0];
  717. break;
  718. case 4:
  719. rgb = [1, 2, 0];
  720. break;
  721. case 5:
  722. rgb = [0, 2, 1];
  723. break
  724. }
  725. for (var i = 0; i < seg.length; i += 1) {
  726. s = 1 - 1 / (seg.length - 1) * i;
  727. c[1] = c[0] * (1 - s * f);
  728. c[2] = c[0] * (1 - s);
  729. seg[i].style.backgroundColor = 'rgb(' + (c[rgb[0]] * 100) + '%,' + (c[rgb[1]] * 100) + '%,' + (c[rgb[2]] * 100) + '%)'
  730. }
  731. break
  732. }
  733. }
  734. function redrawSld() {
  735. switch (modeID) {
  736. case 0:
  737. var yComponent = 2;
  738. break;
  739. case 1:
  740. var yComponent = 1;
  741. break
  742. }
  743. var y = Math.round((1 - THIS.hsv[yComponent]) * (jscolor.images.sld[1] - 1));
  744. jscolor.picker.sldM.style.backgroundPosition = '0 ' + (THIS.pickerFace + THIS.pickerInset + y - Math.floor(jscolor.images.arrow[1] / 2)) + 'px'
  745. }
  746. function isPickerOwner() {
  747. return jscolor.picker && jscolor.picker.owner === THIS
  748. }
  749. function blurTarget() {
  750. if (valueElement === target) {
  751. THIS.importColor()
  752. }
  753. if (THIS.pickerOnfocus) {
  754. THIS.hidePicker()
  755. }
  756. }
  757. function blurValue() {
  758. if (valueElement !== target) {
  759. THIS.importColor()
  760. }
  761. }
  762. function setPad(e) {
  763. var mpos = jscolor.getRelMousePos(e);
  764. var x = mpos.x - THIS.pickerFace - THIS.pickerInset;
  765. var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
  766. switch (modeID) {
  767. case 0:
  768. THIS.fromHSV(x * (6 / (jscolor.images.pad[0] - 1)), 1 - y / (jscolor.images.pad[1] - 1), null, leaveSld);
  769. break;
  770. case 1:
  771. THIS.fromHSV(x * (6 / (jscolor.images.pad[0] - 1)), null, 1 - y / (jscolor.images.pad[1] - 1), leaveSld);
  772. break
  773. }
  774. }
  775. function setSld(e) {
  776. var mpos = jscolor.getRelMousePos(e);
  777. var y = mpos.y - THIS.pickerFace - THIS.pickerInset;
  778. switch (modeID) {
  779. case 0:
  780. THIS.fromHSV(null, null, 1 - y / (jscolor.images.sld[1] - 1), leavePad);
  781. break;
  782. case 1:
  783. THIS.fromHSV(null, 1 - y / (jscolor.images.sld[1] - 1), null, leavePad);
  784. break
  785. }
  786. }
  787. function dispatchImmediateChange() {
  788. if (THIS.onImmediateChange) {
  789. var callback;
  790. if (typeof THIS.onImmediateChange === 'string') {
  791. callback = new Function(THIS.onImmediateChange)
  792. } else {
  793. callback = THIS.onImmediateChange
  794. }
  795. callback.call(THIS)
  796. }
  797. }
  798. var THIS = this;
  799. var modeID = this.pickerMode.toLowerCase() === 'hvs' ? 1: 0;
  800. var abortBlur = false;
  801. var valueElement = jscolor.fetchElement(this.valueElement),
  802. styleElement = jscolor.fetchElement(this.styleElement);
  803. var holdPad = false,
  804. holdSld = false;
  805. var leaveValue = 1 << 0,
  806. leaveStyle = 1 << 1,
  807. leavePad = 1 << 2,
  808. leaveSld = 1 << 3;
  809. jscolor.addEvent(target, 'focus',
  810. function() {
  811. if (THIS.pickerOnfocus) {
  812. THIS.showPicker()
  813. }
  814. });
  815. jscolor.addEvent(target, 'blur',
  816. function() {
  817. if (!abortBlur) {
  818. window.setTimeout(function() {
  819. abortBlur || blurTarget();
  820. abortBlur = false
  821. },
  822. 0)
  823. } else {
  824. abortBlur = false
  825. }
  826. });
  827. if (valueElement) {
  828. var updateField = function() {
  829. THIS.fromString(valueElement.value, leaveValue);
  830. dispatchImmediateChange()
  831. };
  832. jscolor.addEvent(valueElement, 'keyup', updateField);
  833. jscolor.addEvent(valueElement, 'input', updateField);
  834. jscolor.addEvent(valueElement, 'blur', blurValue);
  835. valueElement.setAttribute('autocomplete', 'off')
  836. }
  837. if (styleElement) {
  838. styleElement.jscStyle = {
  839. backgroundImage: styleElement.style.backgroundImage,
  840. backgroundColor: styleElement.style.backgroundColor,
  841. color: styleElement.style.color
  842. }
  843. }
  844. switch (modeID) {
  845. case 0:
  846. jscolor.requireImage('hs.png');
  847. break;
  848. case 1:
  849. jscolor.requireImage('hv.png');
  850. break
  851. }
  852. jscolor.requireImage('cross.gif');
  853. jscolor.requireImage('arrow.gif');
  854. this.importColor()
  855. }
  856. };
  857. jscolor.install();