PDA

Просмотр полной версии : Обводка объекта


Isfet
05.09.2013, 13:13
Есть объект, со множеством вложенностей, у некоторых внутренних спрайтов есть тень, нужно обвести этот спрайт (произвольной формы) линией в 10 пикселей.
Подобный эффект достигается с помощью Glow фильтра, если поставить streight = 255, но проблема в том что этот фильтр подсвечивает и все фильтры теней, во вложенных спрайтах, есть ли какие нибудь способы сделать такую обводку, чтобы она не брала в расчет другие фильтры, а строилась только по спрайтам?
Есть дума перерисовывать исходный объект без фильтров, его "светить" и убирать из отображения, и добавлять в основной объект только обводку, но это достаточно трудоемко) думал может есть попроще способы

caseyryan
05.09.2013, 14:30
Отрисовать весь объект в битмапку, и к ней применить обводку.
Но лучше заранее создать класс объекта, который будет делать всю эту работу, с учетом других фильтров. Потрудиться один раз, зато помто все объекты расширяющие этот класс смогут применять обводку.

КорДум
05.09.2013, 22:39
Не-не, все проще. Контейнеру назначить фильтр Inner Glow.

Isfet
06.09.2013, 07:37
иннер все равно тени внутренних объектов подсвечивает

C4Grey
06.09.2013, 08:48
Думаю, все еще проще: если фильтр применяется и к детям контейнера - тогда нужно этот объект-контейнер поместить в Sprite на 0 уровень, поверх в этот же спрайт добавлять детей, и смело применять Glow-фильтр к целевому объекту.

Isfet
06.09.2013, 11:07
так можно было бы сделать, если в спрайте контейнере бы рисовалось именно то , что нужно обвести, а если в нем ничего не рисуется, а просто добавляются дети с фильтрами, а он просто растягивается вследствии их добавления, нужно обвести всех детей по периметру, но не обводя при этом их фильтры

Wolsh
06.09.2013, 12:05
Кликаем.
FiltersIgnore.swf

package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.DropShadowFilter;
import flash.geom.Rectangle;
import flash.utils.Dictionary;

/**
* ...
* @author Wolsh
*/
public class Main extends Sprite
{
private var _filtered:Dictionary = new Dictionary();
private var _isOutlined:Boolean = false;
private var _outline:Bitmap;

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point

var container:Sprite = new Sprite();
super.addChild(container);

var quadro:Sprite = new Sprite()
quadro.graphics.beginFill(0x3344FF);
quadro.graphics.drawRect(0, 0, 250, 250);
container.addChild(quadro);
quadro.x = 100;
quadro.y = 100;
quadro.filters = [new DropShadowFilter(9, 45, 0x000000, 1, 18, 18, 1, 3)];

var circle:Sprite = new Sprite()
circle.graphics.beginFill(0xFF4400);
circle.graphics.drawCircle(0, 0, 100);
container.addChild(circle);
circle.x = 150;
circle.y = 150;
circle.filters = [new DropShadowFilter(9, 45, 0x000000, 1, 18, 18, 1, 3)];

container.addEventListener(MouseEvent.CLICK, handlerClick);
}

private function handlerClick(event:MouseEvent):void
{
if (_isOutlined)
{
removeBorder(event.currentTarget as Sprite);
}
else
{
drawBorderIgnoreFilters(event.currentTarget as Sprite);
}
}

private function removeBorder(container:Sprite):void
{
container.removeChild(_outline);
_filtered = new Dictionary();
_isOutlined = false;
}

private function drawBorderIgnoreFilters(container:Sprite):void
{
var childs:uint = container.numChildren;
for (var i:uint = 0; i < childs; i++)
{
var child:DisplayObject = container.getChildAt(i);
_filtered[child] = child.filters.concat();
child.filters = [];
}
var rect:Rectangle = container.getRect(container);
var bmd:BitmapData = new BitmapData(rect.width + rect.x, rect.height + rect.y, true, 0x00000000);
bmd.draw(container);
_outline = new Bitmap(bmd);
container.addChild(_outline);
_outline.filters = [new DropShadowFilter(0, 45, 0x00FF00, 1, 2, 2, 5, 3, false, true, true)];
for (i = 0; i < childs; i++ )
{
child = container.getChildAt(i);
child.filters = _filtered[child];
}
_isOutlined = true;
}

}

}

Isfet
06.09.2013, 15:29
да это то что нужно , но есть проблема, объект рисуется и в отрицательных координатах, можно ли битмапу отрисовать в отрицательных координатах?

Wolsh
06.09.2013, 15:40
попробуйте с матрицей.

Isfet
06.09.2013, 15:58
var matrix:Matrix = new Matrix();
matrix.tx = -rect.width*0.5;
matrix.ty = -rect.height*0.5;
bmd.draw(container,matrix);

не работает придется видать отрисовывать в батмапе контейнер контейнера

Wolsh
06.09.2013, 18:59
Замените функцию private function drawBorderIgnoreFilters(container:Sprite):void
{
var childs:uint = container.numChildren;
for (var i:uint = 0; i < childs; i++)
{
var child:DisplayObject = container.getChildAt(i);
_filtered[child] = child.filters.concat();
child.filters = [];
}
var rect:Rectangle = container.getRect(container);
var matrix:Matrix = new Matrix();
matrix.tx = -rect.x;
matrix.ty = -rect.y;
var bmd:BitmapData = new BitmapData(rect.width, rect.height, true, 0x00000000);
bmd.draw(container, matrix);
_outline = new Bitmap(bmd);
container.addChild(_outline);
_outline.x = rect.x;
_outline.y = rect.y;
_outline.filters = [new DropShadowFilter(0, 45, 0x00FF00, 1, 2, 2, 5, 3, false, true, true)];
for (i = 0; i < childs; i++ )
{
child = container.getChildAt(i);
child.filters = _filtered[child];
}
_isOutlined = true;
}

Bletraut
06.09.2013, 19:33
var matrix:Matrix = new Matrix();
matrix.tx = -rect.width*0.5;
matrix.ty = -rect.height*0.5;
bmd.draw(container,matrix);

не работает придется видать отрисовывать в батмапе контейнер контейнера

Попробуй заменить
var rect:Rectangle = container.getRect(container);
на
var rect:Rectangle = container.getBounds(container);

Isfet
07.09.2013, 09:55
Замените функцию
matrix.tx = -rect.x;
matrix.ty = -rect.y;


значит в правильном направлении я шел) немного не дошел) спасибо за функцию) а то уже начал чилдов всех сдвигать на +=rect.width*0,5; ...