ソース ピクセルおよび出力先ピクセルを結合するアルゴリズムを定義します。
説明
注意事項
例
例: 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}} } } || 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} || 厳密にいえば、これは本当の時間を追跡しません。 || これはアニメーションが利用可能な時にのみ、進みます。 {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 } || 補間量(アルファと呼ばれます)の値を計算する場合、 || 何か変動させるものを作成するためにサイン関数を使います。 || この結果は、-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 } } |