var app_colors, canvas_scenes, active_scene; scenesSetup() function colorSettingsSetup(reset) { app_colors = { back: {hex: '#21252b'}, dark: {hex: '#17191d'}, border: {hex: '#181a1f'}, ui: {hex: '#282c34'}, accent: {hex: '#3e90ff'}, grid: {hex: '#495061'}, button: {hex: '#3a3f4b'}, hover: {hex: '#495061'}, text: {hex: '#cacad4'}, light: {hex: '#f4f3ff'}, text_acc: {hex: '#000006'}, main: {font: ''}, headline: {font: ''}, css: '' } if (reset) { $('#layout_font_main').val('') $('#layout_font_headline').val('') changeUIFont('main') changeUIFont('headline') $('style#bbstyle').text('') setScreenRatio() } if (localStorage.getItem('app_colors') != null && reset != true) { var stored_app_colors = JSON.parse(localStorage.getItem('app_colors')) $.extend(app_colors, stored_app_colors) } updateUIColor() buildGrid() } function showDialog(dialog) { var obj = $('.dialog#'+dialog) $('.dialog').hide(0) $('#blackout').fadeIn(200) obj.fadeIn(200) setTimeout(function() { $('.context_handler.ctx').removeClass('ctx') }, 64) open_dialog = dialog Prop.active_panel = 'dialog' //Draggable if (obj.hasClass('draggable')) { obj.draggable({ handle: ".dialog_handle", containment: 'body' }) var x = ($(window).width()-obj.width())/2 obj.css('left', x+'px') obj.css('top', '64px') } //Specific if (dialog === 'file_loader') { $('#file_upload').val('') $('#file_folder').val('') $('#web_import_btn').unbind() } else if (dialog === 'selection_creator') { $('#selection_creator input#selgen_name').select() } else if (dialog === 'plugins') { $('#plugin_list').css('max-height', ($(window).height() - 320) +'px') } } function hideDialog() { $('#blackout').fadeOut(200) $('.dialog').fadeOut(200) open_dialog = false; Prop.active_panel = undefined } function setSettingsTab(tab) { $('#settings .tab.open').removeClass('open') $('#settings .tab#'+tab).addClass('open') $('#settings .tab_content').addClass('hidden') $('#settings .tab_content#'+tab).removeClass('hidden') if (tab === 'keybindings') { //Keybinds $('#keybindlist').css('max-height', ($(window).height() - 320) +'px') } else if (tab === 'setting') { //Settings $('#settingslist').css('max-height', ($(window).height() - 320) +'px') } else if (tab === 'layout_settings') { $('#layout_font_main').val(app_colors.main.font) $('#layout_font_headline').val(app_colors.headline.font) } } function textPrompt(title, var_string, value, callback) { showDialog('text_input') $('#text_input h2').text(title) if (value === true) { //Get Previous Value For Input eval('value = '+var_string) try { eval('value = '+var_string) } catch(err) { console.error(err) } } $('#text_input input#text_input_field').val(value).select() $('#text_input button.confirm_btn').off() $('#text_input button.confirm_btn').click(function() { var s = $('#text_input input#text_input_field').val() if (callback !== undefined) { callback(s) } if (var_string == '') return; try { eval(var_string + ' = "'+s+'"') } catch(err) { console.error(err) } }) } function renameCubeList(name) { elements.forEach(function(obj, i) { if (obj.display.isselected) { obj.name = name.split('%').join(obj.index()).split('$').join(i) } }) } function setActivePanel(panel) { Prop.active_panel = panel } function randomHelpMessage() { var tips = [ 'Go to the Settings menu and select the Keybindings tab to change your keys.', 'Blockbench works as a Program on Windows, macOS and Linux, or as a web app on any device, including tablets.', 'Double click in the canvas or hit spacebar to toggle between the scale and the drag tool.', 'Create groups to manage different parts of your model.', 'Open the Display tab in the top right corner to change how the model looks in your hands.', 'Only open textures that are in your resource pack.', 'Use Fizzy81\'s animation generator to create animated models.', 'Use blockmodels.com or sketchfab.com to share your models.', 'Press Ctrl + P to take a screenshot, press Ctrl + V to paste it into a Discord chat or a tweet.', 'Hold Shift or Ctrl to select multiple cubes', 'Join the Discord server to ask for help: discord.blockbench.net', 'You can load a blueprint of your model to make it easier to get the proportions right. Enter a side view and drag the image into the background. Use the menu on the bottom right to adjust it.', 'There are many useful plugins by the community in the plugin menu. Just click install and go.', 'Keep Blockbench updated. Updates add new functions to Blockbench, fix bugs and installing them is as easy opening the updates screen from the File menu and clicking the Update button', 'Check the Move Relative box in the Edit menu to move cubes on their rotated axis.', 'When you are renaming multiple elements, you can number them by adding the placeholders $ (relative) or % (absolute).' ] var message = tips[Math.floor(Math.random()*tips.length)] Blockbench.showMessageBox({ width: 640, title: 'Tip', icon: 'info', message: message, cancel: 1, confirm: 0, buttons: ['Next', 'Close'] }, function(answer) { if (answer === 0) { randomHelpMessage() } }) } //Scenes function enterScene(scene) { var container = $('div#preview') var scene_controls = $('#scene_controls') if (scene !== true) { active_scene = canvas_scenes[scene] } else { } if (active_scene.background.image !== false) { //Background container.css('background-image', 'url("'+active_scene.background.image.split('\\').join('/')+'")') updateScenePosition() //Panel scene_controls.fadeIn(100) $('#scene_controls_panel').hide(0) scene_controls.find('img').attr('src', active_scene.background.image) scene_controls.find('#scene_controls_toggle i').text('first_page') if (active_scene.background.lock === 'disabled') { scene_controls.find('.scene_lock').hide() } else { scene_controls.find('.scene_lock').show() } } else { container.css('background-image', 'none') scene_controls.fadeOut(100) } } function clearBackgroundImage() { active_scene.background.image = false; enterScene(true) } function updateScenePosition(zoom) { if (zoom === undefined) zoom = 1 if (isOrtho === true && active_scene.background.lock === false) zoom = cameraOrtho.zoom if (active_scene.background.lock === true) zoom = 1 var offset = [0, 0]; if (isOrtho === true && active_scene.background.lock !== true) { offset.forEach(function(s, i) { s = cameraOrtho.backgroundHandle[i].n === true ? 1 : -1 s = s * controls.target[cameraOrtho.backgroundHandle[i].a] s = s * zoom * 40; offset[i] = s }) } var pos_x = offset[0] + (active_scene.background.x * zoom) + c_width/2 - (active_scene.background.size * zoom) / 2 var pos_y = offset[1] + (active_scene.background.y * zoom) + c_height/2 - ((active_scene.background.size / active_scene.background.ratio) * zoom) / 2 $('div#preview').css('background-position', pos_x + 'px ' + pos_y+'px') .css('background-size', active_scene.background.size * zoom +'px') } function updateBackgroundRatio() { //Update Ratio var img = $('#scene_controls img')[0] active_scene.background.ratio = img.naturalWidth / img.naturalHeight updateScenePosition() } function toggleScenePanel() { var scene_controls = $('#scene_controls') if (scene_controls.find('#scene_controls_panel').is(':visible')) { //Hide scene_controls.find('#scene_controls_panel').hide(200) scene_controls.find('#scene_controls_toggle i').text('first_page') } else { //Show scene_controls.find('#scene_controls_panel').show(200) scene_controls.find('#scene_controls_toggle i').text('last_page') scene_controls.find('input#scene_size').val(active_scene.background.size) scene_controls.find('input#scene_x').val(active_scene.background.x) scene_controls.find('input#scene_y').val(active_scene.background.y) scene_controls.find('input#scene_fixed').prop('checked', active_scene.background.y === true) } } function updateScenePanelControls() { var scene_controls = $('#scene_controls') active_scene.background.size = limitNumber(parseInt( scene_controls.find('input#scene_size').val()) ) active_scene.background.x = limitNumber(parseInt( scene_controls.find('input#scene_x').val()) ) active_scene.background.y = limitNumber(parseInt( scene_controls.find('input#scene_y').val()) ) active_scene.background.lock = scene_controls.find('input#scene_fixed').is(':checked') updateScenePosition() } function scenesSetup(reset) { canvas_scenes = { normal: {name: 'Normal', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, ortho0: {name: 'Ortho 0', background: {image: false, size: 1000, x: 0, y: 0}}, ortho1: {name: 'Ortho 1', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: false}}, ortho2: {name: 'Ortho 2', background: {image: false, size: 1200, x: 0, y: 0, ratio: 1, lock: false}}, ortho3: {name: 'Ortho 3', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: false}}, ortho4: {name: 'Ortho 4', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: false}}, ortho5: {name: 'Ortho 5', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: false}}, thirdperson_righthand: {name: 'thirdperson_righthand', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, thirdperson_lefthand: {name: 'thirdperson_lefthand', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, firstperson_righthand: {name: 'firstperson_righthand', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, firstperson_lefthand: {name: 'firstperson_lefthand', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, head: {name: 'head', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, ground: {name: 'ground', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, fixed: {name: 'fixed', background: {image: false, size: 1000, x: 0, y: 0, ratio: 1, lock: 'disabled'}}, gui: {name: 'gui', background: {image: './assets/inventory.png', size: 1020, x: 0, y: 0, ratio: 1, lock: false}} } if (localStorage.getItem('canvas_scenes') != null && reset != true) { var stored_canvas_scenes = JSON.parse(localStorage.getItem('canvas_scenes')) $.extend(canvas_scenes, stored_canvas_scenes) } active_scene = canvas_scenes.normal } //Color function initUIColor(event) { var type = $(event.target).attr('id').split('color_')[1] $('input#color_'+type).val(app_colors[type].hex) } function changeUIColor(event) { var type = $(event.target).attr('id').split('color_')[1] app_colors[type].hex = $('input#color_'+type).val() updateUIColor() } function changeUIFont(type) { var font = $('#layout_font_'+type).val() app_colors[type].font = font if (type === 'main') { $('body').css('font-family', app_colors[type].font) } else { $('h1, h2, h3, h4, h5').css('font-family', app_colors[type].font) } } function updateUIColor() { for (var type in app_colors) { if (app_colors.hasOwnProperty(type)) { if (type === 'css') { $('style#bbstyle').text(app_colors.css) } else if (app_colors[type].hex) { document.body.style.setProperty('--color-'+type, app_colors[type].hex); } else if (app_colors[type].font) { if (type === 'main') { $('body').css('font-family', app_colors[type].font) } else { $('h1, h2, h3, h4, h5').css('font-family', app_colors[type].font) } } } } //var grid_color = '0x'+app_colors.hover.hex.replace('#', '') $('meta[name=theme-color]').attr('content', app_colors.ui.hex) var c_outline = parseInt('0x'+app_colors.accent.hex.replace('#', '')) if (!gizmo_colors.outline || c_outline !== gizmo_colors.outline.getHex()) { gizmo_colors.outline = new THREE.Color( c_outline ) elements.forEach(function(obj) { obj.getMesh().outline.material.color = gizmo_colors.outline }) } var c_grid = parseInt('0x'+app_colors.grid.hex.replace('#', '')) if (!gizmo_colors.grid || c_grid !== gizmo_colors.grid.getHex()) { gizmo_colors.grid = new THREE.Color( c_grid ) try { three_grid.getObjectByName('grid').material.color = gizmo_colors.grid } catch(err) {} } //gizmo_colors.grid = new THREE.Color( parseInt('0x'+app_colors.accent.hex.replace('#', '')) ) localStorage.setItem('app_colors', JSON.stringify(app_colors)) } function importLayout() { Blockbench.import('bbstyle', function(content) { applyBBStyle(content) }) } function applyBBStyle(data) { if (typeof data === 'string') { try { data = JSON.parse(data) } catch(err) { console.log(err) return; } } if (typeof data !== 'object') return; $.extend(app_colors, data) if (data.css) { $('style#bbstyle').text(data.css) setScreenRatio() } updateUIColor() } function exportLayout() { Blockbench.export(autoStringify(app_colors), 'layout', 'bbstyle') } function showQuickMessage(message, time) { var quick_message_box = $('
') $('body').append(quick_message_box) quick_message_box.text(message) quick_message_box.fadeIn(100) setTimeout(function() { quick_message_box.fadeOut(100) setTimeout(function() { quick_message_box.remove() }, 100) }, time ? time : 1000) } function showStatusMessage(message, time) { //Shows a quick message in the status bar var status_message = $('#status_message') var status_name = $('#status_name') status_message.text(message) status_name.hide(100) status_message.show(100) setTimeout(function() { status_message.hide(100) status_name.show(100) }, time ? time : 600) } function setProgressBar(id, val, time) { $('#'+id+' > .progress_bar_inner').animate({width: val*488}, time-1) } //Tooltip function showShiftTooltip() { $(':hover').find('.tooltip_shift').css('display', 'inline') } $(document).keyup(function(event) { if (event.which === 16) { $('.tooltip_shift').hide() } }) function setProjectTitle(title) { if (Blockbench.entity_mode && Project.parent) { title = Project.parent } if (title) { Prop.file_name = title if (Blockbench.entity_mode) { title = title.replace(/^geometry\./,'') } $('title').text(title+' - Blockbench') } else { Prop.file_name = '' $('title').text('Blockbench') } } /* function updateCubeList() { Vue.nextTick(function() { $('.cube_context').on('click', function(event) { var ul = $(this).find('ul') var pos = $(window).height() - event.clientY if (pos < 110) { ul.css('top', '-120px'); } else { ul.css('top', '24px'); } }) }) }*/ function setInterfaceMode(mode) { $('.mode_tab').removeClass('open') $('.mode_tab#mode_'+mode+'_tab').addClass('open') setScreenRatio() } //SplashScreen var splashScreen = { attempt: function(res) { //NOW: Internet Available! -- DOM Ready! //Post Model if (!isApp && tryLoadPOSTModel()) { return; } //Show if (res[1] ||//Forced localStorage.getItem('welcomed_version') != appVersion//Updated ) { splashScreen.show() } }, show: function() { if (open_dialog) return; $('#welcome_content').load('https://www.blockbench.net/api/welcome/index.html', function() { $('#welcome_screen #welcome_body').css('max-height', ($(window).height() - 478) + 'px') showDialog('welcome_screen') localStorage.setItem('welcomed_version', appVersion) }) }, p_doc: new Promise(function(resolve, reject) { $(document).ready(function() { resolve(true) }) }), p_force: new Promise(function(resolve, reject) { $.getJSON('https://blockbench.net/api/index.json', function (data) { resolve(data.forceSplashScreen) }) }) } Promise.all([splashScreen.p_doc, splashScreen.p_force]).then(splashScreen.attempt) //Mobile function setMobileTab(mode) { $('.mobile_mode_tab').removeClass('open') $('#mobile_tab_'+mode).addClass('open') // $('.sidebar').css('grid-area', '') $('#preview').css('grid-area', '') $('header').css('grid-area', '') switch (mode) { case 'preview': $('#preview').css('grid-area', 'main') break; case 'textures': $('#left_bar').css('grid-area', 'main') break; case 'elements': $('#right_bar').css('grid-area', 'main') break; case 'menu': $('header').css('grid-area', 'main') break; } setScreenRatio() }