Automatically resize Canvas to fill the enclosing Parent











up vote
13
down vote

favorite












I recently wanted to create an animated background in JavaFX, similar to the Swing example seen here. I used a Canvas on which to draw, as shown in Working with the Canvas API, and an AnimationTimer for the drawing loop, as shown in Animation Basics. Unfortunately, I'm not sure how to resize the Canvas automatically as the enclosing Stage is resized. What is a good approach?



image










share|improve this question




























    up vote
    13
    down vote

    favorite












    I recently wanted to create an animated background in JavaFX, similar to the Swing example seen here. I used a Canvas on which to draw, as shown in Working with the Canvas API, and an AnimationTimer for the drawing loop, as shown in Animation Basics. Unfortunately, I'm not sure how to resize the Canvas automatically as the enclosing Stage is resized. What is a good approach?



    image










    share|improve this question


























      up vote
      13
      down vote

      favorite









      up vote
      13
      down vote

      favorite











      I recently wanted to create an animated background in JavaFX, similar to the Swing example seen here. I used a Canvas on which to draw, as shown in Working with the Canvas API, and an AnimationTimer for the drawing loop, as shown in Animation Basics. Unfortunately, I'm not sure how to resize the Canvas automatically as the enclosing Stage is resized. What is a good approach?



      image










      share|improve this question















      I recently wanted to create an animated background in JavaFX, similar to the Swing example seen here. I used a Canvas on which to draw, as shown in Working with the Canvas API, and an AnimationTimer for the drawing loop, as shown in Animation Basics. Unfortunately, I'm not sure how to resize the Canvas automatically as the enclosing Stage is resized. What is a good approach?



      image







      java animation javafx resize






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited May 23 '17 at 12:34









      Community

      11




      11










      asked Aug 1 '15 at 11:35









      trashgod

      186k16139692




      186k16139692
























          3 Answers
          3






          active

          oldest

          votes

















          up vote
          11
          down vote



          accepted










          In the example below, the static nested class CanvasPane wraps an instance of Canvas in a Pane and overrides layoutChildren() to make the canvas dimensions match the enclosing Pane. Note that Canvas returns false from isResizable(), so "the parent cannot resize it during layout," and Pane "does not perform layout beyond resizing resizable children to their preferred sizes." The width and height used to construct the canvas become its initial size. A similar approach is used in the Ensemble particle simulation, Fireworks.java, to scale a background image while retaining its aspect ratio.



          As an aside, note the difference from using fully saturated colors compared to the original. These related examples illustrate placing controls atop the animated background.



          image



          import java.util.LinkedList;
          import java.util.Queue;
          import java.util.Random;
          import javafx.animation.AnimationTimer;
          import javafx.application.Application;
          import javafx.beans.Observable;
          import javafx.scene.Scene;
          import javafx.scene.canvas.Canvas;
          import javafx.scene.canvas.GraphicsContext;
          import javafx.scene.control.CheckBox;
          import javafx.scene.layout.BorderPane;
          import javafx.scene.layout.Pane;
          import javafx.scene.paint.Color;
          import javafx.stage.Stage;

          /**
          * @see https://stackoverflow.com/a/31761362/230513
          * @see https://stackoverflow.com/a/8616169/230513
          */

          public class Baubles extends Application {

          private static final int MAX = 64;
          private static final double WIDTH = 640;
          private static final double HEIGHT = 480;
          private static final Random RND = new Random();
          private final Queue<Bauble> queue = new LinkedList<>();
          private Canvas canvas;

          @Override
          public void start(Stage stage) {
          CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
          canvas = canvasPane.getCanvas();
          BorderPane root = new BorderPane(canvasPane);
          CheckBox cb = new CheckBox("Animate");
          cb.setSelected(true);
          root.setBottom(cb);
          Scene scene = new Scene(root);
          stage.setScene(scene);
          stage.show();

          for (int i = 0; i < MAX; i++) {
          queue.add(randomBauble());
          }
          AnimationTimer loop = new AnimationTimer() {
          @Override
          public void handle(long now) {
          GraphicsContext g = canvas.getGraphicsContext2D();
          g.setFill(Color.BLACK);
          g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
          for (Bauble b : queue) {
          g.setFill(b.c);
          g.fillOval(b.x, b.y, b.d, b.d);
          }
          queue.add(randomBauble());
          queue.remove();
          }
          };
          loop.start();
          cb.selectedProperty().addListener((Observable o) -> {
          if (cb.isSelected()) {
          loop.start();
          } else {
          loop.stop();
          }
          });
          }

          private static class Bauble {

          private final double x, y, d;
          private final Color c;

          public Bauble(double x, double y, double r, Color c) {
          this.x = x - r;
          this.y = y - r;
          this.d = 2 * r;
          this.c = c;
          }
          }

          private Bauble randomBauble() {
          double x = RND.nextDouble() * canvas.getWidth();
          double y = RND.nextDouble() * canvas.getHeight();
          double r = RND.nextDouble() * MAX + MAX / 2;
          Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
          return new Bauble(x, y, r, c);
          }

          private static class CanvasPane extends Pane {

          private final Canvas canvas;

          public CanvasPane(double width, double height) {
          canvas = new Canvas(width, height);
          getChildren().add(canvas);
          }

          public Canvas getCanvas() {
          return canvas;
          }

          @Override
          protected void layoutChildren() {
          super.layoutChildren();
          final double x = snappedLeftInset();
          final double y = snappedTopInset();
          // Java 9 - snapSize is deprecated used snapSizeX() and snapSizeY() accordingly
          final double w = snapSize(getWidth()) - x - snappedRightInset();
          final double h = snapSize(getHeight()) - y - snappedBottomInset();
          canvas.setLayoutX(x);
          canvas.setLayoutY(y);
          canvas.setWidth(w);
          canvas.setHeight(h);
          }
          }

          public static void main(String args) {
          launch(args);
          }
          }





          share|improve this answer























          • Nice demo..+1..
            – Reimeus
            Aug 1 '15 at 11:57


















          up vote
          4
          down vote













          Couldn't you do this with a Binding as well? The following seems to produce the same results without having to add the derived class.



          import java.util.LinkedList;
          import java.util.Queue;
          import java.util.Random;
          import javafx.animation.AnimationTimer;
          import javafx.application.Application;
          import javafx.beans.Observable;
          import javafx.beans.binding.DoubleBinding;
          import javafx.scene.Scene;
          import javafx.scene.canvas.Canvas;
          import javafx.scene.canvas.GraphicsContext;
          import javafx.scene.control.CheckBox;
          import javafx.scene.layout.BorderPane;
          import javafx.scene.paint.Color;
          import javafx.stage.Stage;

          /**
          * @see http://stackoverflow.com/a/31761362/230513
          * @see http://stackoverflow.com/a/8616169/230513
          */

          public class Baubles extends Application {

          private static final int MAX = 64;
          private static final double WIDTH = 640;
          private static final double HEIGHT = 480;
          private static final Random RND = new Random();
          private final Queue<Bauble> queue = new LinkedList<>();
          private Canvas canvas;

          @Override
          public void start(Stage stage) {
          canvas = new Canvas(WIDTH, HEIGHT);
          BorderPane root = new BorderPane(canvas);
          CheckBox cb = new CheckBox("Animate");
          cb.setSelected(true);
          root.setBottom(cb);
          Scene scene = new Scene(root);
          stage.setScene(scene);
          stage.show();

          // Create bindings for resizing.
          DoubleBinding heightBinding = root.heightProperty()
          .subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
          canvas.widthProperty().bind(root.widthProperty());
          canvas.heightProperty().bind(heightBinding);

          for (int i = 0; i < MAX; i++) {
          queue.add(randomBauble());
          }
          AnimationTimer loop = new AnimationTimer() {
          @Override
          public void handle(long now) {
          GraphicsContext g = canvas.getGraphicsContext2D();
          g.setFill(Color.BLACK);
          g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
          for (Bauble b : queue) {
          g.setFill(b.c);
          g.fillOval(b.x, b.y, b.d, b.d);
          }
          queue.add(randomBauble());
          queue.remove();
          }
          };
          loop.start();
          cb.selectedProperty().addListener((Observable o) -> {
          if (cb.isSelected()) {
          loop.start();
          } else {
          loop.stop();
          }
          });
          }

          private static class Bauble {

          private final double x, y, d;
          private final Color c;

          public Bauble(double x, double y, double r, Color c) {
          this.x = x - r;
          this.y = y - r;
          this.d = 2 * r;
          this.c = c;
          }
          }

          private Bauble randomBauble() {
          double x = RND.nextDouble() * canvas.getWidth();
          double y = RND.nextDouble() * canvas.getHeight();
          double r = RND.nextDouble() * MAX + MAX / 2;
          Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
          return new Bauble(x, y, r, c);
          }

          public static void main(String args) {
          launch(args);
          }
          }





          share|improve this answer





















          • Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
            – trashgod
            Aug 1 '15 at 16:00










          • The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
            – clartaq
            Aug 1 '15 at 16:16










          • Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
            – trashgod
            Aug 1 '15 at 17:05










          • For reference, here's an example on binding in a StackPane.
            – trashgod
            Aug 3 '15 at 11:57


















          up vote
          1
          down vote













          I combined both prior solutions ( @trashgod and @clataq's ) by putting the canvas in a Pane and binding it to it:



          private static class CanvasPane extends Pane {

          final Canvas canvas;

          CanvasPane(double width, double height) {
          setWidth(width);
          setHeight(height);
          canvas = new Canvas(width, height);
          getChildren().add(canvas);

          canvas.widthProperty().bind(this.widthProperty());
          canvas.heightProperty().bind(this.heightProperty());
          }
          }





          share|improve this answer





















            Your Answer






            StackExchange.ifUsing("editor", function () {
            StackExchange.using("externalEditor", function () {
            StackExchange.using("snippets", function () {
            StackExchange.snippets.init();
            });
            });
            }, "code-snippets");

            StackExchange.ready(function() {
            var channelOptions = {
            tags: "".split(" "),
            id: "1"
            };
            initTagRenderer("".split(" "), "".split(" "), channelOptions);

            StackExchange.using("externalEditor", function() {
            // Have to fire editor after snippets, if snippets enabled
            if (StackExchange.settings.snippets.snippetsEnabled) {
            StackExchange.using("snippets", function() {
            createEditor();
            });
            }
            else {
            createEditor();
            }
            });

            function createEditor() {
            StackExchange.prepareEditor({
            heartbeatType: 'answer',
            convertImagesToLinks: true,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: 10,
            bindNavPrevention: true,
            postfix: "",
            imageUploader: {
            brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
            contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
            allowUrls: true
            },
            onDemand: true,
            discardSelector: ".discard-answer"
            ,immediatelyShowMarkdownHelp:true
            });


            }
            });














            draft saved

            draft discarded


















            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f31761361%2fautomatically-resize-canvas-to-fill-the-enclosing-parent%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown

























            3 Answers
            3






            active

            oldest

            votes








            3 Answers
            3






            active

            oldest

            votes









            active

            oldest

            votes






            active

            oldest

            votes








            up vote
            11
            down vote



            accepted










            In the example below, the static nested class CanvasPane wraps an instance of Canvas in a Pane and overrides layoutChildren() to make the canvas dimensions match the enclosing Pane. Note that Canvas returns false from isResizable(), so "the parent cannot resize it during layout," and Pane "does not perform layout beyond resizing resizable children to their preferred sizes." The width and height used to construct the canvas become its initial size. A similar approach is used in the Ensemble particle simulation, Fireworks.java, to scale a background image while retaining its aspect ratio.



            As an aside, note the difference from using fully saturated colors compared to the original. These related examples illustrate placing controls atop the animated background.



            image



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.layout.Pane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see https://stackoverflow.com/a/31761362/230513
            * @see https://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
            canvas = canvasPane.getCanvas();
            BorderPane root = new BorderPane(canvasPane);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            private static class CanvasPane extends Pane {

            private final Canvas canvas;

            public CanvasPane(double width, double height) {
            canvas = new Canvas(width, height);
            getChildren().add(canvas);
            }

            public Canvas getCanvas() {
            return canvas;
            }

            @Override
            protected void layoutChildren() {
            super.layoutChildren();
            final double x = snappedLeftInset();
            final double y = snappedTopInset();
            // Java 9 - snapSize is deprecated used snapSizeX() and snapSizeY() accordingly
            final double w = snapSize(getWidth()) - x - snappedRightInset();
            final double h = snapSize(getHeight()) - y - snappedBottomInset();
            canvas.setLayoutX(x);
            canvas.setLayoutY(y);
            canvas.setWidth(w);
            canvas.setHeight(h);
            }
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer























            • Nice demo..+1..
              – Reimeus
              Aug 1 '15 at 11:57















            up vote
            11
            down vote



            accepted










            In the example below, the static nested class CanvasPane wraps an instance of Canvas in a Pane and overrides layoutChildren() to make the canvas dimensions match the enclosing Pane. Note that Canvas returns false from isResizable(), so "the parent cannot resize it during layout," and Pane "does not perform layout beyond resizing resizable children to their preferred sizes." The width and height used to construct the canvas become its initial size. A similar approach is used in the Ensemble particle simulation, Fireworks.java, to scale a background image while retaining its aspect ratio.



            As an aside, note the difference from using fully saturated colors compared to the original. These related examples illustrate placing controls atop the animated background.



            image



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.layout.Pane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see https://stackoverflow.com/a/31761362/230513
            * @see https://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
            canvas = canvasPane.getCanvas();
            BorderPane root = new BorderPane(canvasPane);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            private static class CanvasPane extends Pane {

            private final Canvas canvas;

            public CanvasPane(double width, double height) {
            canvas = new Canvas(width, height);
            getChildren().add(canvas);
            }

            public Canvas getCanvas() {
            return canvas;
            }

            @Override
            protected void layoutChildren() {
            super.layoutChildren();
            final double x = snappedLeftInset();
            final double y = snappedTopInset();
            // Java 9 - snapSize is deprecated used snapSizeX() and snapSizeY() accordingly
            final double w = snapSize(getWidth()) - x - snappedRightInset();
            final double h = snapSize(getHeight()) - y - snappedBottomInset();
            canvas.setLayoutX(x);
            canvas.setLayoutY(y);
            canvas.setWidth(w);
            canvas.setHeight(h);
            }
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer























            • Nice demo..+1..
              – Reimeus
              Aug 1 '15 at 11:57













            up vote
            11
            down vote



            accepted







            up vote
            11
            down vote



            accepted






            In the example below, the static nested class CanvasPane wraps an instance of Canvas in a Pane and overrides layoutChildren() to make the canvas dimensions match the enclosing Pane. Note that Canvas returns false from isResizable(), so "the parent cannot resize it during layout," and Pane "does not perform layout beyond resizing resizable children to their preferred sizes." The width and height used to construct the canvas become its initial size. A similar approach is used in the Ensemble particle simulation, Fireworks.java, to scale a background image while retaining its aspect ratio.



            As an aside, note the difference from using fully saturated colors compared to the original. These related examples illustrate placing controls atop the animated background.



            image



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.layout.Pane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see https://stackoverflow.com/a/31761362/230513
            * @see https://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
            canvas = canvasPane.getCanvas();
            BorderPane root = new BorderPane(canvasPane);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            private static class CanvasPane extends Pane {

            private final Canvas canvas;

            public CanvasPane(double width, double height) {
            canvas = new Canvas(width, height);
            getChildren().add(canvas);
            }

            public Canvas getCanvas() {
            return canvas;
            }

            @Override
            protected void layoutChildren() {
            super.layoutChildren();
            final double x = snappedLeftInset();
            final double y = snappedTopInset();
            // Java 9 - snapSize is deprecated used snapSizeX() and snapSizeY() accordingly
            final double w = snapSize(getWidth()) - x - snappedRightInset();
            final double h = snapSize(getHeight()) - y - snappedBottomInset();
            canvas.setLayoutX(x);
            canvas.setLayoutY(y);
            canvas.setWidth(w);
            canvas.setHeight(h);
            }
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer














            In the example below, the static nested class CanvasPane wraps an instance of Canvas in a Pane and overrides layoutChildren() to make the canvas dimensions match the enclosing Pane. Note that Canvas returns false from isResizable(), so "the parent cannot resize it during layout," and Pane "does not perform layout beyond resizing resizable children to their preferred sizes." The width and height used to construct the canvas become its initial size. A similar approach is used in the Ensemble particle simulation, Fireworks.java, to scale a background image while retaining its aspect ratio.



            As an aside, note the difference from using fully saturated colors compared to the original. These related examples illustrate placing controls atop the animated background.



            image



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.layout.Pane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see https://stackoverflow.com/a/31761362/230513
            * @see https://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            CanvasPane canvasPane = new CanvasPane(WIDTH, HEIGHT);
            canvas = canvasPane.getCanvas();
            BorderPane root = new BorderPane(canvasPane);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            private static class CanvasPane extends Pane {

            private final Canvas canvas;

            public CanvasPane(double width, double height) {
            canvas = new Canvas(width, height);
            getChildren().add(canvas);
            }

            public Canvas getCanvas() {
            return canvas;
            }

            @Override
            protected void layoutChildren() {
            super.layoutChildren();
            final double x = snappedLeftInset();
            final double y = snappedTopInset();
            // Java 9 - snapSize is deprecated used snapSizeX() and snapSizeY() accordingly
            final double w = snapSize(getWidth()) - x - snappedRightInset();
            final double h = snapSize(getHeight()) - y - snappedBottomInset();
            canvas.setLayoutX(x);
            canvas.setLayoutY(y);
            canvas.setWidth(w);
            canvas.setHeight(h);
            }
            }

            public static void main(String args) {
            launch(args);
            }
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 10 at 23:41









            gerardw

            2,8032127




            2,8032127










            answered Aug 1 '15 at 11:35









            trashgod

            186k16139692




            186k16139692












            • Nice demo..+1..
              – Reimeus
              Aug 1 '15 at 11:57


















            • Nice demo..+1..
              – Reimeus
              Aug 1 '15 at 11:57
















            Nice demo..+1..
            – Reimeus
            Aug 1 '15 at 11:57




            Nice demo..+1..
            – Reimeus
            Aug 1 '15 at 11:57












            up vote
            4
            down vote













            Couldn't you do this with a Binding as well? The following seems to produce the same results without having to add the derived class.



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.beans.binding.DoubleBinding;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see http://stackoverflow.com/a/31761362/230513
            * @see http://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            canvas = new Canvas(WIDTH, HEIGHT);
            BorderPane root = new BorderPane(canvas);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            // Create bindings for resizing.
            DoubleBinding heightBinding = root.heightProperty()
            .subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
            canvas.widthProperty().bind(root.widthProperty());
            canvas.heightProperty().bind(heightBinding);

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer





















            • Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
              – trashgod
              Aug 1 '15 at 16:00










            • The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
              – clartaq
              Aug 1 '15 at 16:16










            • Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
              – trashgod
              Aug 1 '15 at 17:05










            • For reference, here's an example on binding in a StackPane.
              – trashgod
              Aug 3 '15 at 11:57















            up vote
            4
            down vote













            Couldn't you do this with a Binding as well? The following seems to produce the same results without having to add the derived class.



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.beans.binding.DoubleBinding;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see http://stackoverflow.com/a/31761362/230513
            * @see http://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            canvas = new Canvas(WIDTH, HEIGHT);
            BorderPane root = new BorderPane(canvas);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            // Create bindings for resizing.
            DoubleBinding heightBinding = root.heightProperty()
            .subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
            canvas.widthProperty().bind(root.widthProperty());
            canvas.heightProperty().bind(heightBinding);

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer





















            • Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
              – trashgod
              Aug 1 '15 at 16:00










            • The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
              – clartaq
              Aug 1 '15 at 16:16










            • Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
              – trashgod
              Aug 1 '15 at 17:05










            • For reference, here's an example on binding in a StackPane.
              – trashgod
              Aug 3 '15 at 11:57













            up vote
            4
            down vote










            up vote
            4
            down vote









            Couldn't you do this with a Binding as well? The following seems to produce the same results without having to add the derived class.



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.beans.binding.DoubleBinding;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see http://stackoverflow.com/a/31761362/230513
            * @see http://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            canvas = new Canvas(WIDTH, HEIGHT);
            BorderPane root = new BorderPane(canvas);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            // Create bindings for resizing.
            DoubleBinding heightBinding = root.heightProperty()
            .subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
            canvas.widthProperty().bind(root.widthProperty());
            canvas.heightProperty().bind(heightBinding);

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            public static void main(String args) {
            launch(args);
            }
            }





            share|improve this answer












            Couldn't you do this with a Binding as well? The following seems to produce the same results without having to add the derived class.



            import java.util.LinkedList;
            import java.util.Queue;
            import java.util.Random;
            import javafx.animation.AnimationTimer;
            import javafx.application.Application;
            import javafx.beans.Observable;
            import javafx.beans.binding.DoubleBinding;
            import javafx.scene.Scene;
            import javafx.scene.canvas.Canvas;
            import javafx.scene.canvas.GraphicsContext;
            import javafx.scene.control.CheckBox;
            import javafx.scene.layout.BorderPane;
            import javafx.scene.paint.Color;
            import javafx.stage.Stage;

            /**
            * @see http://stackoverflow.com/a/31761362/230513
            * @see http://stackoverflow.com/a/8616169/230513
            */

            public class Baubles extends Application {

            private static final int MAX = 64;
            private static final double WIDTH = 640;
            private static final double HEIGHT = 480;
            private static final Random RND = new Random();
            private final Queue<Bauble> queue = new LinkedList<>();
            private Canvas canvas;

            @Override
            public void start(Stage stage) {
            canvas = new Canvas(WIDTH, HEIGHT);
            BorderPane root = new BorderPane(canvas);
            CheckBox cb = new CheckBox("Animate");
            cb.setSelected(true);
            root.setBottom(cb);
            Scene scene = new Scene(root);
            stage.setScene(scene);
            stage.show();

            // Create bindings for resizing.
            DoubleBinding heightBinding = root.heightProperty()
            .subtract(root.bottomProperty().getValue().getBoundsInParent().getHeight());
            canvas.widthProperty().bind(root.widthProperty());
            canvas.heightProperty().bind(heightBinding);

            for (int i = 0; i < MAX; i++) {
            queue.add(randomBauble());
            }
            AnimationTimer loop = new AnimationTimer() {
            @Override
            public void handle(long now) {
            GraphicsContext g = canvas.getGraphicsContext2D();
            g.setFill(Color.BLACK);
            g.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
            for (Bauble b : queue) {
            g.setFill(b.c);
            g.fillOval(b.x, b.y, b.d, b.d);
            }
            queue.add(randomBauble());
            queue.remove();
            }
            };
            loop.start();
            cb.selectedProperty().addListener((Observable o) -> {
            if (cb.isSelected()) {
            loop.start();
            } else {
            loop.stop();
            }
            });
            }

            private static class Bauble {

            private final double x, y, d;
            private final Color c;

            public Bauble(double x, double y, double r, Color c) {
            this.x = x - r;
            this.y = y - r;
            this.d = 2 * r;
            this.c = c;
            }
            }

            private Bauble randomBauble() {
            double x = RND.nextDouble() * canvas.getWidth();
            double y = RND.nextDouble() * canvas.getHeight();
            double r = RND.nextDouble() * MAX + MAX / 2;
            Color c = Color.hsb(RND.nextDouble() * 360, 1, 1, 0.75);
            return new Bauble(x, y, r, c);
            }

            public static void main(String args) {
            launch(args);
            }
            }






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Aug 1 '15 at 15:03









            clartaq

            3,68122838




            3,68122838












            • Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
              – trashgod
              Aug 1 '15 at 16:00










            • The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
              – clartaq
              Aug 1 '15 at 16:16










            • Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
              – trashgod
              Aug 1 '15 at 17:05










            • For reference, here's an example on binding in a StackPane.
              – trashgod
              Aug 3 '15 at 11:57


















            • Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
              – trashgod
              Aug 1 '15 at 16:00










            • The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
              – clartaq
              Aug 1 '15 at 16:16










            • Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
              – trashgod
              Aug 1 '15 at 17:05










            • For reference, here's an example on binding in a StackPane.
              – trashgod
              Aug 3 '15 at 11:57
















            Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
            – trashgod
            Aug 1 '15 at 16:00




            Thank you for suggesting Binding. Am I correct to infer that the binding would have to change for a different root layout? I only tested CanvasPane in BorderPane and StackPane.
            – trashgod
            Aug 1 '15 at 16:00












            The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
            – clartaq
            Aug 1 '15 at 16:16




            The details would need to change, but something similar should work. Also, the example is not perfectly general for a 'BorderPane' since some details would need to change if you had nodes in the top, left, or right positions.
            – clartaq
            Aug 1 '15 at 16:16












            Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
            – trashgod
            Aug 1 '15 at 17:05




            Ah, I see; in a StackPane, I could bind() the canvas.heightProperty() directly to the root.heightProperty(). So far I think CanvasPane is more flexible, but plus one for a useful alternative and a concrete example of Binding arithmetic.
            – trashgod
            Aug 1 '15 at 17:05












            For reference, here's an example on binding in a StackPane.
            – trashgod
            Aug 3 '15 at 11:57




            For reference, here's an example on binding in a StackPane.
            – trashgod
            Aug 3 '15 at 11:57










            up vote
            1
            down vote













            I combined both prior solutions ( @trashgod and @clataq's ) by putting the canvas in a Pane and binding it to it:



            private static class CanvasPane extends Pane {

            final Canvas canvas;

            CanvasPane(double width, double height) {
            setWidth(width);
            setHeight(height);
            canvas = new Canvas(width, height);
            getChildren().add(canvas);

            canvas.widthProperty().bind(this.widthProperty());
            canvas.heightProperty().bind(this.heightProperty());
            }
            }





            share|improve this answer

























              up vote
              1
              down vote













              I combined both prior solutions ( @trashgod and @clataq's ) by putting the canvas in a Pane and binding it to it:



              private static class CanvasPane extends Pane {

              final Canvas canvas;

              CanvasPane(double width, double height) {
              setWidth(width);
              setHeight(height);
              canvas = new Canvas(width, height);
              getChildren().add(canvas);

              canvas.widthProperty().bind(this.widthProperty());
              canvas.heightProperty().bind(this.heightProperty());
              }
              }





              share|improve this answer























                up vote
                1
                down vote










                up vote
                1
                down vote









                I combined both prior solutions ( @trashgod and @clataq's ) by putting the canvas in a Pane and binding it to it:



                private static class CanvasPane extends Pane {

                final Canvas canvas;

                CanvasPane(double width, double height) {
                setWidth(width);
                setHeight(height);
                canvas = new Canvas(width, height);
                getChildren().add(canvas);

                canvas.widthProperty().bind(this.widthProperty());
                canvas.heightProperty().bind(this.heightProperty());
                }
                }





                share|improve this answer












                I combined both prior solutions ( @trashgod and @clataq's ) by putting the canvas in a Pane and binding it to it:



                private static class CanvasPane extends Pane {

                final Canvas canvas;

                CanvasPane(double width, double height) {
                setWidth(width);
                setHeight(height);
                canvas = new Canvas(width, height);
                getChildren().add(canvas);

                canvas.widthProperty().bind(this.widthProperty());
                canvas.heightProperty().bind(this.heightProperty());
                }
                }






                share|improve this answer












                share|improve this answer



                share|improve this answer










                answered Nov 11 at 10:42









                gerardw

                2,8032127




                2,8032127






























                    draft saved

                    draft discarded




















































                    Thanks for contributing an answer to Stack Overflow!


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.





                    Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                    Please pay close attention to the following guidance:


                    • Please be sure to answer the question. Provide details and share your research!

                    But avoid



                    • Asking for help, clarification, or responding to other answers.

                    • Making statements based on opinion; back them up with references or personal experience.


                    To learn more, see our tips on writing great answers.




                    draft saved


                    draft discarded














                    StackExchange.ready(
                    function () {
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f31761361%2fautomatically-resize-canvas-to-fill-the-enclosing-parent%23new-answer', 'question_page');
                    }
                    );

                    Post as a guest















                    Required, but never shown





















































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown

































                    Required, but never shown














                    Required, but never shown












                    Required, but never shown







                    Required, but never shown







                    Popular posts from this blog

                    How to pass form data using jquery Ajax to insert data in database?

                    National Museum of Racing and Hall of Fame

                    Guess what letter conforming each word