blockbench/index.html
JannisX11 cca7221ea1 Fix issue with stretched texture in UV editor
Fix launch issue after folding UV panel
Fix some panels not folding correctly
Make buildGrid available in global scope again
Fix incorrect title for display presets dialog
Fix #1354 Delete in main menu only works for elements/groups
2022-03-30 12:53:02 +02:00

464 lines
20 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<title>Blockbench</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#181a1f">
<meta name="robots" content="noindex">
<link rel="manifest" href="manifest.webmanifest">
<link rel="shortcut icon" href="favicon.png" type="image/x-icon" />
<link rel="apple-touch-icon" href="icon_full.png">
<link rel="stylesheet" href="css/w3.css">
<link rel="stylesheet" href="css/jquery-ui.min.css">
<link rel="stylesheet" href="css/fontawesome.css">
<link rel="stylesheet" href="css/spectrum.css">
<link rel="stylesheet" href="css/prism.css">
<link rel="stylesheet" href="css/setup.css">
<link rel="stylesheet" href="css/general.css">
<link rel="stylesheet" href="css/window.css">
<link rel="stylesheet" href="css/panels.css">
<link rel="stylesheet" href="css/dialogs.css">
<style type="text/css" id="theme_css"></style>
</head>
<body spellcheck="false">
<script>
if (typeof module === 'object') {window.module = module; module = undefined;}//jQuery Fix
const isApp = typeof require !== 'undefined';
const appVersion = '4.2.0';
if (localStorage.getItem('theme')) {
try {
stored_theme = JSON.parse(localStorage.getItem('theme'));
document.body.style.setProperty('--color-dark', stored_theme.colors.dark);
} catch (err) {}
}
window.onerror = (message, file, line) => {
if (typeof Blockbench != 'undefined' && Blockbench.setup_successful) return;
let error_element = document.querySelector('#loading_error_detail');
if (error_element && !error_element.innerText) {
error_element.innerText = `${message}\nIn .${file.split(location.origin).join('')}:${line}`
}
}
</script>
<div id="loading_error_message" style="display: none;">
<div>An error occurred while loading Blockbench</div>
<div id="loading_error_detail" style="color: var(--color-subtle_text);"></div>
<button onclick="isApp ? Blockbench.reload() : window.location.reload(true)" class="large" style="margin-right: auto; margin-left: auto;">Reload</button>
<button onclick="window.close()" class="large" style="margin-right: auto; margin-left: auto;">Quit</button>
</div>
<script src="lib/vue.min.js"></script>
<script src="lib/vue_sortable.js"></script>
<script src="lib/jquery.js"></script>
<script src="lib/jquery-ui.min.js"></script>
<script src="lib/targa.js"></script>
<script src="lib/jimp.min.js"></script>
<script src="lib/jszip.min.js"></script>
<script src="lib/gif.js"></script>
<script src="lib/FileSaver.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>
<script src="lib/spectrum.js"></script>
<script src="lib/color-picker.min.js"></script>
<script src="lib/three.min.js"></script>
<script src="lib/three_custom.js"></script>
<script src="lib/GLTFExporter.js"></script>
<script src="lib/CanvasFrame.js"></script>
<script src="lib/fik.min.js"></script>
<script src="lib/molang.umd.js"></script>
<script src="lib/wintersky.umd.js"></script>
<script src="js/webpack/bundle.js"></script>
<script src="js/preview/OrbitControls.js"></script>
<script src="js/util.js"></script>
<script src="js/property.js"></script>
<script src="js/interface/menu.js"></script>
<script src="js/interface/actions.js"></script>
<script src="js/interface/themes.js"></script>
<script src="js/blockbench.js"></script>
<script src="js/modes.js"></script>
<script src="js/api.js"></script>
<script src="js/file_system.js"></script>
<script src="js/interface/panels.js"></script>
<script src="js/interface/interface.js"></script>
<script src="js/interface/start_screen.js"></script>
<script src="js/interface/keyboard.js"></script>
<script src="js/interface/settings.js"></script>
<script src="js/interface/about.js"></script>
<script src="js/interface/dialog.js"></script>
<script src="js/interface/action_control.js"></script>
<script src="js/copy_paste.js"></script>
<script src="js/undo.js"></script>
<script type="text/javascript">
if (isApp === true) {
document.write("<script src='js/desktop.js'><\/script>");
} else {
document.write("<script src='js/web.js'><\/script>");
}
</script>
<script src="js/edit_sessions.js"></script>
<script src="js/outliner/outliner.js"></script>
<script src="js/outliner/group.js"></script>
<script src="js/outliner/mesh.js"></script>
<script src="js/outliner/cube.js"></script>
<script src="js/outliner/texture_mesh.js"></script>
<script src="js/outliner/locator.js"></script>
<script src="js/outliner/null_object.js"></script>
<script src="js/preview/preview.js"></script>
<script src="js/preview/screenshot.js"></script>
<script src="js/preview/canvas.js"></script>
<script src="js/preview/transformer.js"></script>
<script src="js/transform.js"></script>
<script src="js/texturing/textures.js"></script>
<script src="js/texturing/uv.js"></script>
<script src="js/texturing/painter.js"></script>
<script src="js/texturing/texture_generator.js"></script>
<script src="js/texturing/color.js"></script>
<script src="js/texturing/edit_texture.js"></script>
<script src="js/display_mode.js"></script>
<script src="js/animations/animation.js"></script>
<script src="js/animations/timeline_animators.js"></script>
<script src="js/animations/keyframe.js"></script>
<script src="js/animations/timeline.js"></script>
<script src="js/plugin_loader.js"></script>
<script src="js/io/codec.js"></script>
<script src="js/io/format.js"></script>
<script src="js/io/project.js"></script>
<script src="js/io/io.js"></script>
<script src="js/io/formats/bbmodel.js"></script>
<script src="js/io/formats/java_block.js"></script>
<script src="js/io/formats/bedrock.js"></script>
<script src="js/io/formats/bedrock_old.js"></script>
<script src="js/io/formats/obj.js"></script>
<script src="js/io/formats/gltf.js"></script>
<script src="js/io/formats/collada.js"></script>
<script src="js/io/formats/modded_entity.js"></script>
<script src="js/io/formats/optifine_jem.js"></script>
<script src="js/io/formats/optifine_jpm.js"></script>
<script src="js/io/formats/skin.js"></script>
<script src="js/globals.js"></script>
<script>if (window.module) module = window.module;</script>
<div style="display: none;"></div>
<div id="overlay_message_box" style="display: none;">
<div>
<h3><i class="material-icons">keyboard</i><span class="tl">keybindings.recording</span></h3>
<p class="tl">keybindings.press</p>
<button class="tl" onclick="Keybinds.recording.stopRecording()">dialog.cancel</button>
<button class="tl" onclick="Keybinds.recording.clear().stopRecording()">keybindings.clear</button>
<div id="keybind_input_box" contenteditable="true" style="font-size: 0"></div>
</div>
</div>
<dialog class="dialog draggable" id="entity_import">
<div class="dialog_handle">
<div class="dialog_title tl">dialog.entitylist.title</div>
</div>
<div class="dialog_content">
<div class="dialog_bar narrow tl">dialog.entitylist.text</div>
<div class="search_bar">
<input type="text" class="dark_bordered" id="pe_search_bar" oninput="pe_list._data.search_term = $(this).val().toUpperCase()">
<i class="material-icons" id="plugin_search_bar_icon">search</i>
</div>
<ul id="pe_list" class="list">
<li v-for="item in searched" v-bind:class="{ selected: item.selected }" v-on:click="selectE(item, $event)" v-on:dblclick="open(item)">
<img class="pe_icon" v-if="item.icon" v-bind:src="item.icon">
<div class="pe_icon" v-else></div>
<h4>{{ item.title }} <span>({{ item.name }})</span></h4>
<p>{{ item.bonecount+' '+tl('dialog.entitylist.bones') }}, {{ item.cubecount+' '+tl('dialog.entitylist.cubes') }}</p>
</li>
</ul>
</div>
<div class="dialog_bar button_bar">
<button type="button" class="tl confirm_btn" onclick="">dialog.import</button>
<button type="button" class="cancel_btn tl" onclick="hideDialog();BarItems.close_project.click()">dialog.cancel</button>
</div>
<div class="dialog_close_button" onclick="hideDialog();BarItems.close_project.click()"><i class="material-icons">clear</i></div>
</dialog>
<dialog class="dialog draggable" id="image_extruder">
<div class="dialog_handle">
<div class="dialog_title tl">dialog.extrude.title</div>
</div>
<div class="dialog_content">
<div class="dialog_bar">
<label class="tl">dialog.extrude.mode</label>
<div class="bar_select f_left">
<select id="scan_mode" name="scan_mode">
<option class="tl" id="areas" selected>dialog.extrude.mode.areas</option>
<option class="tl" id="lines">dialog.extrude.mode.lines</option>
<option class="tl" id="columns">dialog.extrude.mode.columns</option>
<option class="tl" id="pixels">dialog.extrude.mode.pixels</option>
</select>
</div>
</div>
<div class="dialog_bar">
<label class="tl">dialog.extrude.opacity</label>
<input class="tool" type="range" id="scan_tolerance" value="255" min="1" max="255">
<label id="scan_tolerance_label">255</label>
</div>
<canvas height="256" width="256" id="extrusion_canvas"></canvas>
</div>
<div class="dialog_bar button_bar">
<button type="button" class="confirm_btn tl" onclick="Extruder.startConversion()">Scan and Import</button>
<button type="button" class="cancel_btn tl" onclick="hideDialog()">dialog.cancel</button>
</div>
<div class="dialog_close_button" onclick="hideDialog()"><i class="material-icons">clear</i></div>
</dialog>
<dialog class="dialog draggable" id="scaling">
<div class="dialog_handle">
<div class="dialog_title tl">dialog.scale.title</div>
</div>
<div class="dialog_content">
<label class="tl">dialog.scale.axis</label>
<div class="dialog_bar" style="height: 32px;">
<input type="checkbox" class="toggle_panel" id="model_scale_x_axis" onchange="scaleAll()" checked>
<label class="toggle_panel" for="model_scale_x_axis">X</label>
<input type="checkbox" class="toggle_panel" id="model_scale_y_axis" onchange="scaleAll()" checked>
<label class="toggle_panel" for="model_scale_y_axis">Y</label>
<input type="checkbox" class="toggle_panel" id="model_scale_z_axis" onchange="scaleAll()" checked>
<label class="toggle_panel" for="model_scale_z_axis">Z</label>
</div>
<label class="tl">data.origin</label>
<div class="dialog_bar">
<label for="scaling_origin_x" class="inline_label tl">X</label>
<input type="number" id="scaling_origin_x" class="dark_bordered medium_width" oninput="scaleAll()">
<label for="scaling_origin_y" class="inline_label tl">Y</label>
<input type="number" id="scaling_origin_y" class="dark_bordered medium_width" oninput="scaleAll()">
<label for="scaling_origin_z" class="inline_label tl">Z</label>
<input type="number" id="scaling_origin_z" class="dark_bordered medium_width" oninput="scaleAll()">
<div class="tool" style="float: none" onclick="setScaleAllPivot('origin')">
<div class="tooltip tl">dialog.scale.element_pivot</div>
<i class="material-icons">center_focus_strong</i>
</div>
<div class="tool" style="float: none" onclick="setScaleAllPivot('selection')">
<div class="tooltip tl">dialog.scale.selection_center</div>
<i class="material-icons">filter_tilt_shift</i>
</div>
</div>
<label class="tl">dialog.scale.scale</label>
<div class="dialog_bar" style="height: 32px;">
<input type="range" id="model_scale_range" value="1" min="0" max="4" step="0.02" oninput="modelScaleSync()">
<input type="number" class="f_left dark_bordered" id="model_scale_label" min="0" max="4" step="0.02" value="1" oninput="modelScaleSync(true)">
</div>
<div class="dialog_bar narrow" id="scaling_clipping_warning"></div>
</div>
<div class="dialog_bar button_bar">
<button type="button" onclick="scaleAll(true)" class="confirm_btn tl">dialog.scale.confirm</button>
<button type="button" class="cancel_btn tl" onclick="cancelScaleAll()">dialog.cancel</button>
<button type="button" class="minor hidden tl" id="scale_overflow_btn" onclick="scaleAllSelectOverflow()">dialog.scale.select_overflow</button>
</div>
<div class="dialog_close_button" onclick="cancelScaleAll()"><i class="material-icons">clear</i></div>
</dialog>
<dialog class="dialog draggable" id="create_preset">
<div class="dialog_handle">
<div class="dialog_title tl">dialog.display_preset.title</div>
</div>
<div class="dialog_content">
<div class="dialog_bar tl">dialog.display_preset.message</div>
<div class="dialog_bar">
<input type="checkbox" id="thirdperson_righthand_save" checked>
<label for="thirdperson_righthand_save" class="tl">display.slot.third_right</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="thirdperson_lefthand_save" checked>
<label for="thirdperson_lefthand_save" class="tl">display.slot.third_left</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="firstperson_righthand_save" checked>
<label for="firstperson_righthand_save" class="tl">display.slot.first_right</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="firstperson_lefthand_save" checked>
<label for="firstperson_lefthand_save" class="tl">display.slot.first_left</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="head_save" checked>
<label for="head_save" class="tl">display.slot.head</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="ground_save" checked>
<label for="ground_save" class="tl">display.slot.ground</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="fixed_save" checked>
<label for="fixed_save" class="tl">display.slot.frame</label>
</div>
<div class="dialog_bar">
<input type="checkbox" id="gui_save" checked>
<label for="gui_save" class="tl">display.slot.gui</label>
</div>
<div class="dialog_bar narrow">
<label class="tl">generic.name</label>
</div>
<div class="dialog_bar">
<input type="text" id="preset_name" class="input_wide" id="new preset">
</div>
</div>
<div class="dialog_bar button_bar">
<button type="button" class="tl confirm_btn" onclick="DisplayMode.createPreset()">dialog.display_preset.create</button>
<button type="button" class="tl cancel_btn" onclick="hideDialog()">dialog.cancel</button>
</div>
<div class="dialog_close_button" onclick="hideDialog()"><i class="material-icons">clear</i></div>
</dialog>
<dialog class="dialog draggable" id="text_input">
<div class="dialog_handle">
<div class="dialog_title tl">dialog.input.title</div>
</div>
<div class="dialog_content">
<input type="text" id="text_input_field" class="dark_bordered input_wide">
</div>
<div class="dialog_bar button_bar">
<button type="button" class="confirm_btn tl" onclick="hideDialog()">dialog.confirm</button>
<button type="button" class="cancel_btn tl" onclick="hideDialog()">dialog.cancel</button>
</div>
<div class="dialog_close_button" onclick="hideDialog()"><i class="material-icons">clear</i></div>
</dialog>
<div id="dialog_wrapper"></div>
<header>
<ul id="mac_window_menu" hidden></ul>
<div id="corner_logo" class="app-drag-region">
<img class="blockbench_logo" src="assets/logo_text_white.svg" alt="Blockbench" />
</div>
<ul id="menu_bar" class="scroll_horizontal"></ul>
<div id="title_bar_home_button" class="tool" onclick="Interface.tab_bar.openNewTab()"><i class="material-icons">home</i></div>
<div id="title_bar_undo_controls" hidden>
<div class="tool" onclick="BarItems.undo.trigger()"><i class="material-icons">undo</i></div>
<div class="tool" onclick="BarItems.redo.trigger()"><i class="material-icons">redo</i></div>
</div>
<div class="app-drag-region" id="header_free_bar"></div>
<div id="update_menu"></div>
<ul id="windows_window_menu" hidden>
<li onclick="currentwindow.minimize()"><i class="material-icons" style="margin-top: 4px;">remove</i></li>
<li onclick="currentwindow.isMaximized() ? currentwindow.unmaximize() : currentwindow.maximize()"><i class="material-icons">crop_square</i><!--🗖--></li>
<li class="wwm_r" onclick="currentwindow.close()"><i class="material-icons">clear</i></li>
</ul>
<button id="web_download_button" hidden><a class="tl" href="https://blockbench.net/downloads">web.download_app</a></button>
</header>
<div id="page_wrapper" class="invisible start_screen">
<div id="blackout" class="darken"></div>
<div id="tab_bar" :class="{drag_mode: drag_target_index !== null}">
<div id="tab_bar_list">
<div
class="project_tab"
v-for="(project, index) in tabs" :key="project.uuid"
:class="{
selected: project.selected,
new_tab: project.is_new_tab,
dragging: index == drag_target_index,
move_back: (drag_position_index !== null && index > drag_target_index && drag_position_index >= index),
move_forth: (drag_position_index !== null && index < drag_target_index && drag_position_index <= index)
}"
:title="project.name || project.geometry_name"
@dblclick="project.openSettings()"
@mousedown="mouseDown(project, $event)"
@mouseup="mouseUp(project, $event)"
@mouseenter="mouseEnter(project, $event)"
@mouseleave="mouseLeave(project, $event)"
>
<label class="project_tab_session_badge" v-if="project.EditSession"><i class="material-icons">group</i>{{ project.EditSession.client_count }}</label>
<label>{{ project.getDisplayName() }}</label>
<div class="project_tab_close_button" :class="{unsaved: !project.saved}" :title="close_tab_label" @click="project.close()">
<i class="material-icons close_icon">clear</i>
<i class="material-icons unsaved_icon" v-if="!project.saved">fiber_manual_record</i>
</div>
</div>
<div id="new_tab_button" v-if="!new_tab.visible" @click="openNewTab()" :title="new_tab.name">
<i class="material-icons">add</i>
</div>
</div>
<div id="search_tab_button" v-if="projects.length > 1" @click="searchTabs()" :title="search_tabs_label">
<i class="material-icons">search</i>
</div>
</div>
<dialog id="action_selector"></dialog>
<div id="start_screen"></div>
<div id="work_screen" hidden>
<div id="main_toolbar">
<div class="toolbar_wrapper narrow tools"></div>
<div class="toolbar_wrapper narrow tool_options"></div>
<ul id="mode_selector">
<li
v-for="mode in options"
v-if="Condition(mode.condition)"
v-bind:class="{selected: mode.selected}"
v-on:mousedown="mode.select()"
>{{ mode.name }}</li>
</ul>
</div>
<div id="left_bar" class="sidebar"></div>
<div id="right_bar" class="sidebar"></div>
<div id="center">
<ul id="toast_notification_list">
</ul>
<div id="top_slot"></div>
<div id="preview">
</div>
<div id="bottom_slot"></div>
<div id="mobile_panel_overlay" hidden></div>
</div>
<div id="status_bar"></div>
<div id="panel_selector_bar"></div>
</div>
</div>
<script src="js/boot_loader.js"></script>
<script>
if (!Blockbench || !Blockbench.setup_successful) {
document.getElementById('loading_error_message').style.display = 'block'
if (window.require) {
require('electron').remote.getCurrentWindow().webContents.openDevTools()
}
} else {
document.getElementById('loading_error_message').innerHTML = 'No loading errors...'
}
</script>
</body>
</html>