From 0d2f641091bb1ac2952a4f6e0e030a6f004880e7 Mon Sep 17 00:00:00 2001 From: Victor Date: Sun, 10 Sep 2017 11:59:05 +0300 Subject: [PATCH] Add examples --- app/build.gradle | 2 +- .../ui/controller/EditorController.java | 70 ++++++++--- .../main/resources/examples/blend-modes.hfx | 80 +++++++++++++ app/src/main/resources/examples/clip-text.hfx | 34 ++++++ .../main/resources/examples/font-awesome.hfx | 43 +++++++ app/src/main/resources/examples/font.hfx | 21 ++++ .../main/resources/examples/hotarufx-logo.hfx | 20 ++++ app/src/main/resources/examples/hsv.hfx | 18 +++ app/src/main/resources/examples/line.hfx | 44 +++++++ app/src/main/resources/examples/rectangle.hfx | 17 +++ .../main/resources/examples/round-rect.hfx | 16 +++ .../main/resources/examples/stroke-ants.hfx | 19 +++ app/src/main/resources/fxml/Editor.fxml | 1 + app/src/main/resources/main.hfx | 113 ++---------------- 14 files changed, 374 insertions(+), 124 deletions(-) create mode 100644 app/src/main/resources/examples/blend-modes.hfx create mode 100644 app/src/main/resources/examples/clip-text.hfx create mode 100644 app/src/main/resources/examples/font-awesome.hfx create mode 100644 app/src/main/resources/examples/font.hfx create mode 100644 app/src/main/resources/examples/hotarufx-logo.hfx create mode 100644 app/src/main/resources/examples/hsv.hfx create mode 100644 app/src/main/resources/examples/line.hfx create mode 100644 app/src/main/resources/examples/rectangle.hfx create mode 100644 app/src/main/resources/examples/round-rect.hfx create mode 100644 app/src/main/resources/examples/stroke-ants.hfx diff --git a/app/build.gradle b/app/build.gradle index 85caa94..6e1b797 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ plugins { } group 'HotaruFX' -version '1.0-SNAPSHOT' +version '0.9.1' mainClassName = 'com.annimon.hotarufx.Main' sourceCompatibility = 1.8 diff --git a/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java b/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java index d77b586..60a1649 100644 --- a/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java +++ b/app/src/main/java/com/annimon/hotarufx/ui/controller/EditorController.java @@ -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(); + 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"; } } diff --git a/app/src/main/resources/examples/blend-modes.hfx b/app/src/main/resources/examples/blend-modes.hfx new file mode 100644 index 0000000..40795c5 --- /dev/null +++ b/app/src/main/resources/examples/blend-modes.hfx @@ -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) diff --git a/app/src/main/resources/examples/clip-text.hfx b/app/src/main/resources/examples/clip-text.hfx new file mode 100644 index 0000000..572bcf7 --- /dev/null +++ b/app/src/main/resources/examples/clip-text.hfx @@ -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) + diff --git a/app/src/main/resources/examples/font-awesome.hfx b/app/src/main/resources/examples/font-awesome.hfx new file mode 100644 index 0000000..29750c6 --- /dev/null +++ b/app/src/main/resources/examples/font-awesome.hfx @@ -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) \ No newline at end of file diff --git a/app/src/main/resources/examples/font.hfx b/app/src/main/resources/examples/font.hfx new file mode 100644 index 0000000..bdefcce --- /dev/null +++ b/app/src/main/resources/examples/font.hfx @@ -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) diff --git a/app/src/main/resources/examples/hotarufx-logo.hfx b/app/src/main/resources/examples/hotarufx-logo.hfx new file mode 100644 index 0000000..71dc42f --- /dev/null +++ b/app/src/main/resources/examples/hotarufx-logo.hfx @@ -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) diff --git a/app/src/main/resources/examples/hsv.hfx b/app/src/main/resources/examples/hsv.hfx new file mode 100644 index 0000000..42f56b8 --- /dev/null +++ b/app/src/main/resources/examples/hsv.hfx @@ -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) diff --git a/app/src/main/resources/examples/line.hfx b/app/src/main/resources/examples/line.hfx new file mode 100644 index 0000000..fc7fbf7 --- /dev/null +++ b/app/src/main/resources/examples/line.hfx @@ -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) diff --git a/app/src/main/resources/examples/rectangle.hfx b/app/src/main/resources/examples/rectangle.hfx new file mode 100644 index 0000000..57aa3d0 --- /dev/null +++ b/app/src/main/resources/examples/rectangle.hfx @@ -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) diff --git a/app/src/main/resources/examples/round-rect.hfx b/app/src/main/resources/examples/round-rect.hfx new file mode 100644 index 0000000..da4e7a7 --- /dev/null +++ b/app/src/main/resources/examples/round-rect.hfx @@ -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) + diff --git a/app/src/main/resources/examples/stroke-ants.hfx b/app/src/main/resources/examples/stroke-ants.hfx new file mode 100644 index 0000000..8199b81 --- /dev/null +++ b/app/src/main/resources/examples/stroke-ants.hfx @@ -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) diff --git a/app/src/main/resources/fxml/Editor.fxml b/app/src/main/resources/fxml/Editor.fxml index 5dcc044..a400399 100644 --- a/app/src/main/resources/fxml/Editor.fxml +++ b/app/src/main/resources/fxml/Editor.fxml @@ -29,6 +29,7 @@ + diff --git a/app/src/main/resources/main.hfx b/app/src/main/resources/main.hfx index 3d47476..18388f7 100644 --- a/app/src/main/resources/main.hfx +++ b/app/src/main/resources/main.hfx @@ -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)