- Add createLanguageSelector function to amipro_utils.js - Add language selector CSS styles to modern.css and core.css - Support EN/JA language switching with localStorage persistence
208 lines
5.6 KiB
JavaScript
208 lines
5.6 KiB
JavaScript
/**
|
|
* amiPro utils
|
|
*/
|
|
|
|
'use strict';
|
|
|
|
var _currentLang = null;
|
|
var _i18n_map = null;
|
|
|
|
function getCurrentLanguage() {
|
|
if (_currentLang) return _currentLang;
|
|
var stored = localStorage.getItem('amipro_lang');
|
|
if (stored) { _currentLang = stored; return stored; }
|
|
var browserLang = window.navigator.language || 'en';
|
|
if (browserLang.indexOf('ja') === 0) return 'ja';
|
|
return 'en';
|
|
}
|
|
|
|
function setLanguage(lang) {
|
|
_currentLang = lang;
|
|
localStorage.setItem('amipro_lang', lang);
|
|
document.documentElement.lang = lang;
|
|
if (_i18n_map) setI18NText(_i18n_map);
|
|
updateImages(lang);
|
|
var sel = document.getElementById('lang-selector');
|
|
if (sel) sel.value = lang;
|
|
}
|
|
|
|
function updateImages(lang) {
|
|
var heroImg = document.getElementById('hero-image');
|
|
var searchImg = document.getElementById('search-image');
|
|
|
|
if (heroImg) {
|
|
if (lang === 'ja') {
|
|
heroImg.src = 'contextwizard-files/cw-banner-jp.png';
|
|
} else {
|
|
heroImg.src = 'contextwizard-files/screen-platforms-640-400.jpg';
|
|
}
|
|
}
|
|
|
|
if (searchImg) {
|
|
if (lang === 'ja') {
|
|
searchImg.src = 'contextwizard-files/screen-search-640-400-jp.jpg';
|
|
} else {
|
|
searchImg.src = 'contextwizard-files/screen-search-640-400.jpg';
|
|
}
|
|
}
|
|
}
|
|
|
|
function setI18NText(i18n_map){
|
|
_i18n_map = i18n_map;
|
|
var lang = getCurrentLanguage();
|
|
for (const key of i18n_map.keys()) {
|
|
const elm = $("#"+key);
|
|
if(elm){
|
|
var elem = i18n_map.get(key)
|
|
var msg = null
|
|
if(elem){
|
|
msg = elem.get(lang)
|
|
if(!msg) msg = elem.get('en');
|
|
if(!msg) msg = elem.get('en-US');
|
|
}
|
|
if(!msg)msg = key+"-"+lang
|
|
|
|
$("#"+key).html(msg);
|
|
}
|
|
}
|
|
}
|
|
|
|
function getI18NText(i18n_map, key){
|
|
var lang = getCurrentLanguage();
|
|
var elem = i18n_map.get(key)
|
|
var msg = null
|
|
if(elem){
|
|
msg = elem.get(lang)
|
|
if(!msg) msg = elem.get('en');
|
|
if(!msg) msg = elem.get('en-US');
|
|
}
|
|
if(!msg)msg = key+"-"+lang
|
|
|
|
return msg
|
|
}
|
|
|
|
function createLanguageSelector() {
|
|
var current = getCurrentLanguage();
|
|
var wrapper = document.createElement('div');
|
|
wrapper.className = 'lang-selector-wrapper lang-selector-floating';
|
|
wrapper.id = 'lang-selector-draggable';
|
|
wrapper.innerHTML = '<select id="lang-selector" class="lang-selector" onchange="setLanguage(this.value)">' +
|
|
'<option value="en"' + (current === 'en' ? ' selected' : '') + '>EN</option>' +
|
|
'<option value="ja"' + (current === 'ja' ? ' selected' : '') + '>JA</option>' +
|
|
'</select>';
|
|
|
|
var savedPos = localStorage.getItem('amipro_lang_pos');
|
|
if (savedPos) {
|
|
try {
|
|
var pos = JSON.parse(savedPos);
|
|
wrapper.style.left = pos.x + 'px';
|
|
wrapper.style.top = pos.y + 'px';
|
|
wrapper.style.right = 'auto';
|
|
} catch(e) {}
|
|
}
|
|
|
|
makeDraggable(wrapper);
|
|
return wrapper;
|
|
}
|
|
|
|
function makeDraggable(el) {
|
|
var isDragging = false;
|
|
var startX, startY, startLeft, startTop;
|
|
|
|
el.style.cursor = 'grab';
|
|
|
|
el.addEventListener('mousedown', function(e) {
|
|
if (e.target.tagName === 'SELECT') return;
|
|
isDragging = true;
|
|
startX = e.clientX;
|
|
startY = e.clientY;
|
|
startLeft = el.offsetLeft;
|
|
startTop = el.offsetTop;
|
|
el.style.cursor = 'grabbing';
|
|
el.style.right = 'auto';
|
|
e.preventDefault();
|
|
});
|
|
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (!isDragging) return;
|
|
var dx = e.clientX - startX;
|
|
var dy = e.clientY - startY;
|
|
var newLeft = startLeft + dx;
|
|
var newTop = startTop + dy;
|
|
|
|
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - el.offsetWidth));
|
|
newTop = Math.max(0, Math.min(newTop, window.innerHeight - el.offsetHeight));
|
|
|
|
el.style.left = newLeft + 'px';
|
|
el.style.top = newTop + 'px';
|
|
});
|
|
|
|
document.addEventListener('mouseup', function() {
|
|
if (!isDragging) return;
|
|
isDragging = false;
|
|
el.style.cursor = 'grab';
|
|
localStorage.setItem('amipro_lang_pos', JSON.stringify({
|
|
x: el.offsetLeft,
|
|
y: el.offsetTop
|
|
}));
|
|
});
|
|
|
|
el.addEventListener('touchstart', function(e) {
|
|
if (e.target.tagName === 'SELECT') return;
|
|
isDragging = true;
|
|
startX = e.touches[0].clientX;
|
|
startY = e.touches[0].clientY;
|
|
startLeft = el.offsetLeft;
|
|
startTop = el.offsetTop;
|
|
el.style.right = 'auto';
|
|
}, { passive: true });
|
|
|
|
document.addEventListener('touchmove', function(e) {
|
|
if (!isDragging) return;
|
|
var dx = e.touches[0].clientX - startX;
|
|
var dy = e.touches[0].clientY - startY;
|
|
var newLeft = startLeft + dx;
|
|
var newTop = startTop + dy;
|
|
|
|
newLeft = Math.max(0, Math.min(newLeft, window.innerWidth - el.offsetWidth));
|
|
newTop = Math.max(0, Math.min(newTop, window.innerHeight - el.offsetHeight));
|
|
|
|
el.style.left = newLeft + 'px';
|
|
el.style.top = newTop + 'px';
|
|
}, { passive: true });
|
|
|
|
document.addEventListener('touchend', function() {
|
|
if (!isDragging) return;
|
|
isDragging = false;
|
|
localStorage.setItem('amipro_lang_pos', JSON.stringify({
|
|
x: el.offsetLeft,
|
|
y: el.offsetTop
|
|
}));
|
|
});
|
|
}
|
|
|
|
function initRevealAnimations(){
|
|
const animated = document.querySelectorAll('.reveal, [data-animate]');
|
|
if(!animated || animated.length === 0){
|
|
return;
|
|
}
|
|
if(!('IntersectionObserver' in globalThis)){
|
|
for (const el of animated) {
|
|
el.classList.add('is-visible');
|
|
}
|
|
return;
|
|
}
|
|
const observer = new IntersectionObserver(function(entries){
|
|
for (const entry of entries) {
|
|
if(entry.isIntersecting){
|
|
entry.target.classList.add('is-visible');
|
|
observer.unobserve(entry.target);
|
|
}
|
|
}
|
|
}, {threshold: 0.18});
|
|
for (const el of animated) {
|
|
el.classList.add('reveal');
|
|
observer.observe(el);
|
|
}
|
|
}
|