PDA

Просмотр полной версии : MovieClip: Меню Color в Properties


Fogflasher
27.09.2013, 09:58
У Мувиклипа в "Свойствах" есть такое меню:

30028

Но ведь у класса MovieClip нет ни свойства ни метода color.
И у суперклассов вверх по цепочке наследования тоже, вроде бы нет.

Тогда что это, и как к нему программно обратиться?

KumoKairo
27.09.2013, 10:55
Зато есть свойство .transform (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#transform), в котом есть свойство .colorTransform (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/Transform.html#colorTransform) (ColorTransform (http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/geom/ColorTransform.html)), которое определяет оттенок выбранного DO)

Fogflasher
27.09.2013, 11:27
Да, глубоко жёлуди зарыты, спасибо. )

А как же тогда быть, в самом простом случае?
Ну вот есть, например, мувик mc1. Просто через каскад точек врядли-же можно обратится к этому colorTransform, верно?
Нужно, скорее всего, вводить новые экземпляры каких-то промежуточных классов, ну что-то навроде того, как мы действует с TextFormat.

KumoKairo
27.09.2013, 11:48
Да, придется создавать новый ColorTransform объект. Но это довольно приемлимо, если не предполагается создавать анимацию

package {
import flash.display.Sprite;
import flash.display.GradientType;
import flash.geom.ColorTransform;
import flash.events.MouseEvent;

public class ColorTransformExample extends Sprite {
public function ColorTransformExample() {
var target:Sprite = new Sprite();
draw(target);
addChild(target);
target.useHandCursor = true;
target.buttonMode = true;
target.addEventListener(MouseEvent.CLICK, clickHandler)
}
public function draw(sprite:Sprite):void {
var red:uint = 0xFF0000;
var green:uint = 0x00FF00;
var blue:uint = 0x0000FF;
var size:Number = 100;
sprite.graphics.beginGradientFill(GradientType.LINEAR, [red, blue, green], [1, 0.5, 1], [0, 200, 255]);
sprite.graphics.drawRect(0, 0, 100, 100);
}
public function clickHandler(event:MouseEvent):void {
var rOffset:Number = transform.colorTransform.redOffset + 25;
var bOffset:Number = transform.colorTransform.redOffset - 25;
this.transform.colorTransform = new ColorTransform(1, 1, 1, 1, rOffset, 0, bOffset, 0);
}
}
}

Fogflasher
27.09.2013, 13:00
KumoKairo, спасибо за пример.

Кстати, по нажатию кнопки, как я понимаю, каждый раз создается новый экземпляр ColorTransform?
Это нормально? То есть, выходит мы плодим множество экземпляров, которые накапливаются в памяти.
А гарбадж-коллектор не замучается их зачищать, dimarik благославляет такой подход? )))

Просто интересно, почему нельзя было просто создать один экземпляр, и в нем менять значения.

Про анимацию тоже хотел уточнить, но пока не буду. Видимо нельзя этот подход для твинов применять.

KumoKairo
27.09.2013, 14:12
Нет, это не нормально, я всеми руками за пулинг)
Пример не мой, а с сайта адобовского

Я бы поправил и сделал бы так:

package {
import flash.display.Sprite;
import flash.display.GradientType;
import flash.geom.ColorTransform;
import flash.events.MouseEvent;

public class ColorTransformExample extends Sprite {

private var colorTransformInstance:ColorTransform;

public function ColorTransformExample() {
var target:Sprite = new Sprite();
draw(target);
addChild(target);
target.useHandCursor = true;
target.buttonMode = true;
target.addEventListener(MouseEvent.CLICK, clickHandler)
}
public function draw(sprite:Sprite):void {
var red:uint = 0xFF0000;
var green:uint = 0x00FF00;
var blue:uint = 0x0000FF;
var size:Number = 100;
sprite.graphics.beginGradientFill(GradientType.LINEAR, [red, blue, green], [1, 0.5, 1], [0, 200, 255]);
sprite.graphics.drawRect(0, 0, 100, 100);
}
public function clickHandler(event:MouseEvent):void {
var rOffset:Number = transform.colorTransform.redOffset + 25;
var bOffset:Number = transform.colorTransform.redOffset - 25;
if(colorTransformInstance == null)
{
colorTransformInstance = new ColorTransform(1, 1, 1, 1, rOffset, 0, bOffset, 0);
}
else
{
colorTransformInstance.redOffset = rOffset;
colorTransformInstance.blueOffset = bOffset;
}
this.transform.colorTransform = colorTransformInstance;
}
}
}

Твинер скорее всего свой писать придется

Fogflasher
27.09.2013, 14:56
Хм, я вот тут подумал побольше над примером...

И понял, что не догоняю некоторых вещей.

