您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

canvascolor.js 8.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. /**
  2. * CANVASCOLOR color picker
  3. *********************************************************
  4. * @licstart The following is the entire license notice for the
  5. * JavaScript code in this page.
  6. *
  7. * Copyright (C) 2013-2014 Ophir LOJKINE
  8. *
  9. *
  10. * The JavaScript code in this page is free software: you can
  11. * redistribute it and/or modify it under the terms of the GNU
  12. * General Public License (GNU GPL) as published by the Free Software
  13. * Foundation, either version 3 of the License, or (at your option)
  14. * any later version. The code is distributed WITHOUT ANY WARRANTY;
  15. * without even the implied warranty of MERCHANTABILITY or FITNESS
  16. * FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  17. *
  18. * As additional permission under GNU GPL version 3 section 7, you
  19. * may distribute non-source (e.g., minimized or compacted) forms of
  20. * that code without the copy of the GNU GPL normally required by
  21. * section 4, provided you include this license notice and a URL
  22. * through which recipients can access the Corresponding Source.
  23. *
  24. * @licend
  25. */
  26. /*jshint bitwise:false*/
  27. // ==ClosureCompiler==
  28. // @output_file_name canvascolor.js
  29. // @compilation_level ADVANCED_OPTIMIZATIONS
  30. // @js_externs var canvascolor;
  31. // @language ecmascript5_strict
  32. // @use_types_for_optimization true
  33. // ==/ClosureCompiler==
  34. var canvascolor = (function() {//Code Isolation
  35. "use strict";
  36. (function addCSS () {
  37. var styleTag = document.createElement("style");
  38. styleTag.innerHTML = [".canvascolor-container{",
  39. "background-color:black;",
  40. "border-radius:5px;",
  41. "overflow:hidden;",
  42. "width:179px;",
  43. "padding:2px;",
  44. "display:none;",
  45. "}",
  46. ".canvascolor-container canvas{",
  47. "cursor:crosshair;",
  48. "}",
  49. ".canvascolor-history{",
  50. "overflow:auto;",
  51. "}",
  52. ".canvascolor-history > div{",
  53. "margin:2px;",
  54. "display:inline-block;",
  55. "}"].join("");
  56. document.head.appendChild(styleTag);
  57. })();
  58. function hsv2rgb (h,s,v) {
  59. if( s === 0 ) return [v,v,v]; // achromatic (grey)
  60. h /= (Math.PI/6); // sector 0 to 5
  61. var i = h|0,
  62. f = h - i, // factorial part of h
  63. p = v * ( 1 - s ),
  64. q = v * ( 1 - s * f ),
  65. t = v * ( 1 - s * ( 1 - f ) );
  66. switch( i%6 ) {
  67. case 0: return [v,t,p];
  68. case 1: return [q,v,p];
  69. case 2: return [p,v,t];
  70. case 3: return [p,q,v];
  71. case 4: return [t,p,v];
  72. case 5:return [v,p,q];
  73. }
  74. }
  75. function isFixedPosition(elem) {
  76. do {
  77. if (getComputedStyle(elem).position === "fixed") return true;
  78. } while ( (elem = elem.parentElement) !== null );
  79. return false;
  80. }
  81. var containerTemplate;
  82. (function createContainer(){
  83. containerTemplate = document.createElement("div");
  84. containerTemplate.className = "canvascolor-container";
  85. var canvas = document.createElement("canvas");
  86. var historyDiv = document.createElement("div");
  87. historyDiv.className = "canvascolor-history";
  88. containerTemplate.appendChild(canvas);
  89. containerTemplate.appendChild(historyDiv);
  90. })();
  91. function canvascolor(elem) {
  92. var curcolor = elem.value || "#000";
  93. var w=200, h=w/2;
  94. var container = containerTemplate.cloneNode(true);
  95. container.style.width = w+"px";
  96. container.style.position = isFixedPosition(elem) ? "fixed" : "absolute";
  97. var canvas = container.getElementsByTagName("canvas")[0];
  98. var ctx = canvas.getContext("2d");
  99. canvas.width = w; canvas.height=h;
  100. var prevcolorsDiv = container.getElementsByClassName("canvascolor-history")[0];
  101. prevcolorsDiv.style.width=w+"px";
  102. prevcolorsDiv.style.maxHeight=h+"px";
  103. var previewdiv = createColorDiv(curcolor);
  104. previewdiv.style.border = "1px solid white";
  105. previewdiv.style.borderRadius = "5px";
  106. document.body.appendChild(container);
  107. function displayContainer(){
  108. var rect = elem.getBoundingClientRect();
  109. var conttop=(rect.top+rect.height+3),
  110. contleft=rect.left;
  111. if (container.style.position !== "fixed") {
  112. conttop += document.documentElement.scrollTop;
  113. contleft += document.documentElement.scrollLeft;
  114. }
  115. container.style.top = conttop+"px";
  116. container.style.left = contleft+"px";
  117. container.style.display = "block";
  118. }
  119. function hideContainer(){
  120. container.style.display = "none";
  121. }
  122. elem.addEventListener("mouseover", displayContainer, true);
  123. container.addEventListener("mouseleave", hideContainer, false);
  124. elem.addEventListener("keyup", function(){
  125. changeColor(elem.value, true);
  126. }, true);
  127. changeColor(elem.value, true);
  128. var idata = ctx.createImageData(w,h);
  129. function rgb2hex (rgb) {
  130. function num2hex (c) {return (c*15/255|0).toString(16);}
  131. return "#"+num2hex(rgb[0])+num2hex(rgb[1])+num2hex(rgb[2]);
  132. }
  133. function colorAt(coords) {
  134. var x=coords[0], y=coords[1];
  135. return hsv2rgb(x/w*Math.PI, 1, (1-y/h)*255);
  136. }
  137. function render() {
  138. for (var x=0; x<w; x++) {
  139. for (var y=0;y<h; y++) {
  140. var i = 4*(x+y*w);
  141. var rgb = colorAt([x,y]);
  142. idata.data[i] = rgb[0];//Red
  143. idata.data[i+1] = rgb[1];//Green
  144. idata.data[i+2] = rgb[2];//Blue
  145. idata.data[i+3] = 255;
  146. }
  147. }
  148. ctx.putImageData(idata,0,0);
  149. }
  150. render();
  151. /** Changes the current color (the value of the input field) and updates other variables accordingly
  152. * @param {string} color The new color. Must be a valid CSS color string if ensureValid is not specified
  153. * @param {boolean} [ensureValid=false] Do not make the change if color is not a valid CSS color
  154. */
  155. function changeColor(color, ensureValid) {
  156. elem.style.backgroundColor = color;
  157. if (ensureValid && elem.style.backgroundColor.length === 0) {
  158. elem.style.backgroundColor = curcolor;
  159. return;
  160. }
  161. previewdiv.style.backgroundColor = color;
  162. curcolor = color;
  163. elem.value = color;
  164. elem.focus();
  165. }
  166. function createColorDiv (color) {
  167. var div = document.createElement("div");
  168. div.style.width = (w/3-10)+"px";
  169. div.style.height = (h/3-8)+"px";
  170. div.style.backgroundColor = color;
  171. div.addEventListener("click", function(){
  172. changeColor(color);
  173. }, true);
  174. if (prevcolorsDiv.childElementCount <= 1) prevcolorsDiv.appendChild(div);
  175. else prevcolorsDiv.insertBefore(div,prevcolorsDiv.children[1]);
  176. return div;
  177. }
  178. function canvasPos(evt) {
  179. var canvasrect = canvas.getBoundingClientRect();
  180. return [evt.clientX - canvasrect.left, evt.clientY - canvasrect.top];
  181. }
  182. canvas.addEventListener("mousemove", function(evt){
  183. var coords = canvasPos(evt);
  184. previewdiv.style.backgroundColor = rgb2hex(colorAt(coords));
  185. }, true);
  186. canvas.addEventListener("click", function(evt){
  187. var coords = canvasPos(evt);
  188. var color = rgb2hex(colorAt(coords));
  189. createColorDiv(color);
  190. changeColor(color);
  191. }, true);
  192. canvas.addEventListener("mouseleave", function(){
  193. previewdiv.style.backgroundColor = curcolor;
  194. }, true);
  195. }
  196. //Put a color picker on every input[type=color] if the browser doesn't support this input type
  197. //and on every input with the class canvascolor
  198. var pickers = document.querySelectorAll("input.canvascolor, input[type=color]");
  199. for (var i=0;i <pickers.length; i++) {
  200. var input = pickers.item(i);
  201. //If the browser supports native color picker and the user didn't
  202. //explicitly added canvascolor to the element, we do not add a custom color picker
  203. if (input.type !== "color" ||
  204. input.className.split(" ").indexOf("canvascolor") !== -1) {
  205. canvascolor(input);
  206. }
  207. }
  208. return canvascolor;
  209. }());