Мой коллега Лу, эксперт по динамике, предложил этот аккуратный ответ:
Manipulate[
ControlActive[
Graphics[{LightRed, Circle[{0, 0}, r]},
PlotRange -> {{-1, 1}, {-1, 1}}],
DynamicModule[{exprs = {Red, Circle[{0, 0}, r]}, rr = r},
Graphics[Dynamic[exprs], PlotRange -> {{-1, 1}, {-1, 1}}],
Initialization :> (Pause[1];
AppendTo[exprs, {Red, Disk[{0, 0}, rr]}]; Pause[1];
AppendTo[exprs, {Black, Circle[{0, 0}, rr]}]),
SynchronousInitialization -> False]], {{r, 0.5}, 0, 1}]
Как это работает:
Если не ControlActive, результатом динамического выражения будет DynamicModule
. Код для уточнения графики содержится в опции Initialization
этого DynamicModule. SynchronousInitialization -> False
делает эту инициализацию асинхронной.
Переименование rr = r
в DynamicModule служит двум целям. Во-первых, результат всегда зависит от переменной Manipulate r
. Во-вторых, вы можете проверить rr != r
, чтобы решить, переместил ли пользователь ползунок во время инициализации, и прервать работу раньше, сэкономив время вычислений:
Manipulate[
ControlActive[
Graphics[{LightRed, Circle[{0, 0}, r]},
PlotRange -> {{-1, 1}, {-1, 1}}],
DynamicModule[{exprs = {Red, Circle[{0, 0}, r]}, rr = r},
Graphics[Dynamic[exprs], PlotRange -> {{-1, 1}, {-1, 1}}],
Initialization :> (If[rr =!= r, Abort[]]; Pause[1];
AppendTo[exprs, {Red, Disk[{0, 0}, rr]}]; If[rr =!= r, Abort[]];
Pause[1]; AppendTo[exprs, {Black, Circle[{0, 0}, rr]}]),
SynchronousInitialization -> False]], {{r, 0.5}, 0, 1}]
Надеюсь, это поможет.