Guest User

Untitled

a guest
Jun 25th, 2018
79
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.14 KB | None | 0 0
  1. import javafx.animation.Animation.Status;
  2. import javafx.animation.Interpolator;
  3. import javafx.animation.Transition;
  4. import javafx.event.EventHandler;
  5. import javafx.scene.Node;
  6. import javafx.scene.control.ScrollPane;
  7. import javafx.scene.input.ScrollEvent;
  8. import javafx.scene.layout.VBox;
  9. import javafx.util.Duration;
  10.  
  11. /**
  12. * Scrollpane with kinda smooth transition scrolling.
  13. *
  14. * @author Matt
  15. */
  16. public class SmoothishScrollpane extends ScrollPane {
  17. private final static int TRANSITION_DURATION = 200;
  18. private final static double BASE_MODIFIER = 1;
  19.  
  20. /**
  21. * @param content
  22. * Item to be wrapped in the scrollpane.
  23. */
  24. public SmoothishScrollpane(Node content) {
  25. // ease-of-access for inner class
  26. ScrollPane scroll = this;
  27. // set content in a wrapper
  28. VBox wrapper = new VBox(content);
  29. setContent(wrapper);
  30. // add scroll handling to wrapper
  31. wrapper.setOnScroll(new EventHandler<ScrollEvent>() {
  32. private SmoothishTransition transition;
  33.  
  34. @Override
  35. public void handle(ScrollEvent event) {
  36. double deltaY = BASE_MODIFIER * event.getDeltaY();
  37. double width = scroll.getContent().getBoundsInLocal().getWidth();
  38. double vvalue = scroll.getVvalue();
  39. Interpolator interp = Interpolator.LINEAR;
  40. transition = new SmoothishTransition(transition, deltaY) {
  41. @Override
  42. protected void interpolate(double frac) {
  43. double x = interp.interpolate(vvalue, vvalue + -deltaY * getMod() / width, frac);
  44. scroll.setVvalue(x);
  45. }
  46. };
  47. transition.play();
  48. }
  49. });
  50. }
  51.  
  52. /**
  53. * @param t
  54. * Transition to check.
  55. * @return {@code true} if transition is playing.
  56. */
  57. private static boolean playing(Transition t) {
  58. return t.getStatus() == Status.RUNNING;
  59. }
  60.  
  61. /**
  62. * @param d1
  63. * Value 1
  64. * @param d2
  65. * Value 2.
  66. * @return {@code true} if values signes are matching.
  67. */
  68. private static boolean sameSign(double d1, double d2) {
  69. return (d1 > 0 && d2 > 0) || (d1 < 0 && d2 < 0);
  70. }
  71.  
  72. /**
  73. * Transition with varying speed based on previously existing transitions.
  74. *
  75. * @author Matt
  76. */
  77. abstract class SmoothishTransition extends Transition {
  78. private final double mod;
  79. private final double delta;
  80.  
  81. public SmoothishTransition(SmoothishTransition old, double delta) {
  82. setCycleDuration(Duration.millis(TRANSITION_DURATION));
  83. setCycleCount(0);
  84. // if the last transition was moving inthe same direction, and is still playing
  85. // then increment the modifer. This will boost the distance, thus looking faster
  86. // and seemingly consecutive.
  87. if (old != null && sameSign(delta, old.delta) && playing(old)) {
  88. mod = old.getMod() + 1;
  89. } else {
  90. mod = 1;
  91. }
  92. this.delta = delta;
  93. }
  94.  
  95. public double getMod() {
  96. return mod;
  97. }
  98.  
  99. @Override
  100. public void play() {
  101. super.play();
  102. // Even with a linear interpolation, startup is visibly slower than the middle.
  103. // So skip a small bit of the animation to keep up with the speed of prior
  104. // animation. The value of 10 works and isn't noticeable unless you really pay
  105. // close attention. This works best on linear but also is decent for others.
  106. if (getMod() > 1) {
  107. jumpTo(getCycleDuration().divide(10));
  108. }
  109. }
  110. }
  111. }
Add Comment
Please, Sign In to add comment