Red [ Author: "Toomas Vooglaid" Date: 2018-07-27 Purpose: {Study of bezier-based tweens} File: %bezier-tweens.red Needs: 'View ] down?: none down1?: none down2?: none down3?: none down4?: none tick: 0 prg: 0 last-y: 400 last-x: 0 height: none ;system/view/auto-sync?: off view lay: layout/flags/options [ text "Duration:" 50x24 _dur: field "200" 50x24 text "Rate:" 30x24 _rate: field "64" 50x24 button "Go" [ tick: 0 bz: draw as-pair 200 _box/size/y reduce [ 'anti-alias 'off 'curve _curve/2 - 100x0 _curve/3 - 100x0 _curve/4 - 100x0 _curve/5 - 100x0 ] last-y: _ctrl1/2/y y-points: collect [ repeat x _dur/data [ x: round/to x * (200.0 / _dur/data) 1 repeat y _box/size/y [ either 0.0.0.0 = pick bz as-pair x y [ either last-y >= y [ last-y: y keep y - 1 break ][ last-y: y last-x: x ] ][ case [ all [x = last-x y - 1 = last-y][ keep last-y - 1 break ] y = _box/size/y [keep none] ] ] ] ] ] if _copy/data [write-clipboard mold y-points] time-step: 200.0 / _dur/data _idx-start: _idx/2/y _drw/rate: _rate/data ] button "Stop" [_drw/rate: none] _copy: check "Copy" ;#### Drawing box at 0x0 _drw: box 500x500 draw [ pen silver _time: line 100x299 100x100 pen black _t1: text 50x88 "" _b1: box 100x100 299x299 pen gray _ctrl1: line 100x299 100x150 _ctrl2: line 299x100 150x100 pen blue line-width 2 _curve: curve 100x299 100x150 150x100 299x100 line-width 1 pen black fill-pen red _circle1: circle 100x150 4 _circle2: circle 150x100 4 fill-pen leaf _circle3: circle 299x100 4 fill-pen gold _circle4: circle 100x299 4 ] on-down [ case [ within? event/offset _circle4/2 - 4 8x8 [down?: down4?: yes] within? event/offset _circle3/2 - 4 8x8 [down?: down3?: yes] within? event/offset _circle2/2 - 4 8x8 [down?: down2?: yes] within? event/offset _circle1/2 - 4 8x8 [down?: down1?: yes] within? event/offset _b1/2 - 0x2 as-pair _b1/3/x - _b1/2/x 5 [ down?: b1-down?: yes ofs: event/offset/y height: _b1/3/y - _b1/2/y ] within? event/offset (as-pair _b1/2/x _b1/3/y - 2) as-pair _b1/3/x - _b1/2/x 5 [ down?: b3-down?: yes ofs: event/offset/y elements: copy [_time] if (as-pair _b1/2/x _b1/3/y) = _circle4/2 [append elements [_circle4 _ctrl1]] if _b1/3 = _circle3/2 [append elements [_circle3 _ctrl2]] ] ] ] on-up [ down?: no down1?: no down2?: no down3?: no down4?: no b1-down?: no b3-down?: no _t1/3: "" ] all-over on-over [ if down? [ either all [ event/offset/x >= 100 event/offset/x <= 299 ][ case [ down1? [_circle1/2: _ctrl1/3: _curve/3: event/offset] down2? [_circle2/2: _ctrl2/3: _curve/4: event/offset] down3? [_circle3/2: _ctrl2/2: _curve/5: event/offset] down4? [ _circle4/2: _ctrl1/2: _curve/2: event/offset _idx/2/y: event/offset/y - 5 _t1/3: form _circle4/2/y ] b1-down? [ delta: event/offset/y - ofs ofs: event/offset/y _t1/3: form event/offset/y _t1/2/y: -8 + _b1/2/y: event/offset/y _b1/3/y: _b1/2/y + height foreach element [_circle1 _circle2 _circle3 _circle4 _idx _time _ctrl1 _ctrl2 _curve][ element: get element element/2/y: element/2/y + delta ] foreach element [_time _ctrl1 _ctrl2 _curve][ element: get element element/3/y: element/3/y + delta ] _curve/4/y: _curve/4/y + delta _curve/5/y: _curve/5/y + delta ] b3-down? [ _t1/3: form event/offset/y _t1/2/y: -8 + _b1/3/y: event/offset/y delta: event/offset/y - ofs ofs: event/offset/y foreach element elements [ switch element [ _circle4 [ _idx/2/y: -5 + _curve/2/y: _curve/2/y + delta ] _circle3 [ _curve/5/y: _curve/5/y + delta ] ] element: get element element/2/y: element/2/y + delta ] ] ] ][ case [ down1? [ _circle1/2: _ctrl1/3: _curve/3: either event/offset/x < 100 [ as-pair 100 event/offset/y ][ as-pair 299 event/offset/y ] ] down2? [ _circle2/2: _ctrl2/3: _curve/4: either event/offset/x < 100 [ as-pair 100 event/offset/y ][ as-pair 299 event/offset/y ] ] down3? [ _circle3/2: _ctrl2/2: _curve/5: either event/offset/x < 100 [ as-pair 100 event/offset/y ][ as-pair 299 event/offset/y ] ] down4? [ _idx/2/y: event/offset/y - 5 _circle4/2: _ctrl1/2: _curve/2: either event/offset/x < 100 [ as-pair 100 event/offset/y ][ as-pair 299 event/offset/y ] ] ] ] ] ] on-time [ either _dur/data >= (tick: tick + 1) [ _time/2/x: _time/3/x: to-integer (tick * time-step) + 100 if pick y-points tick [_idx/2/y: 95 - 100 + pick y-points tick] ;show _drw ][ face/rate: none ] ] ;#### Indicator at 305x0 _box: box 20x400 draw [ fill-pen red _idx: translate 0x295 shape [line 0x5 5x0 15x0 15x10 5x10] ] ][resize][ actors: object [ on-resize: func [face event][ _drw/size: lay/size _box/size/y: lay/size/y ] ] ] ;do-events