我已经研究了为什么在IOS和模拟器中的代号One拉伸滚动与原始的IOS橡皮筋滚动如此不同。
为了评估这一点,我需要研究Motion
类及其基于时间的各种过渡。为此,我创建了一个应用程序以可视化这些Motion
中的几个。
看看:
我在那里看到了几个问题。看一下this example,我想要实现哪种运动-一种橡皮筋运动,起初速度很快,但像橡皮筋一样容易放松。我可能不了解com.codename1.ui.animations.Motion.createCubicBezierMotion(int, int, int, float, float, float, float)
,但这些值与我在其他地方和在此示例中看到的明显不同:
在使用CN1的Motion
类的示例中,如何实现运动?
Motion.createEaseInOutMotion
随时间变化的值看起来也太线性而无用。
Motion.createEaseInMotion
和Motion.createEaseOutMotion
随时间推移的值看起来很奇怪,或者可能已交换。
我使用错了吗?或者我应该如何使用和理解呢?
以下是用于查看CN1动作的应用程序:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.codename1.ui.Component;
import com.codename1.ui.Container;
import com.codename1.ui.Form;
import com.codename1.ui.Graphics;
import com.codename1.ui.Label;
import com.codename1.ui.TextField;
import com.codename1.ui.animations.Motion;
import com.codename1.ui.geom.Dimension;
import com.codename1.ui.geom.Point;
import com.codename1.ui.layouts.BorderLayout;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.layouts.FlowLayout;
import com.codename1.ui.layouts.GridBagConstraints;
import com.codename1.ui.layouts.GridBagLayout;
public class FormMotionCourse extends Form {
private abstract class Plotter extends Component {
@Override
public void paint(Graphics aGraphics) {
super.paint(aGraphics);
aGraphics.setColor(0x000000);
int width = getWidth();
int height = getHeight();
int minExtent = Math.min(width, height);
int size = minExtent * 90 / 100;
int shiftX = (width - size) / 2;
int shiftY = (height -size) / 2;
int start = 0;
int destination = size;
Motion motion = getMotion(start, destination);
motion.setStartTime(0);
List<Point> points = new ArrayList<>();
for (int xAxis = 0; xAxis < destination; xAxis++) {
motion.setCurrentMotionTime(xAxis);
int yAxis = motion.getValue();
points.add(new Point(xAxis, yAxis));
}
for (Point point: points) {
aGraphics.drawChar('+', getX() + shiftX + point.getX(), getY() + shiftY + point.getY());
}
aGraphics.setColor(0x20aa20);
aGraphics.drawString("Time ->", minExtent - size, height - size);
}
protected abstract Motion getMotion(int aStart, int aDestination);
@Override
protected Dimension calcPreferredSize() {
return new Dimension(300, 300);
}
}
private interface Row {
Plotter getPlotter();
Component getControls();
}
public FormMotionCourse() {
super("FormMotionCourse");
setLayout(BoxLayout.y());
setScrollable(true);
List<Row> rows = Arrays.asList(
createCubicBezierRow(),
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createEaseInOutMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("EaseInOutMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createEaseMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("EaseMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createEaseInMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("EaseInMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createEaseOutMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("EaseOutMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createLinearMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("LinearMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createSplineMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("SplineMotion");
}
},
new Row() {
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createDecelerationMotion(aDestination, aStart, aDestination);
}
};
}
@Override
public Component getControls() {
return new Label("DecelerationMotion");
}
});
for (Row row: rows) {
Container container = new Container(new BorderLayout()) {
@Override
public void paint(Graphics aGraphics) {
super.paint(aGraphics);
aGraphics.setColor(0x888888);
aGraphics.drawRoundRect(getX(), getY(), getWidth() - 1, getHeight(), 20, 20);
}
};
container.add(BorderLayout.WEST, row.getPlotter());
container.add(BorderLayout.CENTER, FlowLayout.encloseCenterMiddle(row.getControls()));
add(container);
}
}
private Row createCubicBezierRow() {
return new Row() {
float p1 = 0, p2 = 1.75f, p3 = 0.75f, p4 = 1.0f;
@Override
public Plotter getPlotter() {
return new Plotter() {
@Override
protected Motion getMotion(int aStart, int aDestination) {
return Motion.createCubicBezierMotion(aDestination, aStart, aDestination, p1, p2, p3, p4);
}
};
}
@Override
public Component getControls() {
Container container = new Container(new GridBagLayout());
int y = 1;
{ // Caption
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridwidth = 2;
constraints.gridy = y++;
container.add(constraints, new Label("CubicBezierMotion"));
}
{ // label p1
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = y;
container.add(constraints, new Label("p1:"));
}
{ // Field p1
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = y++;
TextField textField = new TextField(5);
textField.setText(p1 + "");
textField.setConstraint(TextField.DECIMAL);
textField.addDataChangedListener((aType, aIndex) -> {
try {
p1 = Float.parseFloat(textField.getText());
} catch (NumberFormatException aNumberFormatException) {
}
});
container.add(constraints, textField);
}
{ // label p2
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = y;
container.add(constraints, new Label("p2:"));
}
{ // Field p2
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = y++;
TextField textField = new TextField(5);
textField.setText(p2 + "");
textField.setConstraint(TextField.DECIMAL);
textField.addDataChangedListener((aType, aIndex) -> {
try {
p2 = Float.parseFloat(textField.getText());
} catch (NumberFormatException aNumberFormatException) {
}
});
container.add(constraints, textField);
}
{ // label p3
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = y;
container.add(constraints, new Label("p3:"));
}
{ // Field p3
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = y++;
TextField textField = new TextField(5);
textField.setText(p3 + "");
textField.setConstraint(TextField.DECIMAL);
textField.addDataChangedListener((aType, aIndex) -> {
try {
p3 = Float.parseFloat(textField.getText());
} catch (NumberFormatException aNumberFormatException) {
}
});
container.add(constraints, textField);
}
{ // label p4
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = y;
container.add(constraints, new Label("p4:"));
}
{ // Field p4
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 2;
constraints.gridy = y++;
TextField textField = new TextField(5);
textField.setText(p4 + "");
textField.setConstraint(TextField.DECIMAL);
textField.addDataChangedListener((aType, aIndex) -> {
try {
p4 = Float.parseFloat(textField.getText());
} catch (NumberFormatException aNumberFormatException) {
}
});
container.add(constraints, textField);
}
return container;
}
};
}
}