acesesibiliti
This commit is contained in:
431
src/systems/DyslexiaSupportSystem.js
Normal file
431
src/systems/DyslexiaSupportSystem.js
Normal file
@@ -0,0 +1,431 @@
|
||||
/**
|
||||
* DYSLEXIA SUPPORT SYSTEM
|
||||
* Provides reading assistance for players with dyslexia
|
||||
*/
|
||||
class DyslexiaSupportSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.enabled = true;
|
||||
|
||||
// OpenDyslexic font (loaded via CSS)
|
||||
this.fonts = {
|
||||
'default': 'Arial, sans-serif',
|
||||
'opendyslexic': 'OpenDyslexic, Arial, sans-serif',
|
||||
'comic-sans': 'Comic Sans MS, cursive',
|
||||
'verdana': 'Verdana, sans-serif'
|
||||
};
|
||||
|
||||
// Text size presets
|
||||
this.textSizes = {
|
||||
'small': { base: 14, ui: 16, subtitle: 18 },
|
||||
'medium': { base: 16, ui: 18, subtitle: 20 },
|
||||
'large': { base: 20, ui: 22, subtitle: 24 },
|
||||
'extra-large': { base: 24, ui: 26, subtitle: 28 }
|
||||
};
|
||||
|
||||
// Line spacing presets
|
||||
this.lineSpacings = {
|
||||
'normal': 1.2,
|
||||
'increased': 1.5,
|
||||
'double': 2.0,
|
||||
'triple': 3.0
|
||||
};
|
||||
|
||||
// Settings
|
||||
this.settings = {
|
||||
enabled: false,
|
||||
font: 'default',
|
||||
textSize: 'medium',
|
||||
lineSpacing: 'normal',
|
||||
highlightText: false,
|
||||
simplifiedLanguage: false,
|
||||
textToSpeech: false,
|
||||
colorOverlay: false,
|
||||
overlayColor: '#ffffcc', // Light yellow
|
||||
overlayOpacity: 0.3
|
||||
};
|
||||
|
||||
// Text simplification dictionary
|
||||
this.simplificationDict = {
|
||||
'acquire': 'get',
|
||||
'utilize': 'use',
|
||||
'commence': 'start',
|
||||
'terminate': 'end',
|
||||
'construct': 'build',
|
||||
'eliminate': 'remove',
|
||||
'approximately': 'about',
|
||||
'insufficient': 'not enough',
|
||||
'maximum': 'most',
|
||||
'minimum': 'least',
|
||||
'purchase': 'buy',
|
||||
'require': 'need',
|
||||
'additional': 'more',
|
||||
'previous': 'last',
|
||||
'subsequent': 'next'
|
||||
};
|
||||
|
||||
this.loadSettings();
|
||||
this.init();
|
||||
|
||||
console.log('✅ Dyslexia Support System initialized');
|
||||
}
|
||||
|
||||
init() {
|
||||
// Load OpenDyslexic font
|
||||
this.loadOpenDyslexicFont();
|
||||
|
||||
// Apply saved settings
|
||||
if (this.settings.enabled) {
|
||||
this.applySettings();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load OpenDyslexic font
|
||||
*/
|
||||
loadOpenDyslexicFont() {
|
||||
// Check if font is already loaded
|
||||
if (document.getElementById('opendyslexic-font')) return;
|
||||
|
||||
// Create style element
|
||||
const style = document.createElement('style');
|
||||
style.id = 'opendyslexic-font';
|
||||
style.textContent = `
|
||||
@font-face {
|
||||
font-family: 'OpenDyslexic';
|
||||
src: url('https://cdn.jsdelivr.net/npm/opendyslexic@3.0.1/OpenDyslexic-Regular.woff2') format('woff2'),
|
||||
url('https://cdn.jsdelivr.net/npm/opendyslexic@3.0.1/OpenDyslexic-Regular.woff') format('woff');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
@font-face {
|
||||
font-family: 'OpenDyslexic';
|
||||
src: url('https://cdn.jsdelivr.net/npm/opendyslexic@3.0.1/OpenDyslexic-Bold.woff2') format('woff2'),
|
||||
url('https://cdn.jsdelivr.net/npm/opendyslexic@3.0.1/OpenDyslexic-Bold.woff') format('woff');
|
||||
font-weight: bold;
|
||||
font-style: normal;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
|
||||
console.log('📖 OpenDyslexic font loaded');
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply all settings
|
||||
*/
|
||||
applySettings() {
|
||||
this.applyFont();
|
||||
this.applyTextSize();
|
||||
this.applyLineSpacing();
|
||||
this.applyColorOverlay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply font setting
|
||||
*/
|
||||
applyFont() {
|
||||
const font = this.fonts[this.settings.font];
|
||||
|
||||
// Apply to game canvas
|
||||
const canvas = document.querySelector('canvas');
|
||||
if (canvas) {
|
||||
canvas.style.fontFamily = font;
|
||||
}
|
||||
|
||||
// Apply to all text elements in game
|
||||
this.updateGameTexts();
|
||||
|
||||
console.log(`📖 Font set to: ${this.settings.font}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply text size setting
|
||||
*/
|
||||
applyTextSize() {
|
||||
const sizes = this.textSizes[this.settings.textSize];
|
||||
|
||||
// Update game text sizes
|
||||
this.updateGameTextSizes(sizes);
|
||||
|
||||
console.log(`📏 Text size set to: ${this.settings.textSize}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply line spacing setting
|
||||
*/
|
||||
applyLineSpacing() {
|
||||
const spacing = this.lineSpacings[this.settings.lineSpacing];
|
||||
|
||||
// Apply to game texts
|
||||
this.updateGameLineSpacing(spacing);
|
||||
|
||||
console.log(`📐 Line spacing set to: ${this.settings.lineSpacing} (${spacing})`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply color overlay
|
||||
*/
|
||||
applyColorOverlay() {
|
||||
if (!this.settings.colorOverlay) {
|
||||
this.removeColorOverlay();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create or update overlay
|
||||
let overlay = document.getElementById('dyslexia-overlay');
|
||||
if (!overlay) {
|
||||
overlay = document.createElement('div');
|
||||
overlay.id = 'dyslexia-overlay';
|
||||
overlay.style.position = 'fixed';
|
||||
overlay.style.top = '0';
|
||||
overlay.style.left = '0';
|
||||
overlay.style.width = '100%';
|
||||
overlay.style.height = '100%';
|
||||
overlay.style.pointerEvents = 'none';
|
||||
overlay.style.zIndex = '9998';
|
||||
document.body.appendChild(overlay);
|
||||
}
|
||||
|
||||
overlay.style.backgroundColor = this.settings.overlayColor;
|
||||
overlay.style.opacity = this.settings.overlayOpacity;
|
||||
|
||||
console.log('🎨 Color overlay applied');
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove color overlay
|
||||
*/
|
||||
removeColorOverlay() {
|
||||
const overlay = document.getElementById('dyslexia-overlay');
|
||||
if (overlay) {
|
||||
overlay.remove();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update game texts with new font
|
||||
*/
|
||||
updateGameTexts() {
|
||||
// This would update all Phaser text objects
|
||||
// Implementation depends on game structure
|
||||
console.log('🔄 Updating game texts...');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update game text sizes
|
||||
*/
|
||||
updateGameTextSizes(sizes) {
|
||||
// Update subtitle system if available
|
||||
if (this.scene.visualSoundCues) {
|
||||
// Map to subtitle sizes
|
||||
const sizeMap = {
|
||||
'small': 'small',
|
||||
'medium': 'medium',
|
||||
'large': 'large',
|
||||
'extra-large': 'very-large'
|
||||
};
|
||||
this.scene.visualSoundCues.setSubtitleSize(sizeMap[this.settings.textSize]);
|
||||
}
|
||||
|
||||
console.log('🔄 Updating game text sizes...');
|
||||
}
|
||||
|
||||
/**
|
||||
* Update game line spacing
|
||||
*/
|
||||
updateGameLineSpacing(spacing) {
|
||||
// This would update line spacing for all text objects
|
||||
console.log(`🔄 Updating line spacing to ${spacing}...`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplify text for easier reading
|
||||
*/
|
||||
simplifyText(text) {
|
||||
if (!this.settings.simplifiedLanguage) return text;
|
||||
|
||||
let simplified = text;
|
||||
for (const [complex, simple] of Object.entries(this.simplificationDict)) {
|
||||
const regex = new RegExp(`\\b${complex}\\b`, 'gi');
|
||||
simplified = simplified.replace(regex, simple);
|
||||
}
|
||||
|
||||
return simplified;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read text aloud (if TTS enabled)
|
||||
*/
|
||||
readAloud(text) {
|
||||
if (!this.settings.textToSpeech) return;
|
||||
|
||||
// Use screen reader system if available
|
||||
if (this.scene.screenReader) {
|
||||
this.scene.screenReader.speak(text);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set font
|
||||
*/
|
||||
setFont(fontName) {
|
||||
if (!this.fonts[fontName]) {
|
||||
console.error(`Font "${fontName}" not available`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.font = fontName;
|
||||
this.applyFont();
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set text size
|
||||
*/
|
||||
setTextSize(size) {
|
||||
if (!this.textSizes[size]) {
|
||||
console.error(`Text size "${size}" not available`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.textSize = size;
|
||||
this.applyTextSize();
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set line spacing
|
||||
*/
|
||||
setLineSpacing(spacing) {
|
||||
if (!this.lineSpacings[spacing]) {
|
||||
console.error(`Line spacing "${spacing}" not available`);
|
||||
return;
|
||||
}
|
||||
|
||||
this.settings.lineSpacing = spacing;
|
||||
this.applyLineSpacing();
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle simplified language
|
||||
*/
|
||||
toggleSimplifiedLanguage() {
|
||||
this.settings.simplifiedLanguage = !this.settings.simplifiedLanguage;
|
||||
this.saveSettings();
|
||||
console.log(`📝 Simplified language: ${this.settings.simplifiedLanguage ? 'ON' : 'OFF'}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle text-to-speech
|
||||
*/
|
||||
toggleTextToSpeech() {
|
||||
this.settings.textToSpeech = !this.settings.textToSpeech;
|
||||
this.saveSettings();
|
||||
console.log(`🔊 Text-to-speech: ${this.settings.textToSpeech ? 'ON' : 'OFF'}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle color overlay
|
||||
*/
|
||||
toggleColorOverlay() {
|
||||
this.settings.colorOverlay = !this.settings.colorOverlay;
|
||||
this.applyColorOverlay();
|
||||
this.saveSettings();
|
||||
console.log(`🎨 Color overlay: ${this.settings.colorOverlay ? 'ON' : 'OFF'}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overlay color
|
||||
*/
|
||||
setOverlayColor(color) {
|
||||
this.settings.overlayColor = color;
|
||||
if (this.settings.colorOverlay) {
|
||||
this.applyColorOverlay();
|
||||
}
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set overlay opacity
|
||||
*/
|
||||
setOverlayOpacity(opacity) {
|
||||
this.settings.overlayOpacity = Phaser.Math.Clamp(opacity, 0, 1);
|
||||
if (this.settings.colorOverlay) {
|
||||
this.applyColorOverlay();
|
||||
}
|
||||
this.saveSettings();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable dyslexia support
|
||||
*/
|
||||
enable() {
|
||||
this.settings.enabled = true;
|
||||
this.applySettings();
|
||||
this.saveSettings();
|
||||
console.log('✅ Dyslexia support enabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable dyslexia support
|
||||
*/
|
||||
disable() {
|
||||
this.settings.enabled = false;
|
||||
this.removeColorOverlay();
|
||||
this.saveSettings();
|
||||
console.log('❌ Dyslexia support disabled');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available fonts
|
||||
*/
|
||||
getAvailableFonts() {
|
||||
return Object.keys(this.fonts);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available text sizes
|
||||
*/
|
||||
getAvailableTextSizes() {
|
||||
return Object.keys(this.textSizes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get available line spacings
|
||||
*/
|
||||
getAvailableLineSpacings() {
|
||||
return Object.keys(this.lineSpacings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save settings to localStorage
|
||||
*/
|
||||
saveSettings() {
|
||||
localStorage.setItem('novafarma_dyslexia_support', JSON.stringify(this.settings));
|
||||
}
|
||||
|
||||
/**
|
||||
* Load settings from localStorage
|
||||
*/
|
||||
loadSettings() {
|
||||
const saved = localStorage.getItem('novafarma_dyslexia_support');
|
||||
if (saved) {
|
||||
try {
|
||||
this.settings = { ...this.settings, ...JSON.parse(saved) };
|
||||
console.log('✅ Dyslexia support settings loaded');
|
||||
} catch (error) {
|
||||
console.error('❌ Failed to load dyslexia support settings:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destroy system
|
||||
*/
|
||||
destroy() {
|
||||
this.removeColorOverlay();
|
||||
console.log('📖 Dyslexia Support System destroyed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user