< prev index next >

modules/graphics/src/main/java/javafx/animation/PathTransition.java

Print this page




  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.animation;
  27 
  28 import javafx.beans.property.ObjectProperty;
  29 import javafx.beans.property.ObjectPropertyBase;
  30 import javafx.beans.property.SimpleObjectProperty;
  31 import javafx.scene.Node;
  32 import javafx.scene.shape.Shape;
  33 import javafx.util.Duration;
  34 
  35 import com.sun.javafx.geom.Path2D;
  36 import com.sun.javafx.geom.PathIterator;
  37 import com.sun.javafx.geom.transform.BaseTransform;

  38 import com.sun.javafx.scene.shape.ShapeHelper;
  39 import java.util.ArrayList;
  40 
  41 /**
  42  * This {@code Transition} creates a path animation that spans its
  43  * {@link #duration}. The translation along the path is done by updating the
  44  * {@code translateX} and {@code translateY} variables of the {@code node}, and
  45  * the {@code rotate} variable will get updated if {@code orientation} is set to
  46  * {@code OrientationType.ORTHOGONAL_TO_TANGENT}, at regular interval.
  47  * <p>
  48  * The animated path is defined by the outline of a shape.
  49  *
  50  * <p>
  51  * Code Segment Example:
  52  * </p>
  53  *
  54  * <pre>
  55  * <code>
  56  * import javafx.scene.shape.*;
  57  * import javafx.animation.*;


 324 
 325         // provide smooth rotation on segment bounds
 326         double z = Math.min(SMOOTH_ZONE, seg.length / 2);
 327         if (partLength < z && !prevSeg.isMoveTo) {
 328             //interpolate rotation to previous segment
 329             rotateAngle = interpolate(
 330                     prevSeg.rotateAngle, seg.rotateAngle,
 331                     partLength / z / 2 + 0.5F);
 332         } else {
 333             double dist = seg.length - partLength;
 334             Segment nextSeg = seg.nextSeg;
 335             if (dist < z && nextSeg != null) {
 336                 //interpolate rotation to next segment
 337                 if (!nextSeg.isMoveTo) {
 338                     rotateAngle = interpolate(
 339                             seg.rotateAngle, nextSeg.rotateAngle,
 340                             (z - dist) / z / 2);
 341                 }
 342             }
 343         }
 344         cachedNode.setTranslateX(x - cachedNode.impl_getPivotX());
 345         cachedNode.setTranslateY(y - cachedNode.impl_getPivotY());
 346         // Need to handle orientation if it is requested
 347         if (cachedIsNormalRequired) {
 348             cachedNode.setRotate(rotateAngle);
 349         }
 350     }
 351 
 352     private Node getTargetNode() {
 353         final Node node = getNode();
 354         return (node != null) ? node : getParentTargetNode();
 355     }
 356 
 357     @Override
 358     boolean startable(boolean forceSync) {
 359         return super.startable(forceSync)
 360                 && (((getTargetNode() != null) && (getPath() != null) && !getPath().getLayoutBounds().isEmpty()) || (!forceSync
 361                         && (cachedNode != null)));
 362     }
 363 
 364     @Override
 365     void sync(boolean forceSync) {
 366         super.sync(forceSync);
 367         if (forceSync || (cachedNode == null)) {
 368             cachedNode = getTargetNode();
 369             recomputeSegments();
 370             cachedIsNormalRequired = getOrientation() == OrientationType.ORTHOGONAL_TO_TANGENT;
 371         }
 372     }
 373 
 374     private void recomputeSegments() {
 375         segments.clear();
 376         final Shape p = getPath();
 377         Segment moveToSeg = Segment.getZeroSegment();
 378         Segment lastSeg = Segment.getZeroSegment();
 379 
 380         float[] coords = new float[6];
 381         for (PathIterator i = ShapeHelper.configShape(p).getPathIterator(p.impl_getLeafTransform(), 1.0f); !i.isDone(); i.next()) {
 382             Segment newSeg = null;
 383             int segType = i.currentSegment(coords);
 384             double x = coords[0];
 385             double y = coords[1];
 386 
 387             switch (segType) {
 388                 case PathIterator.SEG_MOVETO:
 389                     moveToSeg = Segment.newMoveTo(x, y, lastSeg.accumLength);
 390                     newSeg = moveToSeg;
 391                     break;
 392                 case PathIterator.SEG_CLOSE:
 393                     newSeg = Segment.newClosePath(lastSeg, moveToSeg);
 394                     if (newSeg == null) {
 395                         // make the last segment to close the path
 396                         lastSeg.convertToClosePath(moveToSeg);
 397                     }
 398                     break;
 399                 case PathIterator.SEG_LINETO:
 400                     newSeg = Segment.newLineTo(lastSeg, x, y);
 401                     break;




  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javafx.animation;
  27 
  28 import javafx.beans.property.ObjectProperty;
  29 import javafx.beans.property.ObjectPropertyBase;
  30 import javafx.beans.property.SimpleObjectProperty;
  31 import javafx.scene.Node;
  32 import javafx.scene.shape.Shape;
  33 import javafx.util.Duration;
  34 
  35 import com.sun.javafx.geom.Path2D;
  36 import com.sun.javafx.geom.PathIterator;
  37 import com.sun.javafx.geom.transform.BaseTransform;
  38 import com.sun.javafx.scene.NodeHelper;
  39 import com.sun.javafx.scene.shape.ShapeHelper;
  40 import java.util.ArrayList;
  41 
  42 /**
  43  * This {@code Transition} creates a path animation that spans its
  44  * {@link #duration}. The translation along the path is done by updating the
  45  * {@code translateX} and {@code translateY} variables of the {@code node}, and
  46  * the {@code rotate} variable will get updated if {@code orientation} is set to
  47  * {@code OrientationType.ORTHOGONAL_TO_TANGENT}, at regular interval.
  48  * <p>
  49  * The animated path is defined by the outline of a shape.
  50  *
  51  * <p>
  52  * Code Segment Example:
  53  * </p>
  54  *
  55  * <pre>
  56  * <code>
  57  * import javafx.scene.shape.*;
  58  * import javafx.animation.*;


 325 
 326         // provide smooth rotation on segment bounds
 327         double z = Math.min(SMOOTH_ZONE, seg.length / 2);
 328         if (partLength < z && !prevSeg.isMoveTo) {
 329             //interpolate rotation to previous segment
 330             rotateAngle = interpolate(
 331                     prevSeg.rotateAngle, seg.rotateAngle,
 332                     partLength / z / 2 + 0.5F);
 333         } else {
 334             double dist = seg.length - partLength;
 335             Segment nextSeg = seg.nextSeg;
 336             if (dist < z && nextSeg != null) {
 337                 //interpolate rotation to next segment
 338                 if (!nextSeg.isMoveTo) {
 339                     rotateAngle = interpolate(
 340                             seg.rotateAngle, nextSeg.rotateAngle,
 341                             (z - dist) / z / 2);
 342                 }
 343             }
 344         }
 345         cachedNode.setTranslateX(x - NodeHelper.getPivotX(cachedNode));
 346         cachedNode.setTranslateY(y - NodeHelper.getPivotY(cachedNode));
 347         // Need to handle orientation if it is requested
 348         if (cachedIsNormalRequired) {
 349             cachedNode.setRotate(rotateAngle);
 350         }
 351     }
 352 
 353     private Node getTargetNode() {
 354         final Node node = getNode();
 355         return (node != null) ? node : getParentTargetNode();
 356     }
 357 
 358     @Override
 359     boolean startable(boolean forceSync) {
 360         return super.startable(forceSync)
 361                 && (((getTargetNode() != null) && (getPath() != null) && !getPath().getLayoutBounds().isEmpty()) || (!forceSync
 362                         && (cachedNode != null)));
 363     }
 364 
 365     @Override
 366     void sync(boolean forceSync) {
 367         super.sync(forceSync);
 368         if (forceSync || (cachedNode == null)) {
 369             cachedNode = getTargetNode();
 370             recomputeSegments();
 371             cachedIsNormalRequired = getOrientation() == OrientationType.ORTHOGONAL_TO_TANGENT;
 372         }
 373     }
 374 
 375     private void recomputeSegments() {
 376         segments.clear();
 377         final Shape p = getPath();
 378         Segment moveToSeg = Segment.getZeroSegment();
 379         Segment lastSeg = Segment.getZeroSegment();
 380 
 381         float[] coords = new float[6];
 382         for (PathIterator i = ShapeHelper.configShape(p).getPathIterator(NodeHelper.getLeafTransform(p), 1.0f); !i.isDone(); i.next()) {
 383             Segment newSeg = null;
 384             int segType = i.currentSegment(coords);
 385             double x = coords[0];
 386             double y = coords[1];
 387 
 388             switch (segType) {
 389                 case PathIterator.SEG_MOVETO:
 390                     moveToSeg = Segment.newMoveTo(x, y, lastSeg.accumLength);
 391                     newSeg = moveToSeg;
 392                     break;
 393                 case PathIterator.SEG_CLOSE:
 394                     newSeg = Segment.newClosePath(lastSeg, moveToSeg);
 395                     if (newSeg == null) {
 396                         // make the last segment to close the path
 397                         lastSeg.convertToClosePath(moveToSeg);
 398                     }
 399                     break;
 400                 case PathIterator.SEG_LINETO:
 401                     newSeg = Segment.newLineTo(lastSeg, x, y);
 402                     break;


< prev index next >