Wednesday Dec 10, 2008

Spring Motion - Physics in JavaFX

3 weeks back, we were thinking of some cool application to make. I am a guy who has seen very less outside world, so coming up with some great idea is always tough for me. So, deciding that, I went back to my tenth class physics book and saw some of the cool physics motion. Its one of the tough subject and always screw me in exam. Searching some of the easy equation, I though to make one spring motion. Meantime, I though there is some spring motion residing in our repository. Actually one of the Josh applications do it in awesome way, but still we were missing the actual feel of Spring motion because of the gig-gag and spiral stuff attached to the wall and spring is going up and down in it, with a complete view of awesomeness :). This is what finally we achieve from this blog :

 I can still bet this can be 3 times much better than what you are seeing here. So, little of good news here that this sample can be executed on mobile

Here are the code files :

1. Main file.

2. Spring file.

3. SpringEquation file.

Enjoy FX'ing !

Tuesday Dec 09, 2008

3D button Effect in JavaFX

Me and Vikram was looking today some of the cool flash examples and I have seen the button effect at some place, when you press the button it really goes like inside and coming out. But that was an effect achieved by the images(two different images, one unpressed button and one pressed button) and then we thought to simulate this effect by code. Somehow we are able to do that in FX, here is the final outcome:

What we have tried to do is pressing one button will put the other in unpressed mode and vice-versa. This has been achieved by some of the cool API's of JavaFX. And we have used the DistantLight effect of JavaFX which gives a lighting effect in its awesome way. Actually this can be more cooler but I left that for developer to modify it according to their need :). But this is a modular code and can be used in any of the button place.

Here is the simple code for the same(again code is not written in the most optimized way but in the best way for understanding) :

package lighteff;

import javafx.scene.effect.light.DistantLight;
import javafx.scene.effect.Lighting;
import javafx.scene.Group;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.Scene;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.stage.StageStyle;

var factor = 5;
var scale = 1.0;
var factor1 = 10;
var scale1 = 0.85;

Stage {
    title: "Control Panel"
    width: 290
    height: 180
    style: StageStyle.UNDECORATED
    scene: Scene {
        fill: Color.BLACK
        content: [
            Group {
                effect: Lighting {
                    light: DistantLight {
                        azimuth: 90
                        elevation: 60
                    }
                    surfaceScale: bind factor
                }
                content: [
                    Circle {
                        centerX: 100,
                        centerY: 100
                        radius: 40
                        fill: Color.RED

 
                        onMousePressed: function( e: MouseEvent ):Void {
                            scale = 0.85;
                            factor = 10;
                            scale1 = 1.0;
                            factor1 = 5;
                        }
                    },
                    Text {
                        fill: Color.WHITE
                        scaleX: bind scale
                        scaleY: bind scale
                        font: Font {
                            size: 24
                        }
                        x: 71,
                        y: 105
                        content: "Press"
                    }
                ]
            },
            Group {
                effect: Lighting {
                    light: DistantLight {
                        azimuth: 90
                        elevation: 60
                    }
                    surfaceScale: bind factor1
                }
                content: [

                    Circle {
                        centerX: 200
                        centerY: 100
                        radius: 40
                        fill: Color.BLUE
                        onMousePressed: function( e: MouseEvent ):Void {
                            scale1 = 0.85;
                            factor1 = 10;
                            scale = 1.0;
                            factor = 5;
                        }
                    },
                    Text {
                        fill: Color.WHITE
                        scaleX: bind scale1
                        scaleY: bind scale1
                        font: Font {
                            size: 24
                        }
                        x: 171,
                        y: 105
                        content: "Press"
                    }
                ]
            }
        ]

    }
}  

Saturday Aug 09, 2008

JavaFX, Constrain check - Next Part !

As we discussed in the last blog, about easing and constraint. Now we have seen the ball is moving inside the box but not completely. And this is not possible as well because the mouseMove code has been written on the box and mouse can move anywhere in the box. So, the basic funda comes first is to make one virtual box bigger than target box and the mouseMove code should be written on the outer virtual box rather than the box inside which we want to move our ball. Now the real constraint part, that will be written inside the onMouseMove code: 

                onMouseMoved: function( e: MouseEvent ):Void {
                    mouseX = e.getX();
                    mouseY = e.getY();
                    if(mouseX < rect.x + circleRadius ) {
                        mouseX = rect.x + circleRadius
                    };
                    if(mouseX > rect.x + rect.width - circleRadius ) {
                        mouseX = rect.x + rect.width - circleRadius
                    };

                    if(mouseY < rect.y + circleRadius ) {
                        mouseY = rect.y + circleRadius
                    };
                    if( mouseY > rect.y + rect.height - circleRadius ) {
                        mouseY = rect.y + rect.height - circleRadius
                    };
                }

Here, rect is the target box inside which we want the ball to move. So, if mouse position is going out of the boundary, we are pushing it inside the boundary. I am still damn sure, some checking may be missing. Now, this mouseMove will go into the outer bigger circle. Here is the final code: 

 package constraintcheck;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Circle;
import javafx.scene.paint.Color;
import javafx.input.MouseEvent;
import javafx.scene.transform.Translate;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import java.lang.Math;
import javafx.scene.geometry.Rectangle;

var mouseX : Number = 100;
var mouseY : Number = 100;
var circleX : Number = 300;
var circleY : Number = 300;
var t : Number = 100;
var easing : Number = 0.05;
var circleRadius : Number = 50;

var timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames : [
        KeyFrame {
            time : 16ms
            action : function() {
                if( 
                Math.abs(mouseX - circleX ) > 0.1 ) {
                    circleX = circleX + (mouseX - circleX ) \* easing;
                }
                if( Math.abs(mouseY - circleY ) > 0.1 ) {
                    circleY = circleY + ( mouseY - circleY ) \* easing;
                }
            }
        }
    ]
}

