Add uniform keyframe scaling

Fix timeline updating issue
This commit is contained in:
JannisX11 2021-08-11 23:46:19 +02:00
parent 75fe2f58f8
commit f20f256c15
6 changed files with 42 additions and 35 deletions

View File

@ -913,7 +913,10 @@ class BoneAnimator extends GeneralAnimator {
}
});
keyframe.extend({
interpolation: closest && closest.interpolation
interpolation: closest && closest.interpolation,
uniform: (keyframe.channel == 'scale')
? (closest && closest.uniform && closest.data_points[0].x == closest.data_points[0].y && closest.data_points[0].x == closest.data_points[0].z)
: undefined,
})
} else {
keyframe.extend(values)

View File

@ -92,7 +92,13 @@ class Keyframe {
set(axis, value, data_point = 0) {
if (data_point) data_point = Math.clamp(data_point, 0, this.data_points.length-1);
if (this.data_points[data_point]) {
this.data_points[data_point][axis] = value;
if (this.uniform) {
this.data_points[data_point].x = value;
this.data_points[data_point].y = value;
this.data_points[data_point].z = value;
} else {
this.data_points[data_point][axis] = value;
}
}
return this;
}
@ -379,22 +385,9 @@ class Keyframe {
}
}
Keyframe.prototype.menu = new Menu([
//Quaternions have been removed in Bedrock 1.10.0
/*
{name: 'menu.keyframe.quaternion',
icon: (keyframe) => (keyframe.isQuaternion ? 'check_box' : 'check_box_outline_blank'),
condition: (keyframe) => keyframe.channel === 'rotation',
click: function(keyframe) {
keyframe.select()
var state = !keyframe.isQuaternion
Timeline.keyframes.forEach((kf) => {
kf.isQuaternion = state
})
updateKeyframeSelection()
}
},*/
'change_keyframe_file',
'_',
'keyframe_uniform',
'keyframe_interpolation',
{name: 'menu.cube.color', icon: 'color_lens', children: [
{icon: 'bubble_chart', name: 'generic.unset', click: function(kf) {kf.forSelected(kf2 => {kf2.color = -1}, 'change color')}},
@ -423,6 +416,7 @@ class Keyframe {
// Misc Functions
function updateKeyframeValue(axis, value, data_point) {
Timeline.selected.forEach(function(kf) {
if (axis == 'uniform' && kf.channel == 'scale') kf.uniform = true;
kf.set(axis, value, data_point);
})
if (!['effect', 'locator', 'script'].includes(axis)) {
@ -439,6 +433,10 @@ function updateKeyframeSelection() {
if (Timeline.selected.length) {
BarItems.slider_keyframe_time.update()
BarItems.keyframe_interpolation.set(Timeline.selected[0].interpolation)
if (BarItems.keyframe_uniform.value != !!Timeline.selected[0].uniform) {
BarItems.keyframe_uniform.value = !!Timeline.selected[0].uniform;
BarItems.keyframe_uniform.updateEnabledState();
}
}
if (settings.motion_trails.value && Modes.animate && Animation.selected && (Group.selected || NullObject.selected[0] || Project.motion_trail_lock)) {
Animator.showMotionTrail();
@ -626,6 +624,20 @@ BARS.defineActions(function() {
Undo.finishEdit('Change keyframe time')
}
})
new Toggle('keyframe_uniform', {
icon: 'link',
category: 'animation',
condition: () => Animator.open && Timeline.selected.length && !Timeline.selected.find(kf => kf.channel !== 'scale'),
onChange(value) {
let keyframes = Timeline.selected;
Undo.initEdit({keyframes})
keyframes.forEach((kf) => {
kf.uniform = value;
})
Undo.finishEdit('Change keyframes uniform setting')
updateKeyframeSelection();
}
})
new BarSelect('keyframe_interpolation', {
category: 'animation',
condition: () => Animator.open && Timeline.selected.length && Timeline.selected.find(kf => kf.transform),
@ -833,7 +845,6 @@ Interface.definePanels(function() {
components: {VuePrismEditor},
data() { return {
keyframes: Timeline.selected,
uniform_scale: true,
channel_colors: {
x: 'color_x',
y: 'color_y',
@ -842,13 +853,7 @@ Interface.definePanels(function() {
}},
methods: {
updateInput(axis, value, data_point) {
if (axis == 'uniform') {
updateKeyframeValue('x', value, data_point);
updateKeyframeValue('y', value, data_point);
updateKeyframeValue('z', value, data_point);
} else {
updateKeyframeValue(axis, value, data_point);
}
updateKeyframeValue(axis, value, data_point);
},
getKeyframeInfos() {
let list = [tl('timeline.'+this.channel)];
@ -915,14 +920,6 @@ Interface.definePanels(function() {
<div id="keyframe_type_label">
<label>{{ tl('panel.keyframe.type', [getKeyframeInfos()]) }}</label>
<div
class="in_list_button"
v-if="channel == 'scale'"
v-on:click.stop="uniform_scale = !uniform_scale"
title="${ tl('panel.keyframe.toggle_uniform_scale') }"
>
<i class="material-icons">{{ uniform_scale ? 'calendar_view_day' : 'view_list' }}</i>
</div>
<div
class="in_list_button"
v-if="(keyframes[0].transform && keyframes[0].data_points.length <= 1) || channel == 'particle' || channel == 'sound'"
@ -945,7 +942,7 @@ Interface.definePanels(function() {
</div>
</div>
<template v-if="channel == 'scale' && uniform_scale && data_point.x_string == data_point.y_string && data_point.y_string == data_point.z_string">
<template v-if="channel == 'scale' && keyframes[0].uniform && data_point.x_string == data_point.y_string && data_point.y_string == data_point.z_string">
<div
class="bar flex"
id="keyframe_bar_uniform_scale"

View File

@ -423,8 +423,8 @@ const Timeline = {
clear() {
Timeline.animators.purge();
Timeline.selected.empty();
Timeline.vue._data.markers = [];
Timeline.vue._data.animation_length = 0;
Timeline.vue.markers = [];
Timeline.vue.animation_length = 0;
updateKeyframeSelection();
},
start() {

View File

@ -1828,10 +1828,14 @@ const BARS = {
children: [
'slider_keyframe_time',
'keyframe_interpolation',
'keyframe_uniform',
'change_keyframe_file',
'reset_keyframe'
]
})
Blockbench.onUpdateTo('4.0', () => {
Toolbars.keyframe.add(BarItems.keyframe_uniform, 2);
})
Toolbars.timeline = new Toolbar({
id: 'timeline',
children: [

View File

@ -177,6 +177,7 @@ class ModelProject {
Animation.selected = null;
let selected_anim = this.animations.find(anim => anim.selected);
if (selected_anim) selected_anim.select();
Timeline.animators = this.timeline_animators;
Timeline.vue.animators = this.timeline_animators;
Interface.Panels.variable_placeholders.inside_vue.text = this.variable_placeholders.toString();

View File

@ -1104,6 +1104,8 @@
"action.keyframe_interpolation.desc": "Select the keyframe interpolation mode",
"action.keyframe_interpolation.linear": "Linear",
"action.keyframe_interpolation.catmullrom": "Smooth",
"action.keyframe_uniform": "Uniform Scaling",
"action.keyframe_uniform.desc": "Enable uniform scaling on the selected keyframes",
"action.change_keyframe_file": "Select Keyframe File",
"action.change_keyframe_file.desc": "Select an audio or particle file to preview an effect",
"action.reset_keyframe": "Reset Keyframe",