/* TINY STAR VIEWER */ /* MOTION SENSOR Ver 2.3 */ /* TYPE:DISPELL CURSED */ /* Author:K-ARAI */ /* created on 2026.03.10 */ /* revised on 2026.04.03 */ /* Version 2.3.1 */ /* WITH MIT-LICENSE , */ /* USE FREE !!! */ /* I WELCOME YOUR REPORT */ /* PRIVATE TEST */ /* QUALIFIED : */ /* SHARP AQUOS wish */ /* SHARP AQUOS wish 5 */ /* APPLE iPad 6th-Gen */ /* ( iPad OS 17.7.10 ) */ /* APPLE iPhone SE */ /* ( iOS 18.5 ) */ /* CONDITION */ var motion_init = false; var motion_ios = false; /* ORIENTATION VAR */ var mobile_alpha = 0; var mobile_beta = 0; var mobile_gamma = 0; /* DETECTED DIRECTION */ var center_vh = 0; var center_vd = 0; var tilt_b = 0; var tilt_g = 0; /* ACTIVATION */ function MotionActivate() { if(window.DeviceOrientationEvent != undefined ) { // iOS 13 if(window.DeviceOrientationEvent.requestPermission != undefined ) { window.DeviceOrientationEvent.requestPermission().then( (permission) => { if(permission === "granted" ) { window.addEventListener("deviceorientation",handle_orientation); motion_init = true; motion_ios = true; } }); } else { window.addEventListener("deviceorientationabsolute",handle_orientation); motion_init = true; } } } /* VECTOR CHECKER */ let initial_skip = 5; let screen_angle = null; let alpha_sign = null; let last_alpha = null; let alpha_cnt = 0; let beta_sign = null; let last_beta = null; let beta_cnt = 0; let gamma_sign = null; let last_gamma = null; let gamma_cnt = 0; /* MANUAL RESET */ function reset_sensor() { alpha_sign = null; last_alpha = null; alpha_cnt = 0; beta_sign = null; last_beta = null; beta_cnt = 0; gamma_sign = null; last_gamma = null; gamma_cnt = 0; } /* HANDLE MOTION */ function handle_orientation(event) { let a = event.alpha; let b = event.beta; let g = event.gamma; // Evil spirits, begone! if (a == null || b == null || g == null) return; if (isNaN(a) || isNaN(b) || isNaN(g)) return; if (a === 0 && b === 0 && g === 0) return; // 機種ごとの座標系を学習判定 // alpha の回転方向を判定 if (last_alpha !== null && alpha_sign === null) { let diff = a - last_alpha; // 1周跨ぎに気を付けろ! if (Math.abs(diff) > 1 && Math.abs(diff) < 17) { if(++alpha_cnt > initial_skip) { alpha_sign = (diff > 0) ? +1 : -1; } } } last_alpha = a; // beta の符号を端末ごとに自動判定 if (last_beta !== null && beta_sign === null) { let diff = b - last_beta; if (Math.abs(diff) > 1) { if(++beta_cnt > initial_skip) { beta_sign = (diff > 0) ? +1 : -1; } } } last_beta = b; // gamma の符号も端末ごとに自動判定 ← NEW!! if (last_gamma !== null && gamma_sign === null) { let diff = g - last_gamma; if (Math.abs(diff) > 1) { if(++gamma_cnt > initial_skip) { gamma_sign = (diff > 0) ? +1 : -1; } } } last_gamma = g; // 座標軸を揃える mobile_alpha = (alpha_sign || 1) * a; mobile_beta = (beta_sign || 1) * b; mobile_gamma = (gamma_sign || 1) * g; tilt_b = mobile_beta; tilt_g = mobile_gamma; // 端末の持ち方:画面の向き let screenAngle = (screen.orientation && screen.orientation.angle) || window.orientation || 0; const ua = navigator.userAgent || ""; const platform = navigator.platform || ""; const maxTouch = navigator.maxTouchPoints || 0; const isiOS = /iPhone|iPod/.test(ua) || // iPhone / iPod (/iPad/.test(ua)) || // 古い iPad (platform === "MacIntel" && maxTouch > 1); // iPadOS(Mac と名乗る iPad) const isiPad = navigator.userAgent.includes("iPad") || (navigator.platform === "MacIntel" && navigator.maxTouchPoints > 1); if(isiOS) { // 嘘ついてるぞ!気を付けろ! screenAngle = window.orientation; if(screenAngle < 0) screenAngle += 360; } if(screenAngle != screen_angle) { screen_angle = screenAngle; reset_sensor(); } // show_screenangle(); let beta = mobile_beta; let gamma = mobile_gamma; // 入れ替わるよ! switch (screenAngle) { case 0: beta = mobile_beta; gamma = mobile_gamma; break; case 90: beta = -mobile_gamma; gamma = -mobile_beta; break; case 180: beta = -mobile_beta; gamma = -mobile_gamma; break; case 270: beta = mobile_gamma; gamma = mobile_beta; break; default: beta = mobile_beta; gamma = mobile_gamma; break; } let alpha_fixed = mobile_alpha; let compass_dir = undefined; if (isiOS && typeof event.webkitCompassHeading === "number") { // iOS 専用:方位 compass_dir = event.webkitCompassHeading; } // 最終的な上下角 center_vh = beta; // 最終的な方位:東が0度で右回り if(compass_dir != undefined) { center_vd = compass_dir + screenAngle - 180; } else { center_vd = 270 - alpha_fixed + screenAngle - 90; } // SAFETY if(center_vd<-180) center_vd += 360; if(center_vd>+180) center_vd -= 360; return; }