Frame {
    title: "Constrain Check"
    width: 700
    height: 700
    closeAction: function() { java.lang.System.exit( 0 ); 
    }
    visible: true

    var rect = Rectangle {
        x: 100, y: 100
        width: 400, height: 400
        fill: Color.RED
   }
    stage: Stage {
        content: [ 
            Rectangle {
                x: 0, y: 0
                width: 500, height: 500
                fill: Color.BLACK
                onMouseMoved: function( e: MouseEvent ):Void {
                    mouseX = e.getX(); 
                    mouseY = e.getY();
                    if(mouseX < rect.x + circleRadius ) { 
                        mouseX = rect.x + circleRadius
                    };
                    if(mouseX > rect.x + rect.width - circleRadius ) { 
                        mouseX = rect.x + rect.width - circleRadius
                    };
 
                    if(mouseY < rect.y + circleRadius ) { 
                        mouseY = rect.y + circleRadius
                    };
                    if( mouseY > rect.y + rect.height - circleRadius ) { 
                        mouseY = rect.y + rect.height - circleRadius
                    };
                }
            },rect,
            Circle {
                centerX: bind circleX, centerY: bind circleY
                radius: circleRadius
                fill: Color.GRAY
            }
        ]
        fill: Color.BLACK 
    }
}
timeline.start();

It combines both the code, easing part and the constaint part :-). Virual box has been made by filling the rectangle same color as of frame.  Now, you can play around with the coordinate value and check its working fine or not. Still some condition need to check like the outer box size should be bigger. Now, look at the code of Constraint.fx written in Netbeans 6.1 example :-P.

JavaFX and giving motion with mouse - Easing factor

When we write animation code like moving a circle or rotating a cube, we do a bad thing. We write the coordinates according to our ease and later its pain  for others to understand the code. In the code, you will see 450 - size or 200 + radius. Now, its really tough to guess what this 450 and 200. It came from direct calculation or from addition, multiplication. Sometimes, in our mind we do those mathematical calculation and we put the final value. I have mostly done in all my previous code :-D. And this is how I got the Netbeans JavaFX sample example. For getting some hand into JavaFX code, I was trying to write a constraint code, which I was inspired from NB example, Constraint.fx in the section Best Practices -> Input. And it was all pain to understand that code, because the manipulation was done like a mathematician not like a coder. Anyway, let me first finish this blog and then you can compare it yourself.

Two good thing that code covers :-

1. How to do easing (there is a separate example of that as well): 

Now, when we move the mouse from one position to other, we don't want our ball(say, we are moving a ball) to stick with mouse and keep on moving with mouse. We want it into a form of motion. Like from the last position of mouse to this new position of mouse, the ball slowly moves. This can be achieved by easing  :

Have a look:

onMouseMoved: function( e: MouseEvent ):Void {
    mouseX = e.getX();
    mouseY = e.getY();

Now, if we bind our X and Y(center) of circle with mouseX, mouseY, the look will come ugly :-)( a sticky look). So, we will write an integral code here:

if(Math.abs(mouseX - circleX ) > 0.1 ) {
   circleX = circleX + (mouseX - circleX ) \* easing;
}
if( Math.abs(mouseY - circleY ) > 0.1 ) {
   circleY = circleY + ( mouseY - circleY ) \* easing;
}

We are doing something same but in a fashionable style. We are increasing the value of CircleX and CircleY in bits and pieces and the smoothness depends on the value of easing factor which we have multiplied at the end. Lets have a look to this full code how it work :

package easingcheck;

import javafx.application.Frame;
import javafx.application.Stage;
import javafx.scene.geometry.Rectangle;
import javafx.scene.paint.Color;
import javafx.scene.geometry.Circle;
import java.lang.Math;
import javafx.animation.Timeline;
import javafx.animation.KeyFrame;
import javafx.input.MouseEvent;

var mouseX: Number;
var mouseY: Number;
var circleX: Number = 250;
var circleY: Number = 250;
var easing = 0.04;

var timeline = Timeline {
    repeatCount: Timeline.INDEFINITE
    keyFrames : [
        KeyFrame {
            time : 16ms
            action : function() {
                if( Math.abs(mouseX - circleX ) > 0.1 ) {
                    circleX = circleX + (mouseX - circleX ) \* easing;
                }
                if( Math.abs(mouseY - circleY ) > 0.1 ) {
                    circleY = circleY + ( mouseY - circleY ) \* easing;
                }
            }
        }
    ]
}
Frame {
    title: "MyApplication"
    width: 500
    height: 500
    closeAction: function() { java.lang.System.exit( 0 ); 
    }
    visible: true

    stage: Stage {
        content: [ 
            Rectangle {
                x: 100, y: 100
                width: 300, height: 300
                fill: Color.BLACK
                onMouseMoved: function( e: MouseEvent ):Void {
                       mouseX = e.getX();
                       mouseY = e.getY();
 
                }
            },
            Circle {
                centerX: bind circleX, centerY: bind circleY
                radius: 20
                fill: Color.RED
 
            }
        ]
    }
}
timeline.start();

We can see a smooth movement of ball(if you want to see ugly look once, then bind centerX and centerY on MouseX and MouseY). Also notice that ball is not coming out of the rectangular box because the OnMouseMoved code has been written inside the box. So, it should not come out of the box. We have to constraint the ball inside the Rectangular box completely, right now half of the ball is coming out of the box. This is 25 percent of the story. We will see how to do this job, which looks easy but not so. Keeping mind of blog size, I am continue into next blog :-)

About

Hi, I am Vaibhav Choudhary working in Sun. This blog is all about simple concept of Java and JavaFX.

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today