Как правильно нарисовать один векторный объект на определенной позиции другого в ActionScript с учетом позиционирования, прозрачности и т. Д.
Моя идея (как предложено, например, здесь ) заключалась в том, чтобы использовать beginBitmapFill
() и drawRect
() для рисования растровой копии (сделанной с использованием BitmapData.draw
()) одного мувиклипа на . graphics
свойство другого MovieClip, но это оказалось сложнее, чем я думал, в основном по следующим причинам:
Прозрачность не сохраняется : если исходный MovieClip является прозрачным, целевая графика становится белой. Я пытался использовать BlendMode
, но это не помогает. Кажется, белые пиксели на самом деле копируются в BitmapData. Я, должно быть, что-то упускаю, но я не знаю, что. Кажется, проблема заключалась в том, что документация для конструктора BitmapData
неверна: прозрачность по умолчанию не true , а ложь . Так что если вы создаете new BitmapData(x, y, true)
прозрачность сохраняется, в противном случае нет.
Позиционирование . Если исходный MovieClip центрирован (с центром в (0, 0), необходимо применить матрицу, чтобы переместить его при копировании в BitmapData, или растровое изображение будет содержать только правый нижний угол исходного MovieClip. переместить его сложно, и я предполагаю, что это связано с получением границ каким-либо образом (если исходный объект идеально центрирован в пределах его холста, вы, конечно, можете просто сместить его на половину его ширины и высоты.)
beginBitmapFill
плитка . Кажется, что если вы не начнете drawRect
() с (0, 0), заливка растрового изображения не начинается с (0, 0) внутри растрового изображения. Это означает, что вам нужно снова сдвинуть исходное растровое изображение в зависимости от того, где вы хотите начать рисование.
(Тогда есть другие вещи, такие как необходимость lineStyle (0,0,0), поэтому drawRect () не рисует границу и т. Д.)
Все эти хитрые проблемы заставляют меня поверить, что я поступаю неправильно. Есть ли более простой способ сделать это? Где-нибудь есть библиотека, которая может мне помочь? Кто-нибудь успешно сделал это? Возможно, мой холст для рисования должен быть не спрайтом, а растровым изображением? Но тогда я не знаю, как рисовать, используя lineTo
() и т. Д.
Вот ситуация : у меня есть Sprite, в который я рисую, используя его .graphics, используя lineTo () и т. Д. Теперь я хочу использовать MovieClip в качестве кисти при рисовании (или просто разместить копию другого мувиклипа на поверхности рисования), делая другой мувиклип частью графики первого. Я не могу addChild
(), потому что тогда векторная графика не будет взаимодействовать с нарисованной графикой.
РЕДАКТИРОВАТЬ : Тео предоставил рабочее решение, которое отлично работает , за исключением , поскольку он не применяет вращение и масштабирование применяется к объекту DisplayObject, рисуемому на графической поверхности. Это решение Тео :
private function drawOntoGraphics(source : IBitmapDrawable, target : Graphics, position : Point = null) : void
{
position = position == null ? new Point() : position;
var bounds : Rectangle = DisplayObject(source).getBounds(DisplayObject(source));
var bitmapData : BitmapData = new BitmapData(bounds.width, bounds.height, true, 0x00000000);
bitmapData.draw(source, new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y), null, null, null, true);
target.beginBitmapFill(bitmapData, new Matrix(1, 0, 0, 1, bounds.x + position.x, bounds.y + position.y));
target.drawRect(bounds.x + position.x, bounds.y + position.y, bounds.width, bounds.height);
}
Для поддержки вращения и масштабирования, я предполагаю, что необходимо изменить следующее:
-
Matrix
, используемый в draw()
, должен копировать масштабирование и поворот из источника DisplayObject
?
-
Matrix
, используемый в beginBitmapFill()
, должен также копировать это масштабирование и вращение? Или, может быть, это создаст «двойное» масштабирование и вращение?
- Координаты
drawRect()
должны быть изменены, чтобы соответствовать размеру масштабированного и повернутого DisplayObject
? Что значит getBounds()
не будет точным?
РЕДАКТИРОВАТЬ : Вот рабочая реализация, которая поддерживает масштабирование и поворот, сделанные из всех отзывов:
static function DrawOntoGraphics(source:MovieClip, target:Graphics,
position:Point = null):void {
var sourceClass:Class = getDefinitionByName(getQualifiedClassName(source))
as Class;
var sourceCopy:MovieClip = new sourceClass();
sourceCopy.rotation = source.rotation;
sourceCopy.scaleX = source.scaleX;
sourceCopy.scaleY = source.scaleY;
sourceCopy.graphics.clear();
var placeholder:MovieClip = new MovieClip();
placeholder.addChild(sourceCopy);
if (!position)
position = new Point();
var bounds:Rectangle = placeholder.getBounds(placeholder);
var bitmapData:BitmapData = new BitmapData(bounds.width, bounds.height,
true, 0x00000000);
var drawMatrix:Matrix = new Matrix(1, 0, 0, 1, -bounds.x, -bounds.y);
bitmapData.draw(placeholder, drawMatrix);
placeholder.removeChild(sourceCopy);
var fillMatrix:Matrix = new Matrix(1, 0, 0, 1, bounds.x + position.x,
bounds.y + position.y);
target.beginBitmapFill(bitmapData, fillMatrix);
target.lineStyle(0, 0x00000000, 0);
target.drawRect(bounds.x + position.x, bounds.y + position.y,
bounds.width, bounds.height);
target.endFill();
}
Несколько связанный, но не очень горячий вопрос: Как разместить изображение (скажем, PNG) на графике во Flex 3?