/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
* Copyright 2008, 2010 Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*
* This file is available and licensed under the following license:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Oracle Corporation nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package effectsplayground;
import javafx.scene.*;
import javafx.scene.effect.*;
import javafx.scene.effect.light.*;
import javafx.scene.image.*;
import javafx.scene.paint.*;
import javafx.scene.text.*;
import javafx.stage.*;
import java.lang.Math.*;
import effectsplayground.control.*;
import effectsplayground.Main.Preview;
package class EffectControl {
public var previewNode:Preview;
public var controlsGroup:Node;
public var canvasEffect:Effect;
public var canvasImage:Node = ImageView {
smooth: true
effect: bind canvasEffect
image: bind Main.fgImage
};
public var thumbEffect:Effect;
public var thumbImage:Node = ImageView {
effect: bind thumbEffect
image: bind Main.fgThumb
}
}
class ModeButton extends RadioButton {
var mode:BlendMode = BlendMode.ADD;
}
package class BlendControl extends EffectControl {
var slider:LabeledSlider;
def bg = ButtonGroup { };
override public var canvasImage = Group {
var selMode = bind (bg.selectedButton as ModeButton).mode;
blendMode: bind if (selMode != null) selMode else BlendMode.MULTIPLY
content: [
ImageView {
smooth: true
translateX: bind (Main.fgImage.width/2) - (Main.bgImage.width/2)
translateY: bind (Main.fgImage.height/2) - (Main.bgImage.height/2)
image: bind Main.bgImage
}
ImageView {
smooth: true
image: bind Main.fgImage
opacity: bind slider.value
},
]
};
override public var thumbImage = Group {
blendMode: BlendMode.MULTIPLY
content: [
ImageView {
translateX: bind (Main.fgImage.width/2) - (Main.bgImage.width/2)
translateY: bind (Main.fgImage.height/2) - (Main.bgImage.height/2)
image: bind Main.bgThumb
},
ImageView {
image: bind Main.fgThumb
opacity: 0.5
}
]
};
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Opacity"
value: 0.5
padding: 90
},
ModeButton {
translateX: 290
translateY: 15
bg: bind bg
text: "Multiply"
mode: BlendMode.MULTIPLY
selected: true
},
ModeButton {
translateX: 290
translateY: 35
bg: bind bg
text: "Screen"
mode: BlendMode.SCREEN
},
ModeButton {
translateX: 370
translateY: 15
bg: bind bg
text: "Overlay"
mode: BlendMode.OVERLAY
},
ModeButton {
translateX: 370
translateY: 35
bg: bind bg
text: "Hard Light"
mode: BlendMode.HARD_LIGHT
},
ModeButton {
translateX: 460
translateY: 15
bg: bind bg
text: "Difference"
mode: BlendMode.DIFFERENCE
},
ModeButton {
translateX: 460
translateY: 35
bg: bind bg
text: "Exclusion"
mode: BlendMode.EXCLUSION
},
]
};
}
package class BlurControl extends EffectControl {
var slider:LabeledSlider;
override public var canvasEffect = GaussianBlur {
radius: bind if (slider.value < 1) 1 else slider.value
};
override public var thumbEffect = GaussianBlur { radius: 5 };
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Radius"
minimum: 1
maximum: 63
value: 10
padding: 90
}
]
};
}
package class MotionBlurControl extends EffectControl {
var slider:LabeledSlider;
var knob:LabeledKnob;
override public var canvasEffect = MotionBlur {
radius: bind if (slider.value < 1) 1 else slider.value
angle: bind knob.value
};
override public var thumbEffect = MotionBlur { radius: 5 angle: 45 };
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Radius"
minimum: 1
maximum: 63
value: 10
padding: 90
},
knob = LabeledKnob {
translateX: 320
translateY: 20
text: "Angle"
minimum: -90.0
maximum: 90.0
value: 45.0
minAngle: -90.0
maxAngle: 90.0
}
]
};
}
package class BloomControl extends EffectControl {
var slider:LabeledSlider;
override public var canvasEffect = Bloom {
threshold: bind slider.value
};
override public var thumbEffect = Bloom { threshold: 0.0 };
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Threshold"
value: 0.0
}
]
};
}
package class GlowControl extends EffectControl {
var slider:LabeledSlider;
override public var canvasEffect = Glow {
level: bind slider.value
};
override public var thumbEffect = Glow { level: 0.7 };
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Level"
value: 0.7
padding: 90
}
]
};
}
package class ColorAdjustControl extends EffectControl {
var bslider:LabeledSlider;
var cslider:LabeledSlider;
var hslider:LabeledSlider;
var sslider:LabeledSlider;
override public var canvasEffect = ColorAdjust {
brightness: bind bslider.value
contrast: bind if (cslider.value < 0.25) 0.25 else cslider.value
hue: bind hslider.value
saturation: bind sslider.value
};
override public var thumbEffect = ColorAdjust { hue: -1 };
override public var controlsGroup = Group {
content: [
bslider = LabeledSlider {
translateX: 15
translateY: 12
text: "Brightness"
minimum: -1
maximum: 1
value: 0
},
cslider = LabeledSlider {
translateX: 15
translateY: 32
text: "Contrast"
minimum: 0.25
maximum: 4.00
value: 1.00
},
hslider = LabeledSlider {
translateX: 290
translateY: 12
text: "Hue"
minimum: -1
maximum: 1
value: -1
},
sslider = LabeledSlider {
translateX: 290
translateY: 32
text: "Saturation"
minimum: -1
maximum: 1
value: 0
},
]
};
}
package class ShadowControl extends EffectControl {
def width = 80;
def pad = 85;
var rslider:LabeledSlider;
var xslider:LabeledSlider;
var yslider:LabeledSlider;
var picker:ColorPicker;
override public var thumbImage = ImageView {
effect: bind thumbEffect
image: bind Main.fgThumb
x: 0
y: 6
fitHeight: bind Main.fgThumb.height*0.7
preserveRatio: true
}
override public var controlsGroup = Group {
content: [
rslider = LabeledSlider {
translateX: 15
translateY: 12
text: "Radius"
minimum: 1
maximum: 63
value: 10
width: bind width
padding: bind pad
},
xslider = LabeledSlider {
translateX: 195
translateY: 12
text: "X Offset"
minimum: -20
maximum: 20
value: 4
width: bind width
padding: bind pad
},
yslider = LabeledSlider {
translateX: 375
translateY: 12
text: "Y Offset"
minimum: -20
maximum: 20
value: 4
width: bind width
padding: bind pad
},
Text {
translateX: 15
translateY: 44
content: "Color"
font:Font { size: 10 }
fill: Color.WHITE
},
picker = ColorPicker {
translateX: 60
translateY: 32
}
]
};
}
package class DropShadowControl extends ShadowControl {
override public var canvasEffect = DropShadow {
radius: bind if (rslider.value < 1) 1 else rslider.value
offsetX: bind xslider.value
offsetY: bind yslider.value
color: bind if (picker.selectedColor != null) picker.selectedColor else Color.BLACK
};
override public var thumbEffect = DropShadow { spread: 0.2 };
}
package class InnerShadowControl extends ShadowControl {
override public var canvasEffect = InnerShadow {
radius: bind if (rslider.value < 1) 1 else rslider.value
offsetX: bind xslider.value
offsetY: bind yslider.value
color: bind if (picker.selectedColor != null) picker.selectedColor else Color.BLACK
};
override public var thumbEffect = InnerShadow { choke: 0.2 };
}
package class PerspectiveControl extends EffectControl {
var slider:LabeledSlider;
function getTransform(angle:Number, imgWidth:Number, imgHeight:Number, yoff:Number):PerspectiveTransform {
PerspectiveTransform {
var ox = 0;
var oy = yoff;
var pw = imgWidth;
var ph = imgHeight;
var radius = pw/2;
var back = ph/10;
var t = toRadians(angle);
ulx: ox+radius-sin(t)*radius
uly:oy+0 -cos(t)*back
urx: ox+radius+sin(t)*radius
ury:oy+0 +cos(t)*back
lrx: ox+radius+sin(t)*radius
lry:oy+ph-cos(t)*back
llx: ox+radius-sin(t)*radius
lly:oy+ph+cos(t)*back
}
}
override public var canvasEffect =
bind getTransform(slider.value, Main.fgImage.width, Main.fgImage.height, 0);
override public var thumbEffect =
bind getTransform(30.0, Main.fgThumb.width*0.7, Main.fgThumb.height*0.7, 7);
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Angle"
value: 60.0
minimum: 0.0
maximum: 360.0
padding: 90
}
]
};
}
package class LightingControl extends EffectControl {
def width = 60;
var dcSlider:LabeledSlider;
var ssSlider:LabeledSlider;
var scSlider:LabeledSlider;
var seSlider:LabeledSlider;
var aKnob:LabeledKnob;
var eKnob:LabeledKnob;
override public var canvasEffect = Lighting {
light: DistantLight {
azimuth: bind aKnob.value
elevation: bind eKnob.value
}
surfaceScale: bind ssSlider.value
diffuseConstant: bind dcSlider.value
specularConstant: bind scSlider.value
specularExponent: bind seSlider.value
};
override public var thumbEffect = Lighting { };
override public var controlsGroup = Group {
content: [
dcSlider = LabeledSlider {
translateX: 15
translateY: 12
text: "Diffuse"
value: 1.0
minimum: 0.0
maximum: 2.0
width: bind width
padding: 75
},
ssSlider = LabeledSlider {
translateX: 15
translateY: 32
text: "Scale"
value: 1.5
minimum: 0.0
maximum: 10.0
width: bind width
padding: 75
},
scSlider = LabeledSlider {
translateX: 170
translateY: 12
text: "Specular Con"
value: 0.3
minimum: 0.0
maximum: 2.0
width: bind width
padding: 110
},
seSlider = LabeledSlider {
translateX: 170
translateY: 32
text: "Specular Exp"
value: 20.0
minimum: 0.0
maximum: 40.0
width: bind width
padding: 110
},
aKnob = LabeledKnob {
translateX: 395
translateY: 20
text: "Azimuth"
value: 45.0
minimum: 0.0
maximum: 360.0
minAngle: 0.0
maxAngle: 360.0
},
eKnob = LabeledKnob {
translateX: 480
translateY: 20
text: "Elevation"
value: 45.0
minimum: 0.0
maximum: 90.0
minAngle: -90.0
maxAngle: 0.0
},
]
};
}
package class SepiaControl extends EffectControl {
var slider:LabeledSlider;
override public var canvasEffect = SepiaTone {
level: bind slider.value
};
override public var thumbEffect = SepiaTone { };
override public var controlsGroup = Group {
content: [
slider = LabeledSlider {
translateX: 15
translateY: 22
text: "Level"
value: 1.0
padding: 90
}
]
};
}
package class ReflectionControl extends EffectControl {
var fractionSlider:LabeledSlider;
var topOffsetSlider:LabeledSlider;
var topOpacitySlider:LabeledSlider;
var botOpacitySlider:LabeledSlider;
def width = 120;
override public var canvasEffect = Reflection {
fraction: bind fractionSlider.value
topOffset: bind topOffsetSlider.value
topOpacity: bind topOpacitySlider.value
bottomOpacity: bind botOpacitySlider.value
};
override public var canvasImage = ImageView {
effect: bind canvasEffect
image: bind Main.fgImage
smooth: true
fitHeight: bind Main.fgImage.height*0.7
preserveRatio: true
};
override public var thumbEffect = Reflection {
topOffset: 1
fraction: 0.4
}
override public var thumbImage = ImageView {
effect: bind thumbEffect
image: bind Main.fgThumb
x: 0
y: 3
fitHeight: bind Main.fgThumb.height*0.6
preserveRatio: true
}
override public var controlsGroup = Group {
content: [
fractionSlider = LabeledSlider {
translateX: 15
translateY: 12
text: "Fraction"
value: 0.4
width: bind width
},
topOffsetSlider = LabeledSlider {
translateX: 15
translateY: 32
text: "Top Offset"
minimum: 0.0
maximum: 20.0
value: 3.0
width: bind width
},
topOpacitySlider = LabeledSlider {
translateX: 260
translateY: 12
text: "Top Opacity"
value: 0.5
padding: 130
width: bind width
},
botOpacitySlider = LabeledSlider {
translateX: 260
translateY: 32
text: "Bottom Opacity"
value: 0.0
padding: 130
width: bind width
},
]
};
}
function run() {
var ec = LightingControl { };
Stage {
width: 600
height: 300
scene:Scene {
fill: Color.BLACK
content: [
ec.controlsGroup
]
}
}
}