mirror of
https://github.com/aNNiMON/HotaruFX.git
synced 2024-09-19 14:14:21 +03:00
Add examples
This commit is contained in:
parent
b29d43a7e3
commit
0d2f641091
@ -5,7 +5,7 @@ plugins {
|
||||
}
|
||||
|
||||
group 'HotaruFX'
|
||||
version '1.0-SNAPSHOT'
|
||||
version '0.9.1'
|
||||
mainClassName = 'com.annimon.hotarufx.Main'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
|
@ -16,6 +16,7 @@ import com.annimon.hotarufx.ui.control.LibraryItem;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.concurrent.Executors;
|
||||
import javafx.application.Platform;
|
||||
@ -32,6 +33,8 @@ import javafx.scene.control.Alert;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ButtonType;
|
||||
import javafx.scene.control.CheckMenuItem;
|
||||
import javafx.scene.control.Menu;
|
||||
import javafx.scene.control.MenuItem;
|
||||
import javafx.scene.control.TextArea;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
@ -47,6 +50,9 @@ import org.fxmisc.richtext.LineNumberFactory;
|
||||
@SuppressWarnings("unused")
|
||||
public class EditorController implements Initializable, DocumentListener {
|
||||
|
||||
@FXML
|
||||
private Menu examplesMenu;
|
||||
|
||||
@FXML
|
||||
private CheckMenuItem syntaxHighlightingItem;
|
||||
|
||||
@ -71,7 +77,7 @@ public class EditorController implements Initializable, DocumentListener {
|
||||
@FXML
|
||||
private void handleMenuNew(ActionEvent event) {
|
||||
documentManager.newDocument();
|
||||
openSample();
|
||||
openExample();
|
||||
updateTitle();
|
||||
}
|
||||
|
||||
@ -249,15 +255,36 @@ public class EditorController implements Initializable, DocumentListener {
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
editor.setParagraphGraphicFactory(LineNumberFactory.get(editor));
|
||||
documentManager = new FileManager();
|
||||
populateExamples();
|
||||
initSyntaxHighlighter();
|
||||
initUndoRedo();
|
||||
initCopyCutPaste();
|
||||
openSample();
|
||||
openExample();
|
||||
editor.getUndoManager().forgetHistory();
|
||||
initializeLibrary();
|
||||
Platform.runLater(editor::requestFocus);
|
||||
}
|
||||
|
||||
private void populateExamples() {
|
||||
val map = new LinkedHashMap<String, String>();
|
||||
map.put("HotaruFX Logo", "hotarufx-logo.hfx");
|
||||
map.put("Font Awesome Icons", "font-awesome.hfx");
|
||||
map.put("HSV Color", "hsv.hfx");
|
||||
map.put("Line", "line.hfx");
|
||||
map.put("Rectangle", "rectangle.hfx");
|
||||
map.put("Round Rectangle", "round-rect.hfx");
|
||||
map.put("Font", "font.hfx");
|
||||
map.put("Text Clipping", "clip-text.hfx");
|
||||
map.put("Blend Modes", "blend-modes.hfx");
|
||||
map.put("Stroke Ants", "stroke-ants.hfx");
|
||||
examplesMenu.getItems().clear();
|
||||
for (val entry : map.entrySet()) {
|
||||
val item = new MenuItem(entry.getKey());
|
||||
item.setOnAction(e -> openExample("/examples/" + entry.getValue()));
|
||||
examplesMenu.getItems().add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private void initSyntaxHighlighter() {
|
||||
val highlightProperty = syntaxHighlightingItem.selectedProperty();
|
||||
highlightProperty.addListener((observable, oldValue, highlightEnabled) -> {
|
||||
@ -333,9 +360,28 @@ public class EditorController implements Initializable, DocumentListener {
|
||||
log.insertText(0, message + System.lineSeparator());
|
||||
}
|
||||
|
||||
private void openSample() {
|
||||
editor.replaceText(
|
||||
"composition(1280, 720, 30)\n" +
|
||||
private void openExample() {
|
||||
openExample(null);
|
||||
}
|
||||
|
||||
private void openExample(String path) {
|
||||
val content = (path != null) ? readProgram(path) : fallbackProgram();
|
||||
editor.replaceText(content);
|
||||
}
|
||||
|
||||
private String readProgram(String path) {
|
||||
try (InputStream is = Main.class.getResourceAsStream(path)) {
|
||||
if (is == null) {
|
||||
return fallbackProgram();
|
||||
}
|
||||
return IOStream.readContent(is);
|
||||
} catch (IOException ioe) {
|
||||
return fallbackProgram();
|
||||
}
|
||||
}
|
||||
|
||||
private String fallbackProgram() {
|
||||
return "composition(1280, 720, 30)\n" +
|
||||
"\n" +
|
||||
"A = circle({\n" +
|
||||
" cx: 0,\n" +
|
||||
@ -348,18 +394,6 @@ public class EditorController implements Initializable, DocumentListener {
|
||||
" .add(300 ms, 200)\n" +
|
||||
" .add(1 sec, 50)\n" +
|
||||
"\n" +
|
||||
"render(A)\n");
|
||||
}
|
||||
|
||||
private String readProgram(String path) {
|
||||
val fallbackProgram = "composition(640, 480, 25)";
|
||||
try (InputStream is = Main.class.getResourceAsStream(path)) {
|
||||
if (is == null) {
|
||||
return fallbackProgram;
|
||||
}
|
||||
return IOStream.readContent(is);
|
||||
} catch (IOException ioe) {
|
||||
return fallbackProgram;
|
||||
}
|
||||
"render(A)\n";
|
||||
}
|
||||
}
|
||||
|
80
app/src/main/resources/examples/blend-modes.hfx
Normal file
80
app/src/main/resources/examples/blend-modes.hfx
Normal file
@ -0,0 +1,80 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
TOP = circle({
|
||||
cx: 0,
|
||||
cy: 100,
|
||||
radius: 100,
|
||||
fill: '#c74747'
|
||||
})
|
||||
RIGHT = circle({
|
||||
cx: 100,
|
||||
cy: 0,
|
||||
radius: 100,
|
||||
fill: '#c7c747'
|
||||
})
|
||||
BOTTOM = circle({
|
||||
cx: 0,
|
||||
cy: -100,
|
||||
radius: 100,
|
||||
fill: '#9bc747'
|
||||
})
|
||||
LEFT = circle({
|
||||
cx: -100,
|
||||
cy: 0,
|
||||
radius: 100,
|
||||
fill: '#47c0c7'
|
||||
})
|
||||
FRONT = circle({
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
radius: 100,
|
||||
fill: '#4754c7',
|
||||
blendMode: "SRC_OVER"
|
||||
})
|
||||
LABEL = text({
|
||||
x: -100,
|
||||
y: -300,
|
||||
halign: "CENTER",
|
||||
valign: "CENTER",
|
||||
text: 'SRC_OVER',
|
||||
fill: 'black',
|
||||
font: 40
|
||||
})
|
||||
|
||||
FRONT@blendMode
|
||||
.add(1 sec, "SRC_ATOP", discrete)
|
||||
.add(2 sec, "ADD", discrete)
|
||||
.add(3 sec, "MULTIPLY", discrete)
|
||||
.add(4 sec, "SCREEN", discrete)
|
||||
.add(5 sec, "OVERLAY", discrete)
|
||||
.add(6 sec, "DARKEN", discrete)
|
||||
.add(7 sec, "LIGHTEN", discrete)
|
||||
.add(8 sec, "COLOR_DODGE", discrete)
|
||||
.add(9 sec, "COLOR_BURN", discrete)
|
||||
.add(10 sec, "HARD_LIGHT", discrete)
|
||||
.add(11 sec, "SOFT_LIGHT", discrete)
|
||||
.add(12 sec, "DIFFERENCE", discrete)
|
||||
.add(13 sec, "EXCLUSION", discrete)
|
||||
.add(14 sec, "RED", discrete)
|
||||
.add(15 sec, "GREEN", discrete)
|
||||
.add(16 sec, "BLUE", discrete)
|
||||
|
||||
LABEL@text
|
||||
.add(1 sec, "SRC_ATOP", discrete)
|
||||
.add(2 sec, "ADD", discrete)
|
||||
.add(3 sec, "MULTIPLY", discrete)
|
||||
.add(4 sec, "SCREEN", discrete)
|
||||
.add(5 sec, "OVERLAY", discrete)
|
||||
.add(6 sec, "DARKEN", discrete)
|
||||
.add(7 sec, "LIGHTEN", discrete)
|
||||
.add(8 sec, "COLOR_DODGE", discrete)
|
||||
.add(9 sec, "COLOR_BURN", discrete)
|
||||
.add(10 sec, "HARD_LIGHT", discrete)
|
||||
.add(11 sec, "SOFT_LIGHT", discrete)
|
||||
.add(12 sec, "DIFFERENCE", discrete)
|
||||
.add(13 sec, "EXCLUSION", discrete)
|
||||
.add(14 sec, "RED", discrete)
|
||||
.add(15 sec, "GREEN", discrete)
|
||||
.add(16 sec, "BLUE", discrete)
|
||||
|
||||
render(TOP, RIGHT, BOTTOM, LEFT, FRONT, LABEL)
|
34
app/src/main/resources/examples/clip-text.hfx
Normal file
34
app/src/main/resources/examples/clip-text.hfx
Normal file
@ -0,0 +1,34 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
CLIP = circle({
|
||||
cx: 400,
|
||||
cy: 0,
|
||||
radius: 80
|
||||
})
|
||||
|
||||
TEXT = text({
|
||||
x: -220,
|
||||
y: 0,
|
||||
text: "HotaruFX",
|
||||
fill: "white",
|
||||
stroke: "black",
|
||||
font: 100,
|
||||
halign: "CENTER",
|
||||
valign: "CENTER",
|
||||
underline: 1,
|
||||
clip: CLIP,
|
||||
css: '
|
||||
-fx-effect: dropshadow(two-pass-box, rgba(0,0,0,0.8), 5, 0, 0.5, 0.25);
|
||||
'
|
||||
})
|
||||
|
||||
CLIP@cx
|
||||
.add(1.2 sec, -210, easeOut)
|
||||
.add(3 sec, 0, ease)
|
||||
CLIP@radius
|
||||
.add(1.2 sec, 80, discrete)
|
||||
.add(3 sec, 300, ease)
|
||||
|
||||
|
||||
render(CLIP, TEXT)
|
||||
|
43
app/src/main/resources/examples/font-awesome.hfx
Normal file
43
app/src/main/resources/examples/font-awesome.hfx
Normal file
@ -0,0 +1,43 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
WE = text({
|
||||
x: -375
|
||||
y: 0
|
||||
valign: "CENTER"
|
||||
text: "\uf0c0"
|
||||
fill: '#292929'
|
||||
font: 200
|
||||
})
|
||||
|
||||
LOVE = text({
|
||||
x: -80
|
||||
y: 0
|
||||
valign: "CENTER"
|
||||
text: "\uf004"
|
||||
fill: '#cf1010'
|
||||
font: 200
|
||||
})
|
||||
LOVE@scaleX
|
||||
.add(200 ms, 1.4, easeOut)
|
||||
.add(600 ms, 1.1, easeOut)
|
||||
LOVE@scaleY
|
||||
.add(200 ms, 1.4, easeOut)
|
||||
.add(600 ms, 1.1, easeOut)
|
||||
|
||||
GITHUB = text({
|
||||
x: 200
|
||||
y: 0
|
||||
valign: "CENTER"
|
||||
text: "\uf09b"
|
||||
fill: '#292929'
|
||||
font: 200
|
||||
})
|
||||
|
||||
G = group(WE LOVE GITHUB)
|
||||
G@rotate
|
||||
.add(1 sec, 0, hold)
|
||||
.add(1800 ms, 360, ease)
|
||||
|
||||
/* note: no commas at all */
|
||||
|
||||
render(G)
|
21
app/src/main/resources/examples/font.hfx
Normal file
21
app/src/main/resources/examples/font.hfx
Normal file
@ -0,0 +1,21 @@
|
||||
composition(1280, 720, 30, "#FAFAFA")
|
||||
|
||||
TEXT = text({
|
||||
x: -250,
|
||||
y: 0,
|
||||
halign: "CENTER",
|
||||
valign: "CENTER",
|
||||
text: 'MULTILINE
|
||||
TEXT
|
||||
EXAMPLE',
|
||||
fill: '#273687',
|
||||
lineSpacing: 50,
|
||||
font: {
|
||||
family: "monospace",
|
||||
weight: "bold",
|
||||
italic: true,
|
||||
size: 100
|
||||
},
|
||||
})
|
||||
|
||||
render(TEXT)
|
20
app/src/main/resources/examples/hotarufx-logo.hfx
Normal file
20
app/src/main/resources/examples/hotarufx-logo.hfx
Normal file
@ -0,0 +1,20 @@
|
||||
composition(1280, 720, 30, "#2F2F2F")
|
||||
|
||||
LOGO = text({
|
||||
x: -250,
|
||||
y: 0,
|
||||
valign: "CENTER",
|
||||
text: 'HotaruFX',
|
||||
fill: '#FDFD42',
|
||||
font: 100,
|
||||
css: '
|
||||
-fx-font-weight: bold;
|
||||
-fx-effect: dropshadow(three-pass-box, rgba(100,183,3,0.8), 18, 0, 0.5, 0.25);
|
||||
'
|
||||
})
|
||||
|
||||
LOGO@fill
|
||||
.add(2 sec, "#82fd42", easeOut)
|
||||
.add(4 sec, "#FDFD42", ease)
|
||||
|
||||
render(LOGO)
|
18
app/src/main/resources/examples/hsv.hfx
Normal file
18
app/src/main/resources/examples/hsv.hfx
Normal file
@ -0,0 +1,18 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
A = circle({
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
radius: 200,
|
||||
fill: '#ff0000'
|
||||
})
|
||||
|
||||
A@fill
|
||||
.add(2 sec, "#ffff00")
|
||||
.add(4 sec, "#00ff00")
|
||||
.add(6 sec, "#00ffff")
|
||||
.add(8 sec, "#0000ff")
|
||||
.add(10 sec, "#ff00ff")
|
||||
.add(12 sec, "#ff0000")
|
||||
|
||||
render(A)
|
44
app/src/main/resources/examples/line.hfx
Normal file
44
app/src/main/resources/examples/line.hfx
Normal file
@ -0,0 +1,44 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
LINE = line({
|
||||
startX: -HalfWidth,
|
||||
startY: -HalfHeight,
|
||||
endX: HalfWidth,
|
||||
endY: HalfHeight,
|
||||
stroke: "#333",
|
||||
strokeWidth: 5
|
||||
})
|
||||
|
||||
LINE@startY
|
||||
.add(2 sec, HalfHeight, ease)
|
||||
.add(4 sec, -HalfHeight, ease)
|
||||
LINE@endY
|
||||
.add(2 sec, -HalfHeight, ease)
|
||||
.add(4 sec, HalfHeight, ease)
|
||||
|
||||
LINE@startX
|
||||
.add(4 sec, -HalfWidth, discrete)
|
||||
.add(6 sec, HalfWidth, ease)
|
||||
.add(8 sec, -HalfWidth, ease)
|
||||
.add(10 sec, HalfWidth, ease)
|
||||
.add(12 sec, -HalfWidth, ease)
|
||||
LINE@endX
|
||||
.add(4 sec, HalfWidth, discrete)
|
||||
.add(6 sec, -HalfWidth, ease)
|
||||
.add(8 sec, HalfWidth, ease)
|
||||
.add(10 sec, -HalfWidth, ease)
|
||||
.add(12 sec, HalfWidth, ease)
|
||||
|
||||
|
||||
LINE@startY
|
||||
.add(8 sec, -HalfHeight, discrete)
|
||||
.add(10 sec, HalfHeight, ease)
|
||||
.add(12 sec, -HalfHeight, ease)
|
||||
LINE@endY
|
||||
.add(8 sec, HalfHeight, discrete)
|
||||
.add(10 sec, -HalfHeight, ease)
|
||||
.add(12 sec, HalfHeight, ease)
|
||||
|
||||
|
||||
|
||||
render(LINE)
|
17
app/src/main/resources/examples/rectangle.hfx
Normal file
17
app/src/main/resources/examples/rectangle.hfx
Normal file
@ -0,0 +1,17 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
A = rectangle({
|
||||
x: -700,
|
||||
y: -75,
|
||||
width: 100,
|
||||
height: 150,
|
||||
fill: '#4233c0'
|
||||
rotate: 0
|
||||
})
|
||||
|
||||
A@rotate
|
||||
.add(2 sec, 720, ease)
|
||||
A@x
|
||||
.add(2 sec, 600, ease)
|
||||
|
||||
render(A)
|
16
app/src/main/resources/examples/round-rect.hfx
Normal file
16
app/src/main/resources/examples/round-rect.hfx
Normal file
@ -0,0 +1,16 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
A = rectangle({
|
||||
x: -100,
|
||||
y: -100,
|
||||
width: 200,
|
||||
height: 200,
|
||||
fill: "green"
|
||||
})
|
||||
A@arcWidth
|
||||
.add(1.5 sec, 100)
|
||||
A@arcHeight
|
||||
.add(1.5 sec, 100)
|
||||
|
||||
render(A)
|
||||
|
19
app/src/main/resources/examples/stroke-ants.hfx
Normal file
19
app/src/main/resources/examples/stroke-ants.hfx
Normal file
@ -0,0 +1,19 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
A = text({
|
||||
x: -450,
|
||||
y: 0,
|
||||
valign: "CENTER",
|
||||
text: 'HotaruFX',
|
||||
fill: "white",
|
||||
stroke: '#37bd2b',
|
||||
strokeWidth: 4,
|
||||
font: 200
|
||||
})
|
||||
|
||||
strokeDashArray(A, [25, 50])
|
||||
|
||||
A@strokeDashOffset
|
||||
.add(5 sec, 500)
|
||||
|
||||
render(A)
|
@ -29,6 +29,7 @@
|
||||
<Menu mnemonicParsing="false" text="File">
|
||||
<MenuItem onAction="#handleMenuNew" text="New" accelerator="Shortcut+N"/>
|
||||
<MenuItem onAction="#handleMenuOpen" text="Open" accelerator="Shortcut+O"/>
|
||||
<Menu fx:id="examplesMenu" text="Open example" mnemonicParsing="false" />
|
||||
<MenuItem onAction="#handleMenuSave" text="Save" accelerator="Shortcut+S"/>
|
||||
<MenuItem onAction="#handleMenuSaveAs" text="Save As" accelerator="Shift+Shortcut+S"/>
|
||||
<MenuItem onAction="#handleMenuExit" text="Exit"/>
|
||||
|
@ -1,111 +1,14 @@
|
||||
composition(1280, 720, 30)
|
||||
|
||||
A = circle({
|
||||
centerX: 0,
|
||||
centerY: 0,
|
||||
radius: 10,
|
||||
fill: "red"
|
||||
cx: 0,
|
||||
cy: 0,
|
||||
radius: 100,
|
||||
fill: '#9bc747'
|
||||
})
|
||||
|
||||
A@radius
|
||||
.add(10, 70)
|
||||
.add(30, 20)
|
||||
A@opacity
|
||||
.add(0.5 sec, 1)
|
||||
.add(1 sec, 0)
|
||||
|
||||
B = rectangle({
|
||||
x: -50,
|
||||
y: -50,
|
||||
width: 100,
|
||||
height: 100,
|
||||
fill: "green"
|
||||
})
|
||||
B@arcWidth
|
||||
.add(28, 0)
|
||||
.add(50, 80)
|
||||
B@arcHeight
|
||||
.add(28, 0)
|
||||
.add(50, 80)
|
||||
|
||||
|
||||
CLIP = circle({
|
||||
cx: -500,
|
||||
cy: -125,
|
||||
radius: 78
|
||||
})
|
||||
CLIP@cx
|
||||
.add(60, -400)
|
||||
.add(100, 173)
|
||||
|
||||
|
||||
C = text({
|
||||
x: -240,
|
||||
y: -100,
|
||||
text: "HotaruFX",
|
||||
fill: "white",
|
||||
stroke: "black",
|
||||
font: 100,
|
||||
underline: 1
|
||||
clip: CLIP,
|
||||
css: '
|
||||
-fx-effect: dropshadow(two-pass-box, rgba(0,0,0,0.8), 5, 0, 0.5, 0.25);
|
||||
'
|
||||
})
|
||||
C@layoutX
|
||||
.add(100, 0)
|
||||
.add(120, -300)
|
||||
C@scaleX
|
||||
.add(100, 1)
|
||||
.add(120, 1.8)
|
||||
C@scaleY
|
||||
.add(100, 1)
|
||||
.add(120, 1.8)
|
||||
|
||||
HEART = svgPath({
|
||||
layoutX: -15,
|
||||
layoutY: -12,
|
||||
content: "M23.6,0c-3.4,0-6.3,2.7-7.6,5.6C14.7,2.7,11.8,0,8.4,0C3.8,0,0,3.8,0,8.4c0,9.4,9.5,11.9,16,21.2
|
||||
6.1-9.3,16-12.1,16-21.2C32,3.8,28.2,0,23.6,0z",
|
||||
fill: "red",
|
||||
strokeWidth: 2,
|
||||
stroke: "white"
|
||||
})
|
||||
|
||||
points = [
|
||||
0, -50,
|
||||
-25, 0,
|
||||
25, 0,
|
||||
0, 50,
|
||||
]
|
||||
POLYGON = polygon(points, {
|
||||
translateX: -300,
|
||||
fill: "purple"
|
||||
})
|
||||
POLYLINE = polyline(points, {
|
||||
translateX: 300,
|
||||
stroke: "purple"
|
||||
})
|
||||
|
||||
LINE = line({
|
||||
visible: false,
|
||||
startX: -600
|
||||
startY: 300
|
||||
endX: 600
|
||||
endY: 300,
|
||||
stroke: "#777",
|
||||
strokeDashOffset: 45
|
||||
})
|
||||
LINE@visible.add(100, true)
|
||||
LINE@strokeWidth.add(100, 0).add(140, 10)
|
||||
|
||||
arcRadius = 200
|
||||
ARC = arc({
|
||||
cy: 295
|
||||
radiusX: arcRadius,
|
||||
radiusY: arcRadius,
|
||||
fill: "yellow"
|
||||
})
|
||||
ARC@length.add(140, 0).add(160, 180)
|
||||
|
||||
render(ARC, B, A, C, CLIP, HEART, POLYGON, POLYLINE, LINE)
|
||||
.add(300 ms, 200)
|
||||
.add(1 sec, 50)
|
||||
|
||||
render(A)
|
||||
|
Loading…
Reference in New Issue
Block a user