ソース ピクセルおよび出力先ピクセルを結合するアルゴリズムを定義します。
説明
注意事項
例

| 例: Renderer2dGraphic を用いた高度な DrawOperation の使用 | |
![]() | |
||filter-pixmap と scaleにアクセスする必要があります。
{import * from CURL.GRAPHICS.IMAGEFILTER}
{let background:FillPattern =
{FillPattern {url "curl://install/docs/default/images/grass.jpg"}}
}
|| .JPGイメージからPixmapを設定します。 保存されているjpgは、大きすぎるので
|| もっと小さくしましょう。
{let our-pixmap:Pixmap =
{filter-pixmap
scale,
scale = 50%,
{Pixmap.from-url
{url "curl://install/docs/default/images/adria.jpg"}
}
}
}
{set our-pixmap.ignore-alpha? = false}
|| 中心では完全に(100%)不透明で、端にむかって徐々に
|| 透過するようにpixmapを設定します。
|| 処理が早いので、doubleではなくて
|| floatを使用し続けることに注意してください
{let half-shortest-dimension:int =
{min our-pixmap.width, our-pixmap.height} div 2
}
{for-pixel pixel at x, y in our-pixmap do
let delta-x-from-center:int =
(x - our-pixmap.width div 2)
let delta-y-from-center:int =
(y - our-pixmap.height div 2)
let distance-from-center:float =
{sqrt
((delta-x-from-center * delta-x-from-center) +
(delta-y-from-center * delta-y-from-center))
asa float
} asa float
let alpha:float =
1.0f - (distance-from-center / half-shortest-dimension)
|| alpha may be negative, since it's possible
|| for distance-from-center to be greater than
|| half-shortest-dimension. We'll clamp it to 0, below.
set pixel =
{Pixel.from-float
pixel.red,
pixel.green,
pixel.blue,
alpha = {min 1, {max 0, alpha}}
}
}
|| Create a FillPattern from the Pixmap. If we don't do this then our
|| call to render-rectangle below will implicitly create a FillPattern
|| every time we call it.
|| PixmapからFillPatternを作成します。これを作成しない場合、以下の
|| render-rectangleの呼び出しは、それが呼び出される度に暗黙的にFillPattern
|| を作成します。
{let our-fillpattern:FillPattern = {FillPattern.from-pixmap our-pixmap}}
|| pixmapの位置は、左から右、上から下に変動します。
|| また、それは時間とともに回転します。
|| ここで、位置の計算に使われる変数を定義します。
{let constant pixmap-horizontal-period:Time = 6s}
{let constant pixmap-vertical-period:Time = 2.5s}
{let constant pixmap-rotation-period:Time = 1.29s}
{let constant pixmap-min-rotation-angle:Angle = -20deg}
{let constant pixmap-max-rotation-angle:Angle = 20deg}
|| This does not, strictly speaking, track "real" time.
|| It only advances when animation is enabled.
|| 厳密にいえば、これは本当の時間を追跡しません。
|| これはアニメーションが利用可能な時にのみ、進みます。
{let animation-time:Time = 0s}
{define-proc package {redraw-proc
rg:Renderer2dGraphic,
r2d:Renderer2d,
dirty-area:#RectangleSet
}:void
let drawable:Drawable = {non-null rg.drawable}
|| First, clear drawable using a FillPattern
{r2d.render-rectangle
0m, 0m,
drawable.width, drawable.height,
fill-pattern = background
}
let pixmap-size:Distance2d =
{Distance2d
r2d.pixel-size * our-pixmap.width,
r2d.pixel-size * our-pixmap.height
}
|| In calculating the value for the interpolation quantity
|| (sometimes called alpha), we use the sine function to
|| generate something which oscillates. The result is from
|| -1 to 1, so we adjust it to be from 0 to 1 (as interpolate
|| wants it to be).
|| 補間量(アルファと呼ばれます)の値を計算する場合、
|| 何か変動させるものを作成するためにサイン関数を使います。
|| この結果は、-1から1の間になります。ですから(補間にあうように)
|| これを0から1に調整します。
let pixmap-pos:Distance2d =
{Distance2d
{interpolate
0m,
(1 + {sin (animation-time / pixmap-horizontal-period) * 360deg}) / 2,
drawable.width
},
{interpolate
0m,
(1 + {sin (animation-time / pixmap-vertical-period) * 360deg}) / 2,
drawable.height
}
}
let pixmap-angle:Angle =
{interpolate
pixmap-min-rotation-angle,
(1 + {sin (animation-time / pixmap-rotation-period) * 360deg}) / 2,
pixmap-max-rotation-angle
}
|| 透過の為に、後ろから前への順序でオブジェクトを描画する必要が
|| あります。これは、各操作があて先(既に描画されている)ピクセル
|| を元の(これから描画される)ピクセルと混合させるので
|| この発生順序は重要です。
|| 幸いなことに、すでにbackgroundを描画しています。
{with-render-properties
|| Try different DrawOperations! add and
|| accumulate are interesting in particular.
draw-operation = DrawOperation.blend,
translation = pixmap-pos,
rotation = pixmap-angle,
translation = -0.5 * pixmap-size
on r2d do
{r2d.render-rectangle
0m,
0m,
pixmap-size.x,
pixmap-size.y,
fill-pattern = our-fillpattern
}
}
}
{let graphic:Renderer2dGraphic =
{Renderer2dGraphic
width = 3in,
height = 2in,
repaint-handler = redraw-proc,
advanced-draw-operations? = true
}
}
{value graphic}
|| これは、アニメーションのスタートをマークします。
|| アニメーションを停止させるためだけに使います。
|| (ずっとアニメーションを動かしたままにしたくないので)
{let animation-start-time:DateTime = {DateTime}}
{let constant timer-duration:Time = 20s}
{let constant timer-frequency:Frequency = 20fps}
|| これは、アニメーションの”最後”の時間をマークします。
|| どの位、時間が経過したかを知るために使います。
|| これはアニメーションのフレームを描画した最後の時間だからです。
|| これは、アニメーション時間の値をどのくらい進めるのか知る方法です。
{let last-animation-time:DateTime = {DateTime}}
{let timer:Timer =
{Timer
enabled? = false,
frequency = timer-frequency,
{on TimerEvent do
let time-now:DateTime = {DateTime}
let time-elapsed:Time = {last-animation-time.elapsed ending=time-now}
set last-animation-time = time-now
{inc animation-time, time-elapsed}
{graphic.update-drawable}
{if {animation-start-time.elapsed} > timer-duration then
set timer.enabled? = false
}
}
}
}
{CommandButton
label = "Start animation!",
{on Action do
|| Reset the animation
set last-animation-time = {DateTime}
|| Reset our "animation start" timer
set animation-start-time = last-animation-time
|| Enable the timer
set timer.enabled? = true
}
}
|