2017-10-27 01:00:52 +08:00
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
2018-03-29 02:48:11 +08:00
Prop . active _panel = 'dialog'
2017-10-27 01:00:52 +08:00
//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 ;
2018-03-29 02:48:11 +08:00
Prop . active _panel = undefined
2017-10-27 01:00:52 +08:00
}
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 ) {
2018-03-29 02:48:11 +08:00
elements . forEach ( function ( obj , i ) {
if ( obj . display . isselected ) {
obj . name = name . split ( '%' ) . join ( obj . index ( ) ) . split ( '$' ) . join ( i )
}
2017-10-27 01:00:52 +08:00
} )
}
2018-03-29 02:48:11 +08:00
function setActivePanel ( panel ) {
Prop . active _panel = panel
}
2017-11-17 05:23:41 +08:00
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' ,
2018-01-03 03:34:44 +08:00
'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).'
2017-11-17 05:23:41 +08:00
]
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 ( )
}
} )
}
2017-10-27 01:00:52 +08:00
2018-03-29 02:48:11 +08:00
2017-10-27 01:00:52 +08:00
//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 )
}
}
}
}
2018-04-28 06:11:32 +08:00
//var grid_color = '0x'+app_colors.hover.hex.replace('#', '')
2018-01-03 03:34:44 +08:00
$ ( 'meta[name=theme-color]' ) . attr ( 'content' , app _colors . ui . hex )
2017-10-27 01:00:52 +08:00
2018-04-28 06:11:32 +08:00
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('#', '')) )
2017-10-27 01:00:52 +08:00
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 = $ ( '<div id="quick_message_box" class="hidden"></div>' )
$ ( '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 ( )
}
} )
2018-03-29 02:48:11 +08:00
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' )
}
}
2017-10-27 01:00:52 +08:00
/ *
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 ( )
}
2018-01-03 03:34:44 +08:00
//SplashScreen
var splashScreen = {
attempt : function ( res ) {
//Post Model
if ( ! isApp && tryLoadPOSTModel ( ) ) {
return ;
}
//Show
2018-05-07 19:17:52 +08:00
if ( localStorage . getItem ( 'welcomed_version' ) != appVersion ) {
2018-01-03 03:34:44 +08:00
splashScreen . show ( )
2018-05-07 19:17:52 +08:00
} else {
$ . getJSON ( 'https://blockbench.net/api/index.json' , function ( data ) {
if ( data . forceSplashScreen ) {
splashScreen . show ( )
}
} )
2018-01-03 03:34:44 +08:00
}
} ,
show : function ( ) {
2018-04-28 06:11:32 +08:00
if ( open _dialog ) return ;
2018-05-07 19:17:52 +08:00
$ ( '#welcome_content' ) . load ( 'https://www.blockbench.net/api/welcome/index.html' , function ( a , err ) {
if ( err === 'error' ) return ;
2018-01-03 03:34:44 +08:00
$ ( '#welcome_screen #welcome_body' ) . css ( 'max-height' , ( $ ( window ) . height ( ) - 478 ) + 'px' )
showDialog ( 'welcome_screen' )
localStorage . setItem ( 'welcomed_version' , appVersion )
} )
2018-05-07 19:17:52 +08:00
}
2018-01-03 03:34:44 +08:00
}
2017-10-27 01:00:52 +08:00
//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 ( )
}