Daniel Biegler пре 7 година
committed by GitHub
родитељ
комит
1e4ad0b2f6
7 измењених фајлова са 137 додато и 27 уклоњено
  1. +1
    -0
      src/css/pannellum.css
  2. +14
    -7
      src/js/libpannellum.js
  3. +27
    -19
      src/js/pannellum.js
  4. +92
    -0
      src/js/strings.js
  5. +1
    -0
      src/standalone/pannellum.htm
  6. +1
    -1
      src/standalone/standalone.js
  7. +1
    -0
      utils/build/build.py

+ 1
- 0
src/css/pannellum.css Прегледај датотеку

@@ -268,6 +268,7 @@
.pnlm-load-button p {
display: table-cell;
vertical-align: middle;
padding: 1em;
}

.pnlm-info-box {


+ 14
- 7
src/js/libpannellum.js Прегледај датотеку

@@ -42,6 +42,9 @@ function Renderer(container) {
var pose;
var image, imageType, dynamic;
var texCoordBuffer, cubeVertBuf, cubeVertTexCoordBuf, cubeVertIndBuf;
// based on ISO 639-1: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
// defaults to 'en' => english
var languageCode;

/**
* Initialize renderer.
@@ -59,16 +62,20 @@ function Renderer(container) {
* @param {number} vaov - Initial vertical angle of view.
* @param {number} voffset - Initial vertical offset angle.
* @param {function} callback - Load callback function.
* @param {Object} [params] - Other configuration parameters (`horizonPitch`, `horizonRoll`, `backgroundColor`).
* @param {Object} [params] - Other configuration parameters (`horizonPitch`, `horizonRoll`, `backgroundColor`, `languageCode`).
*/
this.init = function(_image, _imageType, _dynamic, haov, vaov, voffset, callback, params) {
// set language code for localized strings
// defaults to english if not set!
languageCode = params.languageCode ? params.languageCode : 'en';
// Default argument for image type
if (typeof _imageType === undefined)
_imageType = 'equirectangular';

if (_imageType != 'equirectangular' && _imageType != 'cubemap' &&
_imageType != 'multires') {
console.log('Error: invalid image type specified!');
console.log(STRINGS.ERROR_INVALID_IMG_TYPE[languageCode]);
throw {type: 'config error'};
}

@@ -225,7 +232,7 @@ function Renderer(container) {
return;
} else if (!gl) {
console.log('Error: no WebGL support detected!');
console.log(STRINGS.ERROR_NO_WEBGL[languageCode]);
throw {type: 'no webgl'};
}
if (image.basePath) {
@@ -248,14 +255,14 @@ function Renderer(container) {
width = Math.max(image.width, image.height);
maxWidth = gl.getParameter(gl.MAX_TEXTURE_SIZE);
if (width > maxWidth) {
console.log('Error: The image is too big; it\'s ' + width + 'px wide, but this device\'s maximum supported width is ' + maxWidth + 'px.');
console.log(STRINGS.ERROR_IMG_TOO_BIG[languageCode] + " " + STRINGS.TEXT_IMG_SUPPORTED_WIDTH[languageCode] + maxWidth + "px.");
throw {type: 'webgl size error', width: width, maxWidth: maxWidth};
}
} else if (imageType == 'cubemap') {
width = image[0].width;
maxWidth = gl.getParameter(gl.MAX_CUBE_MAP_TEXTURE_SIZE);
if (width > maxWidth) {
console.log('Error: The cube face image is too big; it\'s ' + width + 'px wide, but this device\'s maximum supported width is ' + maxWidth + 'px.');
console.log(STRINGS.ERROR_CUBE_FACE_TOO_BIG[languageCode] + " " + STRINGS.TEXT_IMG_SUPPORTED_WIDTH[languageCode] + maxWidth + "px.");
throw {type: 'webgl size error', width: width, maxWidth: maxWidth};
}
}
@@ -408,7 +415,7 @@ function Renderer(container) {
// Check if there was an error
var err = gl.getError();
if (err !== 0) {
console.log('Error: Something went wrong with WebGL!', err);
console.log(STRINGS.ERROR_WEBGL[languageCode], err);
throw {type: 'webgl error'};
}

@@ -1186,7 +1193,7 @@ function Renderer(container) {
* @private
*/
function handleWebGLError1286() {
console.log('Reducing canvas size due to error 1286!');
console.log(STRINGS.ERROR_WEBGL_1286[languageCode]);
canvas.width = Math.round(canvas.width / 2);
canvas.height = Math.round(canvas.height / 2);
}


+ 27
- 19
src/js/pannellum.js Прегледај датотеку

@@ -36,6 +36,16 @@ function Viewer(container, initialConfig) {

var _this = this;

/**
* make sure that language is set so strings can be translated properly
* WARNING: Make sure you use a supported `languageCode`, otherwise you will see 'undefined' strings!
*/
if(!initialConfig.languageCode) {
console.log("WARNING: 'languageCode' was not (properly) set in the config. Defaults to English('en') now.\
If you are the author, check your config.languageCode!");
initialConfig.languageCode = 'en';
}

// Declare variables
var config,
renderer,
@@ -100,7 +110,7 @@ var defaultConfig = {
hotSpotDebug: false,
backgroundColor: [0, 0, 0],
animationTimingFunction: timingFunction,
loadButtonLabel: 'Click to\nLoad\nPanorama',
loadButtonLabel: STRINGS.TEXT_CLICK_TO_LOAD[initialConfig.languageCode],
draggable: true,
};

@@ -276,7 +286,7 @@ function init() {
origPitch = config.pitch;

var i, p;
if (config.type == 'cubemap') {
panoImage = [];
for (i = 0; i < 6; i++) {
@@ -303,7 +313,7 @@ function init() {
panoImage = config.panorama;
} else {
if (config.panorama === undefined) {
anError('No panorama image was specified.');
anError(STRINGS.ERROR_NO_PANORAMA[config.languageCode]);
return;
}
panoImage = new Image();
@@ -326,7 +336,7 @@ function init() {
var a = document.createElement('a');
a.href = e.target.src;
a.innerHTML = a.href;
anError('The file ' + a.outerHTML + ' could not be accessed.');
anError(STRINGS.ERROR_FILE_ACCESS[config.languageCode] + " " + a.outerHTML);
};
for (i = 0; i < panoImage.length; i++) {
@@ -362,7 +372,7 @@ function init() {
var a = document.createElement('a');
a.href = encodeURI(p);
a.innerHTML = a.href;
anError('The file ' + a.outerHTML + ' could not be accessed.');
anError(STRINGS.ERROR_FILE_ACCESS[config.languageCode] + " " + a.outerHTML);
}
var img = this.response;
parseGPanoXMP(img);
@@ -398,7 +408,7 @@ function init() {
xhr.open('GET', p, true);
} catch (e) {
// Malformed URL
anError('There is something wrong with the panorama URL.');
anError(STRINGS.ERROR_PANORAMA_URL[config.languageCode]);
}
xhr.responseType = 'blob';
xhr.setRequestHeader('Accept', 'image/*,*/*;q=0.9');
@@ -485,9 +495,7 @@ function parseGPanoXMP(image) {
if (navigator.userAgent.toLowerCase().match(/(iphone|ipod|ipad).* os 8_/)) {
var flagIndex = img.indexOf('\xff\xc2');
if (flagIndex < 0 || flagIndex > 65536) {
anError("Due to iOS 8's broken WebGL implementation, only " +
"progressive encoded JPEGs work for your device (this " +
"panorama uses standard encoding).");
anError(STRINGS.ERROR_IOS8_WEBGL[config.languageCode]);
}
}

@@ -569,7 +577,7 @@ function parseGPanoXMP(image) {
*/
function anError(errorMsg) {
if (errorMsg === undefined)
errorMsg = 'Your browser does not have the necessary WebGL support to display this panorama.';
errorMsg = STRINGS.ERROR_WEBGL[config.languageCode];
infoDisplay.errorMsg.innerHTML = '<p>' + errorMsg + '</p>';
controls.load.style.display = 'none';
infoDisplay.load.box.style.display = 'none';
@@ -647,6 +655,7 @@ function onDocumentMouseDown(event) {
// Log pitch / yaw of mouse click when debugging / placing hot spots
if (config.hotSpotDebug) {
var coords = mouseEventToCoords(event);
// Dont translate this because the config fields are in english!
console.log('Pitch: ' + coords[0] + ', Yaw: ' + coords[1] + ', Center Pitch: ' +
config.pitch + ', Center Yaw: ' + config.yaw + ', HFOV: ' + config.hfov);
}
@@ -1526,6 +1535,8 @@ function renderInit() {
params.horizonRoll = config.horizonRoll * Math.PI / 180;
if (config.backgroundColor !== undefined)
params.backgroundColor = config.backgroundColor;
if (config.languageCode !== undefined)
params.languageCode = config.languageCode;
renderer.init(panoImage, config.type, config.dynamic, config.haov * Math.PI / 180, config.vaov * Math.PI / 180, config.vOffset * Math.PI / 180, renderInitCallback, params);
if (config.dynamic !== true) {
// Allow image to be garbage collected
@@ -1538,12 +1549,9 @@ function renderInit() {
if (event.type == 'webgl error' || event.type == 'no webgl') {
anError();
} else if (event.type == 'webgl size error') {
anError('This panorama is too big for your device! It\'s ' +
event.width + 'px wide, but your device only supports images up to ' +
event.maxWidth + 'px wide. Try another device.' +
' (If you\'re the author, try scaling down the image.)');
anError(STRINGS.ERROR_IMG_TOO_BIG[config.languageCode] + " " + STRINGS.TEXT_IMG_SUPPORTED_WIDTH[config.languageCode] + event.maxWidth + "px.")
} else {
anError('Unknown error. Check developer console.');
anError(STRINGS.ERROR_UNKNOWN[config.languageCode]);
throw event;
}
}
@@ -1872,12 +1880,12 @@ function processOptions(isPreview) {
break;
case 'author':
infoDisplay.author.innerHTML = 'by ' + escapeHTML(config[key]);
infoDisplay.author.innerHTML = STRINGS.TEXT_BY[config.languageCode] + ' ' + escapeHTML(config[key]);
infoDisplay.container.style.display = 'inline';
break;
case 'fallback':
infoDisplay.errorMsg.innerHTML = '<p>Your browser does not support WebGL.<br><a href="' + encodeURI(config[key]) + '" target="_blank">Click here to view this panorama in an alternative viewer.</a></p>';
infoDisplay.errorMsg.innerHTML = '<p>' + STRINGS.ERROR_NO_WEBGL[config.languageCode] + '<br><a href="' + encodeURI(config[key]) + '" target="_blank">' + STRINGS.TEXT_ALTERNATIVE_VIEWER[config.languageCode] + '</a></p>';
break;
case 'hfov':
@@ -2050,7 +2058,7 @@ function constrainHfov(hfov) {
}
if (minHfov > config.maxHfov) {
// Don't change view if bounds don't make sense
console.log('HFOV bounds do not make sense (minHfov > maxHfov).')
console.log(STRINGS.ERROR_HFOV_BOUNDS[config.languageCode]);
return config.hfov;
} if (hfov < minHfov) {
return minHfov;
@@ -2673,7 +2681,7 @@ this.addHotSpot = function(hs, sceneId) {
}
initialConfig.scenes[id].hotSpots.push(hs); // Add hot spot to config
} else {
throw 'Invalid scene ID!'
throw STRINGS.ERROR_INVALID_SCENE_ID[config.languageCode];
}
}
if (sceneId === undefined || config.scene == sceneId) {


+ 92
- 0
src/js/strings.js Прегледај датотеку

@@ -0,0 +1,92 @@
var STRINGS = {
"ERROR_INVALID_IMG_TYPE": {
"de": "Error: Falscher Bild-Typ angegeben!",
"en": "Error: invalid image type specified!",
"ru": "Ошибка: неправильный тип изображения!"
},
"ERROR_IMG_TOO_BIG": {
"de": "Error: Das Bild ist zu groß. Ihr Gerät unterstützt dies nicht.",
"en": "Error: The image is too big; Your device does not support it.",
"ru": "Ошибка: Разрешение этого изображения слишком велико. Ваш прибор это не поддерживает."
},
"ERROR_CUBE_FACE_TOO_BIG": {
"de": "Error: Das Cube Face ist zu groß. Ihr gerät unterstützt dies nicht.",
"en": "Error: The cube face is too big; Your device does not support it.",
"ru": "Ошибка: Изображение верхней стороны кубика слишком велико. Ваш прибор это не поддерживает."
},
"ERROR_NO_WEBGL": {
"de": "Error: WebGL wird nicht unterstützt!",
"en": "Error: no WebGL support detected!",
"ru": "Ошибка: WebGL не поддерживается!"
},
"ERROR_WEBGL": {
"de": "Error: Ein WebGL Fehler ist aufgetreten!",
"en": "Error: Something went wrong with WebGL!",
"ru": "Ошибка: WebGL Ошибка!"
},
"ERROR_WEBGL_1286": {
"de": "Error: Verkleinere Canvas wegen Error 1286!",
"en": "Error: Reducing canvas size due to error 1286!",
"ru": "Ошибка: Из за ошибки 1286 уменьшаю изображение на экране."
},
"ERROR_NO_PANORAMA": {
"de": "Error: Es wurde kein Panorama angegeben.",
"en": "Error: No panorama image was specified.",
"ru": "Ошибка: Панорама не найдена."
},
"ERROR_FILE_ACCESS": {
"de": "Error: Datei konnte nicht geöffnet werden.",
"en": "Error: File could not be accessed.",
"ru": "Ошибка: Файл не открывается."
},
"ERROR_PANORAMA_URL": {
"de": "Error: Da stimmt etwas nicht mit der Panorama URL.",
"en": "Error: There is something wrong with the panorama URL.",
"ru": "Ошибка: URL Панорамы повреждён."
},
"ERROR_IOS8_WEBGL": {
"de": "Error: Wegen der fehlerhaften WebGL Implementierung von iOS8, funktionieren nur progressiv enkodierte JPEGs auf ihrem Gerät (dieses Panorama benutzt standard Enkodierung).",
"en": "Error: Due to iOS 8's broken WebGL implementation, only progressive encoded JPEGs work for your device (this panorama uses standard encoding).",
"ru": "Ошибка: Из за ошибочной WebGL реализации в iOS8, на вашем приборе работают только прогрессивно кодированные JPEGs. (Для этой Панорамы используется стандартная кодировка.)"
},
"ERROR_UNKNOWN": {
"de": "Error: Ein unbekannter Fehler ist aufgetreten. Schauen Sie in die Entwicklerkonsole.",
"en": "Error: An unknown error occured. Check developer console.",
"ru": "Ошибка: Произошла неизвестная ошибка. Обратитесь в консоль разработчика."
},
"ERROR_HFOV_BOUNDS": {
"de": "Error: HFOV Grenzen machen keinen Sinn (minHfov > maxHfov).",
"en": "Error: HFOV bounds do not make sense (minHfov > maxHfov).",
"ru": "Ошибка: HFOV границы не имеют смысла(minHfov > maxHfov)."
},
"ERROR_INVALID_SCENE_ID": {
"de": "Error: Falsche scene ID!",
"en": "Error: Invalid scene ID!",
"ru": "Ошибка: неправильный идентификатор сцены!"
},
"TEXT_IMG_SUPPORTED_WIDTH": {
"de": "Die maximal unterstützte Breite für ihr Gerät ist: ",
"en": "This device's maximum supported width is: ",
"ru": "Максимально поддерживаемая ширина изображения для вашего прибора: "
},
"TEXT_IMG_TOO_BIG_ADVICE": {
"de": "(Falls Sie der Author sind, versuchen Sie das Bild herunterzuskalieren.)",
"en": "(If you're the author, try scaling down the image.)",
"ru": "(Если Вы являетесь автором, попробуйте уменьшить разрешение изображения.)"
},
"TEXT_CLICK_TO_LOAD": {
"de": "Klicke um\nPanorama\nzu laden",
"en": "Click to\nLoad\nPanorama",
"ru": "нажмите здесь чтобы\nзагрузить\nпанораму"
},
"TEXT_ALTERNATIVE_VIEWER": {
"de": "Klicken Sie hier um das Panorama über einen alternativen Weg anzuschauen.",
"en": "Click here to view this panorama in an alternative viewer.",
"ru": "Нажмите здесь, чтобы увидеть Панораму по другому."
},
"TEXT_BY": {
"de": "von",
"en": "by",
"ru": "от"
}
}

+ 1
- 0
src/standalone/pannellum.htm Прегледај датотеку

@@ -15,6 +15,7 @@
</div>
</noscript>
</div>
<script type="text/javascript" src="../js/strings.js"></script>
<script type="text/javascript" src="../js/libpannellum.js"></script>
<script type="text/javascript" src="../js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="../js/pannellum.js"></script>


+ 1
- 1
src/standalone/standalone.js Прегледај датотеку

@@ -37,7 +37,7 @@ function parseURLParameters() {
configFromURL[option] = JSON.parse(value);
break;
case 'author': case 'title': case 'firstScene': case 'fallback':
case 'preview': case 'panorama': case 'config':
case 'preview': case 'panorama': case 'config': case 'languageCode':
configFromURL[option] = decodeURIComponent(value);
break;
default:


+ 1
- 0
utils/build/build.py Прегледај датотеку

@@ -7,6 +7,7 @@ import subprocess
import urllib.parse

JS = [
'js/strings.js',
'js/libpannellum.js',
'js/RequestAnimationFrame.js',
'js/pannellum.js',


Loading…
Откажи
Сачувај