1. Получается, что у нас target напрямую никак с colorTransformInstance и не связан.
То есть, в функции clickHandler этот экземпляр просто сам-на-сам отрабатывает, и всё.

2. Меня не перестает смущать волшебное слово this. Вот и тут... Как его понимать?
Наверное, как-то так:
"Берем экземпляр класса ColorTransformExample, добираемся до его свойства colorTransform и присваиваем этому свойству экземпляр colorTransformInstance."
Хм, ну и... в чем смысл? Причем, мы ведь даже этот экземпляр this не добавляли посредством addChild.

3. Кстати, когда мы написали addChild(target), мы ведь добавили target в экземпляр класса ColorTransformExample, но не на экран, так?

KumoKairo
27.09.2013, 15:08
Ну тут таргет видимо в виде локальной переменной для простоты сделан, это не критично на самом деле. Графику мы рисуем поверх основного спрайта, тинт применяется на все DO внутри спрайта.

Получается, что у нас target напрямую никак с colorTransformInstance и не связан.
В данном случае он связан тем, что находится внутри контейнера, и тинт контейнера распространяет свое действие на все вложенные объекты.

Ключевое слово this. просто указывает на то, что нужно вызвать функцию самого класса ColorTransformExample, в данном случае для понятности просто используется. Что меняем трансформ самого контейнера, а не того объекта, который кликнули.

Берем экземпляр класса ColorTransformExample, добираемся до его свойства colorTransform и присваиваем этому свойству экземпляр colorTransformInstance." Хм, ну и... в чем смысл? Причем, мы ведь даже этот экземпляр this не добавляли посредством addChild.
Экземпляр чего? Там добавляется экземпляр Sprite в конструкторе, и общий тинт в данном случае на него распространяется тоже.

Каждый раз переприсваивать приходится из-за реализации внутреннего сеттера скорее всего, иначе он не обновит внешний вид. Наверное что-то по принципу валидейт-инвалидейт.

Кстати, когда мы написали addChild(target), мы ведь добавили target в экземпляр класса ColorTransformExample, но не на экран, так?
Предполагается, что класс ColorTransformExample - класс документа. Флеш автоматически добавляет класс документа на экран

Fogflasher
27.09.2013, 15:34
Перефразирую то, как я понимаю ход этой программы, с учетом ваших замечаний:

1. Экземпляр класса ColorTransformExample наследует Sprite, и значит автоматически является свойством DisplayObject, и значит автоматически отображается на экране. (Не совсем ясно, по идее для отображения, мы должны написать еще и addChild(this) но этого в коде нет).

2. В конструкторе класса создаем спрайт target и добавляем его в... экземпляр класса ColorTransformExample, вследствие чего он автоматически отображается на экране. (Хотя не очень понятно, почему это так, ведь как замечено в п1, мы не добавляли сам экземпляр ColorTransformExample никуда)

3. Далее в функции clickHandler мы в конечном счете присваиваем заново отформатированный экземпляр colorTransformInstance свойству colorTransform экземпляра ColorTransformExample, чем добиваемся смены цвета на экране. Ну, здесь вроде всё понятно.

KumoKairo
27.09.2013, 15:51
и значит автоматически является свойством DisplayObject
ColorTransformExample - это не свойство, а наследник класса Sprite, который является наследником (не прямым) класса DisplayObject. У DisplayObject нет "свойств" Sprite или ColorTransformExample.
Автоматически на экране отображается только класс документа, все остальное нужно добавлять с помощью .addChild(...)
Не совсем ясно, по идее для отображения, мы должны написать еще и addChild(this) но этого в коде нет
Нельзя добавить объект сам в себя :) И даже если бы можно было бы, от этой операции он на экране не появится. Попробуйте взять какую - нибудь коробочку и положить ее саму в себя.
Еще раз повторюсь - класс ColorTransformExample предполагается как класс документа, он добавляется на экран автоматически. Если у вас другой класс документа, то нужно добавить экземпляр этого класса вручную.

2. В конструкторе класса создаем спрайт target и добавляем его в... экземпляр класса ColorTransformExample, вследствие чего он автоматически отображается на экране. (Хотя не очень понятно, почему это так, ведь как замечено в п1, мы не добавляли сам экземпляр ColorTransformExample никуда)
Еще раз повторюсь - класс ColorTransformExample предполагается как класс документа, он добавляется на экран автоматически. Если у вас другой класс документа, то нужно добавить экземпляр этого класса вручную.

Fogflasher
27.09.2013, 16:42
Спасибо, а то я как-то четко не осознавал того факта, что когда мы прописываем некий класс как Document Class, он автоматически появляется на экране (справедливо только для тех, которые прямо или косвенно наследуются от DisplayObject).