Skip to content

Commit

Permalink
Holding shift now locks bezier handler axis
Browse files Browse the repository at this point in the history
Hold ctrl to snap bezier handles
Closes #1757
Adjust bezier handles when changing animation speed
  • Loading branch information
JannisX11 committed Apr 5, 2024
1 parent 2a7ec4a commit 9e68220
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 7 deletions.
10 changes: 10 additions & 0 deletions js/animations/animation.js
Original file line number Diff line number Diff line change
Expand Up @@ -1199,12 +1199,17 @@ BARS.defineActions(function() {
let initial_times = {};
let initial_snapping = animation.snapping;
let initial_length = animation.length;
let initial_bezier_times = {};
for (let id in animation.animators) {
let animator = animation.animators[id];
keyframes.push(...animator.keyframes);
}
keyframes.forEach(kf => {
initial_times[kf.uuid] = kf.time;
initial_bezier_times[kf.uuid] = {
left: kf.bezier_left_time.slice(),
right: kf.bezier_right_time.slice(),
};
})

let previous_speed = 1;
Expand Down Expand Up @@ -1233,6 +1238,11 @@ BARS.defineActions(function() {
animation.snapping = snapping;
keyframes.forEach(kf => {
kf.time = Timeline.snapTime(initial_times[kf.uuid] / speed, animation);
if (kf.interpolation == 'bezier') {
let old_bezier_time = initial_bezier_times[kf.uuid];
kf.bezier_left_time.V3_set(old_bezier_time.left).V3_divide(speed);
kf.bezier_right_time.V3_set(old_bezier_time.right).V3_divide(speed);
}
})
animation.setLength(initial_length / speed);
TickUpdates.keyframes = true;
Expand Down
40 changes: 33 additions & 7 deletions js/animations/timeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -1007,6 +1007,7 @@ Interface.definePanels(() => {
let time_stretching;
let values_changed;
let is_setup = false;
let old_bezier_values = {};

function setup() {
dragging_range = [Infinity, 0];
Expand All @@ -1029,6 +1030,10 @@ Interface.definePanels(() => {
kf.time_before = kf.time;
dragging_range[0] = Math.min(dragging_range[0], kf.time);
dragging_range[1] = Math.max(dragging_range[1], kf.time);
old_bezier_values[kf.uuid] = {
left: kf.bezier_left_time.slice(),
right: kf.bezier_right_time.slice(),
}
}

if (Timeline.vue.graph_editor_open) {
Expand Down Expand Up @@ -1075,12 +1080,13 @@ Interface.definePanels(() => {
// Time
let difference = 0;
let max, min;
let time_factor = 1;
if ((!e2.ctrlOrCmd && !e2.shiftKey) || time_stretching || !Timeline.vue.graph_editor_open) {
difference = Math.clamp(offset[0] / Timeline.vue._data.size, -256, 256);
[min, max] = dragging_range;

if (time_stretching) {
var time_factor = (clicked && clicked.time_before < (min + max) / 2)
time_factor = (clicked && clicked.time_before < (min + max) / 2)
? ((max-min-difference) / (max-min))
: ((max-min+difference) / (max-min));
time_factor = Math.roundTo(time_factor, 2);
Expand All @@ -1106,7 +1112,7 @@ Interface.definePanels(() => {
}
}

for (var kf of Timeline.selected) {
for (let kf of Timeline.selected) {
if (time_stretching) {
if (clicked && clicked.time_before < (min + max) / 2) {
var t = max - (kf.time_before - max) * -time_factor;
Expand All @@ -1126,6 +1132,11 @@ Interface.definePanels(() => {
if (old_time !== kf.time) {
values_changed = true;
}
if (time_stretching && kf.interpolation == 'bezier') {
let old_bezier = old_bezier_values[kf.uuid];
kf.bezier_left_time.V3_set(old_bezier.left).V3_multiply(time_factor);
kf.bezier_right_time.V3_set(old_bezier.right).V3_multiply(time_factor);
}

if (Timeline.vue.graph_editor_open && value_diff) {
kf.offset(Timeline.vue.graph_editor_axis, value_diff);
Expand Down Expand Up @@ -1182,14 +1193,16 @@ Interface.definePanels(() => {
let is_setup = false;
let axis_number = getAxisNumber(this.graph_editor_axis);
let old_values = {};
let lock_direction;

function setup() {
function setup(offset) {

if (!clicked.selected && !e1.shiftKey && !Pressing.overrides.shift && Timeline.selected.length != 0) {
clicked.select()
} else if (clicked && !clicked.selected) {
clicked.select({shiftKey: true})
}
lock_direction = Math.abs(offset[0]) > Math.abs(offset[1]);

Keyframe.selected.forEach(kf => {
if (kf.interpolation == 'bezier') {
Expand Down Expand Up @@ -1217,15 +1230,28 @@ Interface.definePanels(() => {
]
if (!is_setup) {
if (Math.pow(offset[0], 2) + Math.pow(offset[1], 2) > 20) {
setup();
setup(offset);
} else {
return;
}
}
var difference_time = Math.clamp(offset[0] / Timeline.vue._data.size, -256, 256);
var difference_value = Math.clamp(-offset[1] / Timeline.vue.graph_size, -256, 256);
let difference_time = Math.clamp(offset[0] / Timeline.vue._data.size, -256, 256);
let difference_value = Math.clamp(-offset[1] / Timeline.vue.graph_size, -256, 256);
if (e2.shiftKey || Pressing.overrides.shift) {
if (lock_direction) {
difference_value = 0;
} else {
difference_time = 0;
}
}
if (e2.ctrlOrCmd || Pressing.overrides.ctrl) {
let time_snap = Timeline.getStep();
let val_snap = 0.25;
difference_time = Math.round(difference_time / time_snap) * time_snap;
difference_value = Math.round(difference_value / val_snap) * val_snap;
}

for (var kf of Timeline.selected) {
for (let kf of Timeline.selected) {
if (kf.interpolation == 'bezier') {

kf.bezier_left_time.V3_set(old_values[kf.uuid].bezier_left_time);
Expand Down

0 comments on commit 9e68220

Please # to comment.