rebol [ Title: "REBOL Stargate" File: %rebol-stargate.r Date: 21-Dec-2005 Version: 1.0.2 Progress: 0.4 Status: "working" Needs: [View] License: "MIT" ; see http://www.rebol.com/docs/bsd-mit-license.html Author: "Anton Rolls" Language: "English" Purpose: {Make a swirling zooming effect similar to visual} Usage: {} History: [ 1.0.0 [19-Dec-2005 {First version, testing on View 1.3.2} "Anton"] 1.0.1 [21-Dec-2005 {using key hole, as alpha hole isn't working, logo ellipse size changes on resize and matches alpha hole size, added control-window with scrollers etc. to control each of the variables; using ARC instead of ELLIPSE in order to control angle where the pen-image starts rather than the angle of the whole ellipse, and this keeps the alpha/key hole the same shape as the pen-image; moved code from feel into pic/refresh and init} "Anton"] 1.0.2 [22-Dec-2005 {migrated from face/effect/draw to DRAW function, migrated variables and the generalised redraw function into the stargate context} "Anton"] ] ToDo: { - make it into a general image drawing function, then a regular face can use that function to update its image, leaving its effect block to lighten etc in a non-recursive way. (internally it will use a face to use the effect dialect.) - right-click toggles control window, left-click used for direct control of certain parameters - control-window scrollers etc - initial value - show value textually OR (hard) accompanying fields show and allow user to change the value OR use integer/decimal-edit - alpha hole is not working as I intended it to. Investigation reveals that PEN and FILL-PEN do not draw alpha channel :( - parameter preference settings - one for Dr WHO - undo/redo for parameters (that's basically back/forward buttons) - dialect for specifying variable parameter controls eg: a variable is a decimal with the range [-0.5,2.5], this is mapped to a scroller - invert selected parameters - snapshot and playback (just save parameters and image at start position, that should be enough to recreate) - smooth transitions from one parameter set to another - using a scroller - later: save as sequence of PNG images - compressed formats (try difference trick etc.) - use this face/image as the fill-pen for a sine-text scroller ? - wrap result image onto faces simulating a 3D object (eg. box) Need to calculate coordinates of vertices - mirrors, bouncing balls (use image saving to create animated opening/closing flowers, then constrain to a circle and rotate for spinning balls) - try to get the "orbiting" effect in a more clean mathematical manner ? - colour requesters should not freeze the action, they should have more options (someone made one) } Notes: { http://www.rebol.com/view/demos/rzoom.r http://www.rebol.com/view/demos/reb-circle.r http://www.rebol.com/view/demos/convolve.r http://www.lexicon.net/antonr/rebol/demo/text-swirl-fade.r Dr WHO tunnel: draw the circle behind the face/image, which should have a hole in it to (partially) expose the circle. I think that is a big problem when it comes to applying alpha; the draw dialect doesn't implement it yet. I'm currently applying alpha and it is causing a very trippy effect. I think this might be an unintentional side effect of the half-implemented image drawing in AGG draw. } ] initial-size: 250x250 stargate: context [ tick: 0 ; frame counter pen-image: logo.gif rotation: -2 ; in degrees zoom-x: zoom-y: 1.1 bulk-alpha: 14 img: none ;img/alpha: 128 hole-pen: 55.49.22 hole-fill: 0.0.0.120 stars?: yes star-col: 255.255.255.0 size: none cen: none initialize: func [image [image!]][ img: image size: img/size cen: size / 2 draw-blk: compose/deep draw-blk ] draw-blk: [ translate (cen) pen pen-image arc 0x0 (size / 8x8) 0 361 reset-matrix transform (cen) rotation zoom-x zoom-y 0x0 image (img) 1x1 (size) ;hole-fill ; use hole-fill as key colour ] ; draw a hole using a color (hole-fill) to be keyed later (or alpha channel could merge) hole-blk: [pen hole-pen fill-pen hole-fill ellipse () ()] redraw: func [image /local sine-tick rot dx dy][ ; Copy image ;img: image img: copy image ; start with old image (causes more colour overflow effects) ;img: make image! image/size ; start blank size: img/size cen: size / 2 ; Set variables into the draw block draw-blk/transform: cen sine-tick: sine tick rot: 50 * sine (tick * 10.0 * sine-tick - 20 ) change change skip find draw-blk 'arc 3 rot 361 dx: pen-image/size/y / 3 * cosine (tick * 8.0) dy: pen-image/size/y / 3 * sine (tick * -8.0) draw-blk/translate: cen + as-pair dx dy change skip find draw-blk 'arc 2 (size / 8x8) ; when size changes ; Modify IMG draw img draw-blk ; draw the old img, transformed, into this new one img/alpha: bulk-alpha ; hole in the middle of the image change change next find hole-blk 'ellipse cen (size / 8x8) draw img hole-blk draw-blk/image: img change skip find draw-blk 'image 3 size if stars? [ ;star-col/4: random 100 ; alpha transparency up to 100 (<- not 100% sure it does what I want) poke img (-1x-1 + random size) star-col ; a pixel is a "star" ] tick: tick + 1 img ] make-colour-box-action: func [action [block!]][ compose/deep [ use [col][if col: request-color/color face/color [face/color: col show face (action)]] ] ] control-panel-spec: [ style hscroller scroller 300x20 style colour-box box 40x30 edge [size: 2x2 color: black] across label "rotate:" hscroller [rotation: face/data - 0.5 * 720] with [data: 0.5] return label "zoom-x:" hscroller [zoom-x: face/data * 2 + 0.5] with [data: zoom-x - 0.5 / 2] return label "zoom-y:" hscroller [zoom-y: face/data * 2 + 0.5] with [data: zoom-y - 0.5 / 2] return label "alpha:" hscroller [bulk-alpha: min 255 to-integer face/data * 256] with [data: bulk-alpha / 256] return label "hole pen:" colour-box (hole-pen) (make-colour-box-action [hole-pen: face/color]) label "hole fill:" colour-box (hole-fill) (make-colour-box-action [hole-fill: face/color]) check-line "key hole-fill" [change skip find draw-blk 'image 4 all [face/data in stargate 'hole-fill]] with [data: 'hole-fill = pick skip find draw-blk 'image 4 1] return check-line "stars" [stars?: face/data] with [data: stars?] return ;bar 300 return ;label "emitter movement" return ] ] control-window: center-face layout [ panel (stargate/control-panel-spec) bar 300 style hscroller scroller 300x20 across chk-luma: check-line "luma" [toggle-effect [luma 0] scr-luma] scr-luma: hscroller with [data: 0.5][if find pic/effect 'luma [pic/effect/luma: to-integer face/data * 2 - 1 * 255]] return chk-contrast: check-line "contrast" [toggle-effect [contrast 0] scr-contrast] scr-contrast: hscroller [if find pic/effect 'contrast [pic/effect/contrast: to-integer face/data * 255]] return chk-multiply: check-line "multiply" [toggle-effect [multiply 0] scr-multiply] scr-multiply: hscroller with [data: 0.5][if find pic/effect 'multiply [pic/effect/multiply: to-integer face/data * 255]] ] toggle-effect: func [default [block!] scr [object!] "scroller face"][ either find pic/effect default/1 [remove/part find pic/effect default/1 2][append pic/effect default] do-face scr none ] view/new/options window: center-face layout [ backcolor black origin 0 pic: image (initial-size) (copy logo.gif) rate 48 edge none feel [ engage: func [face action event][ if action = 'time [ if face/size <> face/image/size [ ; size changed ;face/image: to-image face ; new image with new size ; or can stretch the old image to the new size face/image: draw make image! face/size compose [ image (face/image) 1x1 (face/size) ] ; or could just center the old image ;face/image: draw make image! face/size compose [ ; image (face/image) (face/size - face/image/size / 2) ;] ] face/image: stargate/redraw face/image show face ] if action = 'up [ ; toggle control window either viewed? control-window [ unview/only control-window ][ view/new/title/offset control-window "control window" ( ;;window/offset - (control-window/size * 1x0) + (window/size - control-window/size * 0x1 / 2) window/offset + ((window/size * 0x1 / 2) - (control-window/size / 1x2)) - 6x0 ) ] ] ] ] ] 'resize window/feel: make window/feel [ detect: func [face event][ if event/type = 'resize [pic/size: window/size] if event/type = 'close [unview/all] ; <- key handler was 'ere :) event ; allow event to continue ] ] stargate/initialize pic/image do-events