mirror of
https://github.com/JannisX11/blockbench.git
synced 2024-11-21 01:13:37 +08:00
Molang syntax highlighting in keyframe panel
This commit is contained in:
parent
53871c4bc7
commit
687bf00a1b
@ -457,20 +457,76 @@
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
/* Keyframe Panel */
|
||||
.panel#keyframe .tabs_small label {
|
||||
font-size: 1em;
|
||||
height: 30px;
|
||||
width: 25%;
|
||||
}
|
||||
.panel#keyframe .bar.flex {
|
||||
height: auto;
|
||||
min-height: 30px;
|
||||
}
|
||||
.panel .bar.flex label {
|
||||
margin: 3px 8px;
|
||||
min-width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.panel#keyframe .bar input.dark_bordered {
|
||||
width: calc(100% - 45px);
|
||||
width: 100%;
|
||||
flex-shrink: 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.molang_input {
|
||||
overflow-y: hidden;
|
||||
min-height: 30px;
|
||||
height: auto;
|
||||
}
|
||||
.molang_input pre {
|
||||
padding: 2px;
|
||||
min-height: 28px;
|
||||
background-color: transparent;
|
||||
cursor: default;
|
||||
}
|
||||
.molang_input pre code {
|
||||
color: #bec2ca;
|
||||
padding: 0;
|
||||
cursor: auto;
|
||||
}
|
||||
|
||||
.molang_input pre .token.punctuation {
|
||||
color: #5ba8c5
|
||||
}
|
||||
.molang_input pre .token.operator, .molang_input pre .token.keyword {
|
||||
color: #fc2f40
|
||||
}
|
||||
.molang_input pre .token.number, .molang_input pre .token.boolean {
|
||||
color: #b99cff
|
||||
}
|
||||
.molang_input pre .token.function-name {
|
||||
color: #94e400
|
||||
}
|
||||
.molang_input pre .token.selector {
|
||||
color: #92dcff;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*Timeline*/
|
||||
#timeline {
|
||||
display: block;
|
||||
|
37
index.html
37
index.html
@ -42,6 +42,7 @@
|
||||
<script src="lib/gif.js"></script>
|
||||
<script src="lib/prism.js"></script>
|
||||
<script src="lib/VuePrismEditor.min.js"></script>
|
||||
<script src="lib/molang-prism-syntax.js"></script>
|
||||
<script src="lib/lzutf8.js"></script>
|
||||
<script src="lib/peer.min.js"></script>
|
||||
<script src="lib/marked.min.js"></script>
|
||||
@ -803,42 +804,6 @@
|
||||
</div>
|
||||
|
||||
|
||||
<div id="keyframe" class="panel">
|
||||
<div class="toolbar_wrapper keyframe"></div>
|
||||
<p class="tl" id="keyframe_type_label"></p>
|
||||
<div class="bar flex" id="keyframe_bar_x">
|
||||
<label class="color_x" style="font-weight: bolder">X</label>
|
||||
<input type="text" id="keyframe_x" class="dark_bordered code keyframe_input tab_target" axis="x" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_y">
|
||||
<label class="color_y" style="font-weight: bolder">Y</label>
|
||||
<input type="text" id="keyframe_y" class="dark_bordered code keyframe_input tab_target" axis="y" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_z">
|
||||
<label class="color_z" style="font-weight: bolder">Z</label>
|
||||
<input type="text" id="keyframe_z" class="dark_bordered code keyframe_input tab_target" axis="z" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_w">
|
||||
<label>W</label>
|
||||
<input type="text" id="keyframe_w" class="dark_bordered code keyframe_input tab_target" axis="w" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_effect">
|
||||
<label class="tl">data.effect</label>
|
||||
<input type="text" id="keyframe_effect" class="dark_bordered code keyframe_input tab_target" axis="effect" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_locator">
|
||||
<label class="tl">data.locator</label>
|
||||
<input type="text" id="keyframe_locator" class="dark_bordered code keyframe_input tab_target" axis="locator" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_script">
|
||||
<label class="tl">timeline.pre_effect_script</label>
|
||||
<input type="text" id="keyframe_script" class="dark_bordered code keyframe_input tab_target" axis="script" oninput="updateKeyframeValue(this)">
|
||||
</div>
|
||||
<div class="bar" id="keyframe_bar_instructions">
|
||||
<label class="tl">timeline.timeline</label>
|
||||
<textarea id="keyframe_instructions" style="height: 90px;" class="code keyframe_input tab_target" axis="instructions" oninput="updateKeyframeValue(this)"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="variable_placeholders" class="panel grow">
|
||||
<p class="tl">panel.variable_placeholders.info</p>
|
||||
|
@ -342,9 +342,7 @@ class Keyframe {
|
||||
])
|
||||
|
||||
// Misc Functions
|
||||
function updateKeyframeValue(obj) {
|
||||
var axis = $(obj).attr('axis');
|
||||
var value = $(obj).val();
|
||||
function updateKeyframeValue(axis, value) {
|
||||
Timeline.selected.forEach(function(kf) {
|
||||
kf.set(axis, value);
|
||||
})
|
||||
@ -353,57 +351,8 @@ function updateKeyframeValue(obj) {
|
||||
}
|
||||
}
|
||||
function updateKeyframeSelection() {
|
||||
var multi_channel = false;
|
||||
var channel = false;
|
||||
Timeline.selected.forEach((kf) => {
|
||||
if (channel === false) {
|
||||
channel = kf.channel
|
||||
} else if (channel !== kf.channel) {
|
||||
multi_channel = true
|
||||
}
|
||||
})
|
||||
$('.panel#keyframe .bar').hide();
|
||||
|
||||
if (Timeline.selected.length && !multi_channel) {
|
||||
var first = Timeline.selected[0]
|
||||
|
||||
$('#keyframe_type_label').text(tl('panel.keyframe.type', [tl('timeline.'+first.channel)] ))
|
||||
|
||||
if (first.animator instanceof BoneAnimator) {
|
||||
function _gt(axis) {
|
||||
var n = first.get(axis);
|
||||
if (typeof n == 'number') return trimFloatNumber(n);
|
||||
return n;
|
||||
}
|
||||
$('#keyframe_bar_x, #keyframe_bar_y, #keyframe_bar_z').show();
|
||||
$('#keyframe_bar_w').toggle(first.channel === 'rotation' && first.isQuaternion)
|
||||
|
||||
$('#keyframe_bar_x input').val(_gt('x'));
|
||||
$('#keyframe_bar_y input').val(_gt('y'));
|
||||
$('#keyframe_bar_z input').val(_gt('z'));
|
||||
if (first.channel === 'rotation' && first.isQuaternion) {
|
||||
$('#keyframe_bar_w input').val(_gt('w'));
|
||||
}
|
||||
} else if (first.channel == 'particle') {
|
||||
$('#keyframe_bar_effect').show();
|
||||
$('#keyframe_bar_effect input').val(first.get('effect'));
|
||||
$('#keyframe_bar_locator').show();
|
||||
$('#keyframe_bar_locator input').val(first.get('locator'));
|
||||
$('#keyframe_bar_script').show();
|
||||
$('#keyframe_bar_script input').val(first.get('script'));
|
||||
|
||||
} else if (first.channel == 'sound') {
|
||||
$('#keyframe_bar_effect').show();
|
||||
$('#keyframe_bar_effect input').val(first.get('effect'));
|
||||
|
||||
} else if (first.channel == 'timeline') {
|
||||
$('#keyframe_bar_instructions').show();
|
||||
$('#keyframe_bar_instructions textarea').val(first.get('instructions'));
|
||||
}
|
||||
if (Timeline.selected.length) {
|
||||
BarItems.slider_keyframe_time.update()
|
||||
} else {
|
||||
$('#keyframe_type_label').text('')
|
||||
$('#keyframe_bar_x, #keyframe_bar_y, #keyframe_bar_z, #keyframe_bar_w').hide()
|
||||
}
|
||||
BARS.updateConditions()
|
||||
Blockbench.dispatchEvent('update_keyframe_selection');
|
||||
|
@ -379,12 +379,79 @@ function setupPanels() {
|
||||
`
|
||||
}
|
||||
})
|
||||
console.log(Timeline)
|
||||
Interface.Panels.keyframe = new Panel({
|
||||
id: 'keyframe',
|
||||
icon: 'timeline',
|
||||
condition: {modes: ['animate']},
|
||||
toolbars: {
|
||||
head: Toolbars.keyframe
|
||||
},
|
||||
component: {
|
||||
name: 'panel-keyframe',
|
||||
components: {VuePrismEditor},
|
||||
data() { return {
|
||||
keyframes: Timeline.selected
|
||||
}},
|
||||
methods: {
|
||||
updateInput(axis, value) {
|
||||
updateKeyframeValue(axis, value)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
channel() {
|
||||
var channel = false;
|
||||
for (var kf of this.keyframes) {
|
||||
if (channel === false) {
|
||||
channel = kf.channel
|
||||
} else if (channel !== kf.channel) {
|
||||
channel = false
|
||||
break;
|
||||
}
|
||||
}
|
||||
return channel;
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<div>
|
||||
<div class="toolbar_wrapper keyframe"></div>
|
||||
|
||||
<template v-if="channel != false">
|
||||
|
||||
<p id="keyframe_type_label">{{ tl('panel.keyframe.type', [tl('timeline.'+channel)]) }}</p>
|
||||
|
||||
<div class="bar flex" id="keyframe_bar_x" v-if="keyframes[0].animator instanceof BoneAnimator">
|
||||
<label class="color_x" style="font-weight: bolder">X</label>
|
||||
<vue-prism-editor class="molang_input dark_bordered keyframe_input tab_target" :value="keyframes[0].x.toString()" v-model="keyframes[0].x" @change="updateInput('x', $event)" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_y" v-if="keyframes[0].animator instanceof BoneAnimator">
|
||||
<label class="color_y" style="font-weight: bolder">Y</label>
|
||||
<vue-prism-editor class="molang_input dark_bordered keyframe_input tab_target" :value="keyframes[0].y.toString()" v-model="keyframes[0].y" @change="updateInput('y', $event)" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_z" v-if="keyframes[0].animator instanceof BoneAnimator">
|
||||
<label class="color_z" style="font-weight: bolder">Z</label>
|
||||
<vue-prism-editor class="molang_input dark_bordered keyframe_input tab_target" :value="keyframes[0].z.toString()" v-model="keyframes[0].z" @change="updateInput('z', $event)" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
|
||||
<div class="bar flex" id="keyframe_bar_effect" v-if="channel == 'particle' || channel == 'sound'">
|
||||
<label>{{ tl('data.effect') }}</label>
|
||||
<input type="text" class="dark_bordered code keyframe_input tab_target" v-model="keyframes[0].effect" @input="updateInput('effect', $event)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_locator" v-if="channel == 'particle'">
|
||||
<label>{{ tl('data.locator') }}</label>
|
||||
<input type="text" class="dark_bordered code keyframe_input tab_target" v-model="keyframes[0].locator" @input="updateInput('locator', $event)">
|
||||
</div>
|
||||
<div class="bar flex" id="keyframe_bar_script" v-if="channel == 'particle'">
|
||||
<label>{{ tl('timeline.pre_effect_script') }}</label>
|
||||
<vue-prism-editor class="molang_input dark_bordered keyframe_input tab_target" v-model="keyframes[0].script" @change="updateInput('script', $event)" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
<div class="bar" id="keyframe_bar_instructions" v-if="channel == 'timeline'">
|
||||
<label>{{ tl('timeline.timeline') }}</label>
|
||||
<vue-prism-editor class="molang_input dark_bordered keyframe_input tab_target" v-model="keyframes[0].instructions" @change="updateInput('instructions', $event)" language="molang" :line-numbers="false" />
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
})
|
||||
Interface.Panels.variable_placeholders = new Panel({
|
||||
|
10
lib/molang-prism-syntax.js
Normal file
10
lib/molang-prism-syntax.js
Normal file
@ -0,0 +1,10 @@
|
||||
Prism.languages.molang = {
|
||||
'string': /("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,
|
||||
'function-name': /\b(?!\d)math\.\w+(?=[\t ]*\()/i,
|
||||
'selector': /\b(?!\d)(query|variable|temp|math)\.\w+/i,
|
||||
'boolean': /\b(?:true|false)\b/i,
|
||||
'number': /(?:\b\d+(?:\.\d+)?(?:[ed][+-]\d+)?|&h[a-f\d]+)\b[%&!#]?/i,
|
||||
'operator': /--|\+\+|>>=?|<<=?|<>|[-+*/\\<>]=?|[:^=?]|\b(?:and|mod|not|or)\b/i,
|
||||
'keyword': /\b(Return)\b/i,
|
||||
'punctuation': /[.,;()[\]{}]/,
|
||||
};
|
Loading…
Reference in New Issue
Block a user