|
|
|||||
выбор цвета [colorPicker]
Допустим есть пара объектов, разных по цвету. При нажатии на которые цветовая схема должна передаваться в колорпикер т.е. по сути, смещать элементы управления пикером. В принципе, это своего рода, инструмент пипетка.
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; public class ColorPicker extends Sprite { private var _svBmp:Bitmap; private var _hBmp:Bitmap; private var _rot:uint = 0; private var _slider:Sprite; private var _circle:Sprite; private var _color:uint = 0xFFFFFF; public function get color():uint { return _color; } private function bg():void { this.graphics.clear() this.graphics.beginFill(color); this.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight); this.graphics.endFill(); } public function ColorPicker() { this.x = this.y = 100; //sv var svbmpd:BitmapData = CreatePickColor.svBmpd(_rot); _svBmp = new Bitmap(svbmpd); addChild(_svBmp); //h var hbmpd:BitmapData = CreatePickColor.hBmpd(); _hBmp = new Bitmap(hbmpd); addChild(_hBmp); _hBmp.x = 210; //slider _slider = new Sprite(); _slider.graphics.lineStyle(2); _slider.graphics.beginFill(0, 0); _slider.graphics.drawRoundRect(-10, -3, 20, 6, 4, 4); _slider.graphics.endFill(); addChild(_slider); _slider.x = _hBmp.x + 10; _slider.y = _hBmp.y; _slider.addEventListener(MouseEvent.MOUSE_DOWN, onSliderDown); //circle _circle = new Sprite(); _circle.graphics.lineStyle(1, 0xffffff); _circle.graphics.beginFill(0, 0); _circle.graphics.drawCircle(0, 0, 4); _circle.graphics.endFill(); var child:Sprite = new Sprite(); child.graphics.lineStyle(1.5); child.graphics.drawCircle(0, 0, 3); _circle.addChild(child); addChild(_circle); _circle.addEventListener(MouseEvent.MOUSE_DOWN, onCircleDown); } private function onSliderDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, onSliderMove); stage.addEventListener(MouseEvent.MOUSE_UP, onSliderUp); } private function onCircleDown(e:MouseEvent):void { stage.addEventListener(MouseEvent.MOUSE_MOVE, onCircleMove); stage.addEventListener(MouseEvent.MOUSE_UP, onCircleUp); } private function onSliderMove(e:MouseEvent):void { _slider.y = mouseY; if(_slider.y < _hBmp.y) _slider.y = _hBmp.y; else if(_slider.y >= _hBmp.y+_hBmp.height) _slider.y = _hBmp.y + _hBmp.height - 1; svColorChange(); _color = _svBmp.bitmapData.getPixel(_circle.x, _circle.y); bg(); } private function onCircleMove(e:MouseEvent):void { _circle.x = mouseX; _circle.y = mouseY; if(_circle.y < _svBmp.y) _circle.y = _svBmp.y; else if(_circle.y >= _svBmp.y + _svBmp.height) _circle.y = _svBmp.y + _svBmp.height - 1; if(_circle.x < _svBmp.x) _circle.x = _svBmp.x; else if(_circle.x >= _svBmp.x + _svBmp.width) _circle.x = _svBmp.x + _svBmp.width - 1; _color = _svBmp.bitmapData.getPixel(_circle.x, _circle.y); bg(); } private function onSliderUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, onSliderMove); stage.removeEventListener(MouseEvent.MOUSE_UP, onSliderUp); _color = _svBmp.bitmapData.getPixel(_circle.x, _circle.y); bg(); } private function onCircleUp(e:MouseEvent):void { stage.removeEventListener(MouseEvent.MOUSE_MOVE, onCircleMove); stage.removeEventListener(MouseEvent.MOUSE_UP, onCircleUp); _color = _svBmp.bitmapData.getPixel(_circle.x, _circle.y); dispatchEvent(new Event(Event.CHANGE)); bg(); } private function svColorChange():void { removeChild(_svBmp); _rot = 359-(_slider.y)*(359/(_hBmp.height)); var svbmpd:BitmapData = CreatePickColor.svBmpd(_rot); _svBmp = new Bitmap(svbmpd); addChild(_svBmp); setChildIndex(_circle, numChildren-1); } } } import flash.display.Bitmap; import flash.display.BitmapData; import frocessing.color.ColorHSV; class CreatePickColor { public static function svBmpd(rot:Number, size:uint = 200):BitmapData { var bmpd:BitmapData = new BitmapData(size, size, false, 0); bmpd.lock(); for(var y:uint = 0; y < size; y++) for(var x:uint = 0; x < size; x++) bmpd.setPixel(x, y, (new ColorHSV(rot, x/size, 1-y/size)).toRGB().value); bmpd.unlock(); return bmpd; } public static function hBmpd(size:uint = 200):BitmapData { var bmpd:BitmapData = new BitmapData(20, size, false, 0); bmpd.lock(); for(var y:uint = 0; y < size; y++) for (var x:uint = 0; x < size; x++) bmpd.setPixel(x, y, (new ColorHSV(359-y*(359/size))).toRGB().value); bmpd.unlock(); return bmpd; } } Может есть какие мысли или можете посоветовать нечто похожее. |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
Так и не понял, в чем вопрос.
"Как брать цвет с объектов вне колорпикера" ? — делать снимок root в битмапдату и брать из нее пиксель; "Как поставить маркеры колорпикера и задать базовый цвет квадрата для полученного извне значения" ? — пересчитать HSV "обратно". // у Вас как то сложно все сделано, куча битмапдат, попиксельное заполнение — зачем? Делаете квадрат базового цвета (из спектрумбара, Н), поверх него квадрат с градиентом белого от прозрачного до непрозрачного, и третий квадрат с градиентом черного. Теперь все, что нужно — менять цвет базового квадрата дравРектом. Все на векторных шейпах, никаких битмап. Цвет РАССЧИТЫВАЕТЕ (a не берете пиксель с квадрата!) из координат маркера внутри квадрата и координаты Y маркера в спектрумбаре. Добавлено через 5 минут Да, Вам понадобится класс для пересчета HSV package gui.wysiwyg.toolbar.plugins.colorbox { public class HSV { //----------------------------------------------------------------------------------------------- // RGB value from Hue, Saturation and Brightness values //----------------------------------------------------------------------------------------------- public static function toRGB(h:Number, s:Number, v:Number):uint { var r:Number, g:Number, b:Number; var i:int; var f:Number, p:Number, q:Number, t:Number; if (s == 0) { r = g = b = v; return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255); } if (h == 360) h = 0; h /= 60; i = Math.floor(h); f = h - i; p = v * (1 - s); q = v * (1 - s * f); t = v * (1 - s * (1 - f)); switch(i) { case 0: r = v; g = t; b = p; break; case 1: r = q; g = v; b = p; break; case 2: r = p; g = v; b = t; break; case 3: r = p; g = q; b = v; break; case 4: r = t; g = p; b = v; break; default: r = v; g = p; b = q; break; } return (Math.round(r * 255) << 16) + (Math.round(g * 255) << 8) + Math.round(b * 255); } //----------------------------------------------------------------------------------------------- // HSV value from Red, Green and Blue values //----------------------------------------------------------------------------------------------- public static function toHSV(r:uint, g:uint, b:uint):Array { var max:Number = Math.max(r, g, b); var min:Number = Math.min(r, g, b); var h:Number = 0; var s:Number = max != 0 ? (1 - min / max) * 100 : 0; var v:Number = (max / 255) * 100; if((r==g) && (g==b)) h = 0; else if(r>=g && g>=b) h = 60*(g-b)/(r-b); else if(g>=r && r>=b) h = 60 + 60*(g-r)/(g-b); else if(g>=b && b>=r) h = 120 + 60*(b-r)/(g-r); else if(b>=g && g>=r) h = 180 + 60*(b-g)/(b-r); else if(b>=r && r>=g) h = 240 + 60*(r-g)/(b-g); else if(r>=b && b>=g) h = 300 + 60*(r-b)/(r-g); else h = 0; h = Math.min(360, Math.max(0, Math.round(h))); s = Math.min(1, Math.max(0, Math.round(s) / 100)); v = Math.min(1, Math.max(0, Math.round(v) / 100)); return [h, s, v]; } } }
__________________
Reality.getBounds(this); Последний раз редактировалось Wolsh; 17.03.2016 в 01:23. |
|
|||||
То что вы обозначили вторым вопросом, именно в этом проблема. Задать базовый цвет не проблема, а вот расставить маркеры на нужные координаты, это большая проблема.
Переделал, но по моему, это те же грабли, только с боку, потому что без getPixel совсем не получается. Мне в любом случае, чтобы получить цвет у спектрумбара, приходится преобразовывать его в битмапу и использовать гетпиксел по координатам маркера. Пока совсем не догоняю, как передав, грубо говоря цвет 0xFF0000, расставить маркеры по местам.. Сохранил в ФД на всякий ColorBox.zip |
|
|||||
Нуб нубам
модератор форума
Регистрация: Jan 2006
Адрес: Бердск, НСО
Сообщений: 6,445
|
HSV состоит из Оттенка (Hue) — спектрального круга, соотв. измеряется в градусах и имеет 360 градаций, а также Насыщенности и Яркости, которые измеряются в % и имеют по 100 градаций.
Спектрумбар удобно рисовать 360 пикселей высотой и тогда координата маркера будет прямо коррелировать со значением Hue. Спектр здесь — как бы развернутый в линию круг. Брать с него пиксель имеет смысл только в том случае, если Вы действительно закрашивали его точными цветами и все 360 там представлены. Все это рисование требует ресурсов и времени. Гораздо проще кинуть векторный градиент. //// Spectrum Scale var matrix:Matrix = new Matrix(); matrix.createGradientBox(20, 360, Math.PI / 2, 0, 0); // 20, 360 — размеры шкалы, как она будет рисоваться. Градиент "резиновый", так что // размеры шкалы могут быть какими угодно, только координату маркера придется // пересчитывать в проценты и брать этот процент от 360 для Hue. _spectrum.graphics.beginGradientFill ( GradientType.LINEAR, [0xFF0000, 0xFF00FF, 0x0000FF, 0x00FFFF, 0x00FF00, 0xFFFF00, 0xFF0000], [1, 1, 1, 1, 1, 1, 1], [2, 44, 86, 128, 170, 212, 254], matrix ); Итак, координата маркера на спектрумбаре это Hue; соответственно, когда Вы получили извне какой-то цвет в RGB, переводите его в HSV. Н будет координатой маркера на спектрумбаре. Ставите туда маркер и вызываете функцию, которая вычисляет базовый цвет из координаты маркера/Н (у Вас в любом случае такая должна быть, чтобы менять базу когда юзер двигает руками маркер). У меня это выглядит примерно так: Думаю, обратный процесс не составит труда? Вычислить _hue из RGB и отнять его из 360, чтобы узнать нужную координату маркера? Добавлено через 4 минуты Ну а маркер на большом поле ставится по координатам S и V, которые Вы получаете все там же, переведя RGB в HSV. Они в процентах; соотв. Вам надо передвинуть маркер на данный процент от высоты и ширины поля. Удачи))
__________________
Reality.getBounds(this); |
|
|||||
оо Крутяк! Наконец-то до меня дошло. Спасибо)
|
Часовой пояс GMT +4, время: 23:42. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|