1
0
mirror of https://github.com/aNNiMON/HotaruFX.git synced 2024-09-19 14:14:21 +03:00

Add examples

This commit is contained in:
Victor 2017-09-10 11:59:05 +03:00
parent b29d43a7e3
commit 0d2f641091
14 changed files with 374 additions and 124 deletions

View File

@ -5,7 +5,7 @@ plugins {
}
group 'HotaruFX'
version '1.0-SNAPSHOT'
version '0.9.1'
mainClassName = 'com.annimon.hotarufx.Main'
sourceCompatibility = 1.8

View File

@ -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";
}
}

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View 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)

View File

@ -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"/>

View File

@ -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)