1 /* ColorTestViewer 颜色调试器 2 3 attribute: 4 onchange: Function; //颜色改变回调; 默认null 5 6 //以下属性不建议直接修改 7 rgb: RGBColor; /gb模式颜色 8 hsv: Object{h,s,v}; //hsv模式颜色 9 alpha: Number; //透明度 10 11 method: 12 update(): undefined; //更新控件视图 (通常控件被唤出时调用此方法, 前提是在唤出前控件颜色发生了改变) 13 setValue(r, g, b, a): this; //设置控件的颜色 14 15 demo: 16 const ctv = new ColorTestViewer({width: 200}) 17 .setValue(0, 0, 255, 1).update(false) 18 .pos(100, 100).render(); 19 20 ctv.onchange = v => console.log(v); 21 22 */ 23 class ColorTestViewer extends CanvasAnimateRender{ 24 25 get value(){ 26 return this.rgb.getRGBA(Math.floor(this.alpha * 1000) / 1000); 27 } 28 29 constructor(option = {}){ 30 super(option); 31 32 this.rgb = new RGBColor(255); 33 this.hsv = this.rgb.getHSV(); 34 this.alpha = 1; 35 this.cae = null; 36 this.onchange = null; 37 38 this.viewSVColor = null; 39 this.viewSVsv = null; 40 this.viewSVCursor = null; 41 42 this.viewHValueBG = null; 43 this.viewHValue = null; 44 this.viewHScroll = null; 45 this.viewHCursor = null; 46 47 this.viewAScroll = null; 48 this.viewACursor = null; 49 50 this.viewColorInfo = null; 51 52 //默认样式 53 if(option.canvas === undefined){ 54const width = option.width || 200, height = option.height || (width * 0.8), margin = 2, 55h5 = height * 0.5, h1 = height * 0.1, h3 = height * 0.3; 56 57this.size(width + margin * 2, height + margin * 5); 58 59this.initViewSVColor(width, h5); 60this.initViewHScroll(width, h1); 61this.initViewAScroll(width, h1); 62this.initViewHValue(h3, h3); 63this.initViewColorInfo(width - h3, h3); 64 65this.setViewSVPos(margin, margin); 66this.setViewHScrollPos(margin, h5 + margin * 2); 67this.setViewAScrollPos(margin, h5 + h1 + margin * 3); 68this.setViewHValuePos(margin, h5 + h1 * 2 + margin * 4); 69this.viewColorInfo.pos(this.viewHValue.box.maxX(), this.viewHValue.box.y); 70 71this.initList(); 72this.initEvent(); 73 74 } 75 76 } 77 78 update(u){ 79 if(this.viewSVColor !== null){ 80this.updateViewSVCursor(); 81this.updateViewSVColor(); 82this.updateViewHValue(); 83this.updateViewHCursor(); 84this.updateViewACursor(); 85this.updateViewColorInfo(); 86if(u === true) this.redraw(); 87 } 88 89 return this; 90 } 91 92 setValue(r, g, b, a){ 93 this.rgb.r = r; 94 this.rgb.g = g; 95 this.rgb.b = b; 96 this.alpha = a; 97 this.rgb.getHSV(this.hsv); 98 99 return this;100 }101 102 setValueString(color){103 if(typeof color !== "string") return this;104 var _color = this.getColor(color);105 106 if(_color[0] === "#"){107const len = _color.length;108if(len === 4){109 _color = _color.slice(1);110 this.rgb.setFormHex(parseInt("0x"+_color + "" + _color));111 }112else if(len === 7) this.rgb.setFormHex(parseInt("0x"+_color.slice(1)));113this.alpha = 1;114this.rgb.getHSV(this.hsv);115116 }117 118 else if(_color[0] === "r" && _color[1] === "g" && _color[2] === "b"){119const arr = [];120for(let k = 0, len = _color.length, v = "", is = false; k < len; k++){121 122 if(is === true){123 if(_color[k] === "," || _color[k] === ")"){124 arr.push(parseFloat(v));125 v = "";126 }127 else v += _color[k];128 129 }130 131 else if(_color[k] === "(") is = true;132 133 }134 135this.setValue(arr[0], arr[1], arr[2], arr[3] === undefined ? 1 : arr[3]);136137 }138 139 return this;140 }141 142 getColor(str){ //检测 str 是否是颜色类型(16进制, rgb, rgba, 英文); 如果是则返回去除掉空格后的字符串颜色(英文则返回对应16进制颜色)143 var _color = "";144 for(let k = 0, len = str.length; k < len; k++){145if(str[k] === " ") continue;146_color += str[k];147 }148 149 if(_color[0] === "#" || (_color[0] === "r" && _color[1] === "g" && _color[2] === "b")) return _color;150 else{151for(let k = 0, len = ColorRefTable.length; k < len; k++){152 str = ColorRefTable[k];153 if(str[0] === _color) return str[1];154 }155 }156 157 return "";158 }159 160 exit(){161 if(this.cae){162this.onUpSV();163this.onUpH();164this.onUpA();165 }166 167 if(this.domElement.parentElement) this.domElement.parentElement.removeChild(this.domElement);168 169 }170 171 172 //event173 initEvent(){174 175 const cae = new CanvasAnimateEvent(this);176 177 //SV178 const setSV = (pageX, pageY) => {179pageX = (pageX - this.domElementRect.x - this.viewSVColor.box.x) / this.viewSVColor.box.w * 100;180pageY = (1 - (pageY - this.domElementRect.y - this.viewSVColor.box.y) / this.viewSVColor.box.h) * 100;181if(pageX < 0) pageX = 0;182else if(pageX > 100) pageX = 100;183if(pageY < 0) pageY = 0;184else if(pageY > 100) pageY = 100;185if(this.hsv.s !== pageX || this.hsv.v !== pageY){186 this.hsv.s = pageX;187 this.hsv.v = pageY;188 this.rgb.setFormHSV(this.hsv.h, this.hsv.s, this.hsv.v);189 if(typeof this.onchange === "function") this.onchange(this.value);190 this.updateViewHValue();191 this.updateViewColorInfo();192 this.updateViewSVCursor();193 this.redraw();194 }195 196 },197 198 onMoveSV = event => {199 setSV(event.pageX, event.pageY);200 },201 202 onUpSV = () => {203document.body.removeEventListener("pointerup", onUpSV);204document.body.removeEventListener("pointermove", onMoveSV);205cae.remove(this.viewSVCursor, 'up', onUpSV);206cae.remove(this.viewSVCursor, 'move', onMoveSV);207208 },209 210 onDownSV = event => {211 setSV(event.pageX, event.pageY);212cae.add(this.viewSVCursor, "up", onUpSV);213cae.add(this.viewSVCursor, "move", onMoveSV);214document.body.addEventListener("pointerup", onUpSV);215document.body.addEventListener("pointermove", onMoveSV);216217 }218 219 cae.add(this.viewSVColor, "down", onDownSV);220 cae.add(this.viewSVCursor, "down", onDownSV);221 this.onUpSV = onUpSV;222 223 224 //H225 const setH = (pageX) => {226pageX = (pageX - this.domElementRect.x - this.viewHScroll.box.x) / this.viewHScroll.box.w * 360;227if(pageX < 0) pageX = 0;228else if(pageX > 360) pageX = 360;229if(this.hsv.h !== pageX){230 this.hsv.h = pageX;231 this.rgb.setFormHSV(this.hsv.h, this.hsv.s, this.hsv.v);232 if(typeof this.onchange === "function") this.onchange(this.value);233 this.updateViewHValue();234 this.updateViewColorInfo();235 this.updateViewSVColor();236 this.updateViewHCursor();237 this.redraw();238 }239 240 },241 242 onMoveH = event => {243 setH(event.pageX);244 },245 246 onUpH = () => {247document.body.removeEventListener("pointerup", onUpH);248document.body.removeEventListener("pointermove", onMoveH);249cae.remove(this.viewHCursor, 'up', onUpH);250cae.remove(this.viewHCursor, 'move', onMoveH);251 252 },253 254 onDownH = event => {255 setH(event.pageX);256cae.add(this.viewHCursor, "up", onUpH);257cae.add(this.viewHCursor, "move", onMoveH);258document.body.addEventListener("pointerup", onUpH);259document.body.addEventListener("pointermove", onMoveH);260 261 }262 263 cae.add(this.viewHScroll, "down", onDownH);264 cae.add(this.viewHCursor, "down", onDownH);265 this.onUpH = onUpH;266 267 268 269 //A270 const setA = (pageX) => {271pageX = (pageX - this.domElementRect.x - this.viewAScroll.box.x) / this.viewAScroll.box.w;272if(pageX < 0) pageX = 0;273else if(pageX > 1) pageX = 1;274if(this.alpha !== pageX){275 this.alpha = pageX;276 if(typeof this.onchange === "function") this.onchange(this.value);277 this.updateViewColorInfo();278 this.updateViewHValue();279 this.updateViewACursor();280 this.redraw();281 }282 283 },284 285 onMoveA = event => {286 setA(event.pageX);287 },288 289 onUpA = () => {290document.body.removeEventListener("pointerup", onUpA);291document.body.removeEventListener("pointermove", onMoveA);292cae.remove(this.viewACursor, 'up', onUpA);293cae.remove(this.viewACursor, 'move', onMoveA);294295 },296 297 onDownA = event => {298 setA(event.pageX);299cae.add(this.viewACursor, "up", onUpA);300cae.add(this.viewACursor, "move", onMoveA);301document.body.addEventListener("pointerup", onUpA);302document.body.addEventListener("pointermove", onMoveA);303 304 }305 306 cae.add(this.viewAScroll, "down", onDownA);307 cae.add(this.viewACursor, "down", onDownA);308 this.onUpA = onUpA;309 310 this.cae = cae;311 312 }313 314 315 //SV 明度 与 灰度316 updateViewSVCursor(){317 this.viewSVCursor.pos(this.hsv.s / 100 * this.viewSVColor.box.w + this.viewSVColor.box.x - this.viewSVCursor.circle.r, (1 - this.hsv.v / 100) * this.viewSVColor.box.h + this.viewSVColor.box.y - this.viewS