Merge branch 'main' into storefront-nuxt
This commit is contained in:
commit
951dc10107
2 changed files with 124 additions and 26 deletions
|
|
@ -1,5 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<!--suppress JSSuspiciousNameCombination, JSUnresolvedReference -->
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8"/>
|
||||
|
|
@ -16,14 +15,26 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-family: 'Source Code Pro', monospace;
|
||||
background: #2a2a3a;
|
||||
color: #fff;
|
||||
font-family: 'Source Code Pro', 'Courier New', Courier, monospace;
|
||||
}
|
||||
|
||||
canvas {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/* Dark theme (default) */
|
||||
body {
|
||||
background: #2a2a3a;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* Light theme */
|
||||
@media (prefers-color-scheme: light) {
|
||||
body {
|
||||
background: #f5f5f7;
|
||||
color: #1d1d1f;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
|
@ -31,11 +42,62 @@
|
|||
<script>
|
||||
(function () {
|
||||
let scene, camera, renderer;
|
||||
let particleSystem, textGroup, fontLoader;
|
||||
let particleSystem, textGroup, fontLoader, loadedFont;
|
||||
const clock = new THREE.Clock();
|
||||
let targetRotX = 0, targetRotY = 0;
|
||||
let currentRotX = 0, currentRotY = 0;
|
||||
let isMobile = 'ontouchstart' in window;
|
||||
let isDarkTheme = !window.matchMedia('(prefers-color-scheme: light)').matches;
|
||||
|
||||
const translations = {
|
||||
'ar-ar': {title: 'سنعود قريباً', subtitle: 'جارٍ التحديث. يرجى التحقق مرة أخرى لاحقاً.'},
|
||||
'cs-cz': {title: 'Brzy se vrátíme', subtitle: 'Probíhá aktualizace. Zkuste to prosím později.'},
|
||||
'da-dk': {title: 'Vi er snart tilbage', subtitle: 'En opdatering er i gang. Prøv igen senere.'},
|
||||
'de-de': {title: 'Wir sind bald zurück', subtitle: 'Ein Update wird durchgeführt. Bitte später erneut versuchen.'},
|
||||
'en-gb': {title: 'We\'ll Be Back Soon', subtitle: 'An update is in progress. Please check back later.'},
|
||||
'en-us': {title: 'We\'ll Be Back Soon', subtitle: 'An update is in progress. Please check back later.'},
|
||||
'es-es': {title: 'Volveremos pronto', subtitle: 'Actualización en curso. Por favor, vuelva más tarde.'},
|
||||
'fa-ir': {title: 'به زودی برمیگردیم', subtitle: 'بهروزرسانی در حال انجام است. لطفاً بعداً بررسی کنید.'},
|
||||
'fr-fr': {title: 'Nous revenons bientôt', subtitle: 'Une mise à jour est en cours. Revenez plus tard.'},
|
||||
'he-il': {title: 'נחזור בקרוב', subtitle: 'עדכון מתבצע. אנא בדוק שוב מאוחר יותר.'},
|
||||
'hi-in': {title: 'हम जल्द वापस आएंगे', subtitle: 'एक अपडेट प्रगति पर है। कृपया बाद में जांचें।'},
|
||||
'hr-hr': {title: 'Uskoro se vraćamo', subtitle: 'Ažuriranje je u tijeku. Molimo provjerite kasnije.'},
|
||||
'id-id': {title: 'Kami akan segera kembali', subtitle: 'Pembaruan sedang berlangsung. Silakan periksa lagi nanti.'},
|
||||
'it-it': {title: 'Torneremo presto', subtitle: 'È in corso un aggiornamento. Si prega di tornare più tardi.'},
|
||||
'ja-jp': {title: 'すぐに戻ります', subtitle: 'アップデート中です。後でもう一度お試しください。'},
|
||||
'kk-kz': {title: 'Біз жақында қайтамыз', subtitle: 'Жаңарту жүріп жатыр. Кейінірек тексеріңіз.'},
|
||||
'ko-kr': {title: '곧 돌아오겠습니다', subtitle: '업데이트가 진행 중입니다. 나중에 다시 확인해주세요.'},
|
||||
'nl-nl': {title: 'We zijn zo terug', subtitle: 'Er wordt een update uitgevoerd. Kom later terug.'},
|
||||
'no-no': {title: 'Vi er snart tilbake', subtitle: 'En oppdatering pågår. Vennligst sjekk igjen senere.'},
|
||||
'pl-pl': {title: 'Wrócimy wkrótce', subtitle: 'Trwa aktualizacja. Sprawdź ponownie później.'},
|
||||
'pt-br': {title: 'Voltaremos em breve', subtitle: 'Uma atualização está em andamento. Volte mais tarde.'},
|
||||
'ro-ro': {title: 'Revenim în curând', subtitle: 'O actualizare este în curs. Vă rugăm să reveniți mai târziu.'},
|
||||
'ru-ru': {title: 'Скоро вернёмся', subtitle: 'Идёт обновление. Пожалуйста, проверьте позже.'},
|
||||
'sv-se': {title: 'Vi är snart tillbaka', subtitle: 'En uppdatering pågår. Kontrollera igen senare.'},
|
||||
'th-th': {title: 'เราจะกลับมาเร็วๆ นี้', subtitle: 'กำลังอัปเดต โปรดตรวจสอบอีกครั้งในภายหลัง'},
|
||||
'tr-tr': {title: 'Yakında geri döneceğiz', subtitle: 'Güncelleme devam ediyor. Lütfen daha sonra tekrar kontrol edin.'},
|
||||
'vi-vn': {title: 'Chúng tôi sẽ sớm trở lại', subtitle: 'Đang cập nhật. Vui lòng quay lại sau.'},
|
||||
'zh-hans': {title: '我们很快就会回来', subtitle: '正在更新中。请稍后再查看。'}
|
||||
};
|
||||
|
||||
function detectUserLanguage() {
|
||||
const browserLang = (navigator.language || navigator.userLanguage || 'en-gb').toLowerCase();
|
||||
|
||||
if (translations[browserLang]) {
|
||||
return browserLang;
|
||||
}
|
||||
|
||||
const langCode = browserLang.split('-')[0];
|
||||
for (let key in translations) {
|
||||
if (key.startsWith(langCode)) {
|
||||
return key;
|
||||
}
|
||||
}
|
||||
|
||||
return 'en-gb';
|
||||
}
|
||||
|
||||
const userLanguage = detectUserLanguage();
|
||||
|
||||
function init() {
|
||||
scene = new THREE.Scene();
|
||||
|
|
@ -50,8 +112,9 @@
|
|||
createParticleField();
|
||||
|
||||
fontLoader = new THREE.FontLoader();
|
||||
fontLoader.load('https://api.evibes.com/static/Source%20Code%20Pro%20ExtraLight_Regular.json', f => {
|
||||
create3DText(f);
|
||||
fontLoader.load('/static/Source%20Code%20Pro%20ExtraLight_Regular.json', f => {
|
||||
loadedFont = f;
|
||||
create3DText();
|
||||
fitCameraToText();
|
||||
});
|
||||
|
||||
|
|
@ -71,8 +134,15 @@
|
|||
c.height = 2;
|
||||
const ctx = c.getContext('2d');
|
||||
const gradient = ctx.createLinearGradient(0, 0, 0, 2);
|
||||
|
||||
if (isDarkTheme) {
|
||||
gradient.addColorStop(0, '#1E1E2A');
|
||||
gradient.addColorStop(1, '#4C4C6A');
|
||||
} else {
|
||||
gradient.addColorStop(0, '#E8E8ED');
|
||||
gradient.addColorStop(1, '#F5F5F7');
|
||||
}
|
||||
|
||||
ctx.fillStyle = gradient;
|
||||
ctx.fillRect(0, 0, 2, 2);
|
||||
const texture = new THREE.Texture(c);
|
||||
|
|
@ -85,8 +155,15 @@
|
|||
const geometry = new THREE.BufferGeometry();
|
||||
const positions = new Float32Array(particleCount * 3);
|
||||
const colors = new Float32Array(particleCount * 3);
|
||||
const colorStart = new THREE.Color(0x34000d);
|
||||
const colorEnd = new THREE.Color(0x02066F);
|
||||
|
||||
let colorStart, colorEnd;
|
||||
if (isDarkTheme) {
|
||||
colorStart = new THREE.Color(0x34000d);
|
||||
colorEnd = new THREE.Color(0x02066F);
|
||||
} else {
|
||||
colorStart = new THREE.Color(0x7FB3D5);
|
||||
colorEnd = new THREE.Color(0xC9ADA7);
|
||||
}
|
||||
|
||||
for (let i = 0; i < particleCount; i++) {
|
||||
positions[i * 3] = (Math.random() - 0.5) * 400;
|
||||
|
|
@ -105,7 +182,7 @@
|
|||
size: 0.7,
|
||||
vertexColors: true,
|
||||
transparent: true,
|
||||
opacity: 0.7,
|
||||
opacity: isDarkTheme ? 0.7 : 0.5,
|
||||
blending: THREE.AdditiveBlending
|
||||
});
|
||||
|
||||
|
|
@ -113,11 +190,23 @@
|
|||
scene.add(particleSystem);
|
||||
}
|
||||
|
||||
function create3DText(font) {
|
||||
textGroup = new THREE.Group();
|
||||
function create3DText() {
|
||||
if (textGroup) {
|
||||
scene.remove(textGroup);
|
||||
textGroup.traverse(obj => {
|
||||
if (obj.geometry) obj.geometry.dispose();
|
||||
if (obj.material) obj.material.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
const text1 = new THREE.TextGeometry("We’ll Be Back Soon", {
|
||||
font,
|
||||
textGroup = new THREE.Group();
|
||||
const currentLang = translations[userLanguage];
|
||||
|
||||
const textColor = isDarkTheme ? 0xffffff : 0x1d1d1f;
|
||||
const emissiveColor = isDarkTheme ? 0x111111 : 0x555555;
|
||||
|
||||
const text1 = new THREE.TextGeometry(currentLang.title, {
|
||||
font: loadedFont,
|
||||
size: 5,
|
||||
height: 1,
|
||||
curveSegments: 12,
|
||||
|
|
@ -126,20 +215,20 @@
|
|||
bevelSize: 0.1,
|
||||
bevelSegments: 5
|
||||
});
|
||||
const material1 = new THREE.MeshPhongMaterial({color: 0xffffff, emissive: 0x111111});
|
||||
const material1 = new THREE.MeshPhongMaterial({color: textColor, emissive: emissiveColor});
|
||||
const mesh1 = new THREE.Mesh(text1, material1);
|
||||
mesh1.geometry.center();
|
||||
mesh1.position.y = 5;
|
||||
textGroup.add(mesh1);
|
||||
|
||||
const text2 = new THREE.TextGeometry("An update is in progress. Please check back later.", {
|
||||
font,
|
||||
const text2 = new THREE.TextGeometry(currentLang.subtitle, {
|
||||
font: loadedFont,
|
||||
size: 2,
|
||||
height: 0.5,
|
||||
curveSegments: 12,
|
||||
bevelEnabled: false
|
||||
});
|
||||
const material2 = new THREE.MeshPhongMaterial({color: 0xffffff, emissive: 0x111111});
|
||||
const material2 = new THREE.MeshPhongMaterial({color: textColor, emissive: emissiveColor});
|
||||
const mesh2 = new THREE.Mesh(text2, material2);
|
||||
mesh2.geometry.center();
|
||||
mesh2.position.y = -5;
|
||||
|
|
@ -147,13 +236,19 @@
|
|||
|
||||
scene.add(textGroup);
|
||||
|
||||
const ambientLight = new THREE.AmbientLight(0x404040, 2);
|
||||
if (!scene.getObjectByName('ambientLight')) {
|
||||
const ambientLight = new THREE.AmbientLight(isDarkTheme ? 0x404040 : 0x808080, 2);
|
||||
ambientLight.name = 'ambientLight';
|
||||
scene.add(ambientLight);
|
||||
}
|
||||
|
||||
const spotLight = new THREE.SpotLight(0xffffff, 1);
|
||||
if (!scene.getObjectByName('spotLight')) {
|
||||
const spotLight = new THREE.SpotLight(isDarkTheme ? 0xffffff : 0xf0f0f0, 1);
|
||||
spotLight.position.set(100, 100, 100);
|
||||
spotLight.name = 'spotLight';
|
||||
scene.add(spotLight);
|
||||
}
|
||||
}
|
||||
|
||||
function fitCameraToText() {
|
||||
if (!textGroup) return;
|
||||
|
|
|
|||
|
|
@ -97,5 +97,8 @@ urlpatterns = [
|
|||
"admin/doc/",
|
||||
include("django.contrib.admindocs.urls"),
|
||||
),
|
||||
*i18n_patterns(path("admin/", admin.site.urls)),
|
||||
path(
|
||||
"admin/",
|
||||
admin.site.urls,
|
||||
),
|
||||
]
|
||||
|
|
|
|||
Loading…
Reference in a new issue