mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-27 04:21:46 +08:00
Add uniform keyframe scaling
Fix timeline updating issue
This commit is contained in:
parent
75fe2f58f8
commit
f20f256c15
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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() {
|
||||
|
@ -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: [
|
||||
|
@ -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();
|
||||
|
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user