diff --git a/cypress/e2e/astral-accessibility.cy.ts b/cypress/e2e/astral-accessibility.cy.ts
index b9ff0ac..cbb1e76 100644
--- a/cypress/e2e/astral-accessibility.cy.ts
+++ b/cypress/e2e/astral-accessibility.cy.ts
@@ -190,5 +190,20 @@ describe('template spec', () => {
cy.wrap(elmt).should('have.css', 'font-size', `${initialSize}px`);
}
});
+
+ const screenMaskComponent = cy.document().find('astral-screen-mask');
+ // cursor size check
+ cy.document().find('style').should('not.contain', "cursor: url('data:image/png;base64,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'), auto;");
+ screenMaskComponent.click();
+ cy.document().find('style').should('contain', "cursor: url('data:image/png;base64,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'), auto;");
+
+ // screen mask check
+
+ cy.document().find('.mask-top').should('not.exist')
+ screenMaskComponent.click();
+ cy.document().find('.mask-top').should('exist')
+ cy.reload()
+ cy.document().find('.mask-top').should('not.exist')
+
});
});
diff --git a/projects/astral-accessibility/src/lib/astral-accessibility.component.html b/projects/astral-accessibility/src/lib/astral-accessibility.component.html
index 3874397..a3ba16f 100644
--- a/projects/astral-accessibility/src/lib/astral-accessibility.component.html
+++ b/projects/astral-accessibility/src/lib/astral-accessibility.component.html
@@ -45,6 +45,12 @@
+
+
diff --git a/projects/astral-accessibility/src/lib/astral-accessibility.component.scss b/projects/astral-accessibility/src/lib/astral-accessibility.component.scss
index 55b78c4..27656bc 100644
--- a/projects/astral-accessibility/src/lib/astral-accessibility.component.scss
+++ b/projects/astral-accessibility/src/lib/astral-accessibility.component.scss
@@ -282,4 +282,4 @@
word-spacing: 0.48em;
letter-spacing: 0.36em;
}
-}
+}
\ No newline at end of file
diff --git a/projects/astral-accessibility/src/lib/astral-accessibility.component.ts b/projects/astral-accessibility/src/lib/astral-accessibility.component.ts
index c9f50c4..1d32608 100644
--- a/projects/astral-accessibility/src/lib/astral-accessibility.component.ts
+++ b/projects/astral-accessibility/src/lib/astral-accessibility.component.ts
@@ -6,6 +6,8 @@ import { SaturateComponent } from './controls/saturate.component';
import { TextSizeComponent } from './controls/text-size.component';
import { TextSpacingComponent } from './controls/text-spacing.component';
import { ScreenReaderComponent } from './controls/screen-reader.component';
+import { ScreenMaskComponent } from './controls/screen-mask.component';
+import { LineHeightComponent } from './controls/line-height.component';
@Component({
selector: 'astral-accessibility',
@@ -20,6 +22,8 @@ import { ScreenReaderComponent } from './controls/screen-reader.component';
TextSizeComponent,
TextSpacingComponent,
ScreenReaderComponent,
+ ScreenMaskComponent,
+ LineHeightComponent
],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
diff --git a/projects/astral-accessibility/src/lib/controls/line-height.component.ts b/projects/astral-accessibility/src/lib/controls/line-height.component.ts
new file mode 100644
index 0000000..a486ff6
--- /dev/null
+++ b/projects/astral-accessibility/src/lib/controls/line-height.component.ts
@@ -0,0 +1,140 @@
+import { DOCUMENT, NgIf, NgClass } from '@angular/common';
+import { Component, Renderer2, inject } from '@angular/core';
+import { AstralCheckmarkSvgComponent } from '../util/astral-checksvg.component';
+
+@Component({
+ selector: 'astral-line-height',
+ standalone: true,
+ template: `
+
+
+
+
+
+
+
{{ states[currentState] }}
+
+
+
+
+
+
+
+ `,
+ imports: [NgIf, NgClass, AstralCheckmarkSvgComponent],
+})
+export class LineHeightComponent {
+ constructor(private renderer: Renderer2) {}
+ document = inject(DOCUMENT);
+
+ currentState = 0;
+ base = 'Line Height';
+ states = [this.base, 'Light Height', 'Moderate Height', 'Heavy Height'];
+
+ lowHeight = `
+ *{
+ line-height: 1.5 !important;
+ }`;
+
+ moderateHeight = `
+ *{
+ line-height: 3 !important;
+ }`;
+
+ heavyHeight = `
+ *{
+ line-height: 4 !important;
+ }`;
+
+ private lowHeightStyleTag: HTMLStyleElement | null = null;
+ private moderateHeightStyleTag: HTMLStyleElement | null = null;
+ private heavyHeightStyleTag: HTMLStyleElement | null = null;
+
+ _style: HTMLStyleElement;
+
+ nextState() {
+ this.currentState += 1;
+ this.currentState = this.currentState % 4;
+
+ this._runStateLogic();
+ }
+
+ private _runStateLogic() {
+ this._style?.remove?.();
+ this._style = this.document.createElement('style');
+
+ if (this.states[this.currentState] === 'Light Height') {
+ if (!this.lowHeightStyleTag) {
+ this.lowHeightStyleTag = this.renderer.createElement('style');
+ this.renderer.appendChild(this.lowHeightStyleTag, this.renderer.createText(this.lowHeight));
+ this.renderer.appendChild(this.document.head, this.lowHeightStyleTag);
+ }
+ } else {
+ if (this.lowHeightStyleTag) {
+ this.renderer.removeChild(this.document.head, this.lowHeightStyleTag);
+ this.lowHeightStyleTag = null;
+ }
+ }
+
+ if (this.states[this.currentState] === 'Moderate Height') {
+ if (!this.moderateHeightStyleTag) {
+ this.moderateHeightStyleTag = this.renderer.createElement('style');
+ this.renderer.appendChild(this.moderateHeightStyleTag, this.renderer.createText(this.moderateHeight));
+ this.renderer.appendChild(this.document.head, this.moderateHeightStyleTag);
+ }
+ } else {
+ if (this.moderateHeightStyleTag) {
+ this.renderer.removeChild(this.document.head, this.moderateHeightStyleTag);
+ this.moderateHeightStyleTag = null;
+ }
+ }
+
+ if (this.states[this.currentState] === 'Heavy Height') {
+ if (!this.heavyHeightStyleTag) {
+ this.heavyHeightStyleTag = this.renderer.createElement('style');
+ this.renderer.appendChild(this.heavyHeightStyleTag, this.renderer.createText(this.heavyHeight));
+ this.renderer.appendChild(this.document.head, this.heavyHeightStyleTag);
+ }
+ } else {
+ if (this.heavyHeightStyleTag) {
+ this.renderer.removeChild(this.document.head, this.heavyHeightStyleTag);
+ this.heavyHeightStyleTag = null;
+ }
+ }
+
+ this.document.body.appendChild(this._style);
+ }
+}
diff --git a/projects/astral-accessibility/src/lib/controls/screen-mask.component.ts b/projects/astral-accessibility/src/lib/controls/screen-mask.component.ts
new file mode 100644
index 0000000..65a50c2
--- /dev/null
+++ b/projects/astral-accessibility/src/lib/controls/screen-mask.component.ts
@@ -0,0 +1,229 @@
+import { DOCUMENT, NgIf, NgClass } from '@angular/common';
+import { Component, Renderer2, inject } from '@angular/core';
+import { AstralCheckmarkSvgComponent } from '../util/astral-checksvg.component';
+
+@Component({
+ selector: 'astral-screen-mask',
+ standalone: true,
+ template: `
+
+
+
+
+
+
+
{{ states[currentState] }}
+
+
+
+
+
+
+
+
+
+ `,
+ imports: [NgIf, NgClass, AstralCheckmarkSvgComponent],
+})
+export class ScreenMaskComponent {
+ constructor(private renderer: Renderer2) {}
+
+ cursorY = 0;
+ screenHeight: number = window.innerHeight;
+ height = this.screenHeight - this.cursorY;
+ listenersActive: boolean = false;
+
+ screenMaskContainerStyle = `
+ .screen-mask-container {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 9999;
+ }
+ `;
+
+ maskTopStyle = `
+ .mask-top {
+ position: absolute;
+ top: 0;
+ width: 100%;
+ background-color: rgba(0, 0, 0, 0.55);
+ pointer-events: none;
+ border-bottom: 8px solid #654AFF;
+ height: ${this.height - 115}px;
+ }
+ `;
+
+ maskBottomStyle = `
+ .mask-bottom {
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ background-color: rgba(0, 0, 0, 0.55);
+ pointer-events: none;
+ border-top: 8px solid #FFCB00;
+ height: ${this.cursorY}px;
+ }
+ `;
+
+ toggleListeners(active: boolean) {
+ this.listenersActive = active;
+
+ if (this.listenersActive) {
+ this.addEventListeners();
+ this.updateMaskStyles();
+ } else {
+ this.removeEventListeners();
+ }
+ }
+
+ // Method to add the event listeners
+ private addEventListeners() {
+ window.addEventListener('mousemove', this.onMouseMove);
+ window.addEventListener('resize', this.onResize);
+ }
+
+ // Method to remove the event listeners
+ private removeEventListeners() {
+ window.removeEventListener('mousemove', this.onMouseMove);
+ window.removeEventListener('resize', this.onResize);
+ }
+
+ private onMouseMove = (event: MouseEvent) => {
+ if (!this.listenersActive) return; // Don't proceed if listeners are paused
+
+ this.cursorY = event.clientY;
+ this.height = this.screenHeight - this.cursorY;
+ this.updateMaskStyles();
+ }
+
+ // Event listener method for resize
+ private onResize = (event: any) => {
+ if (!this.listenersActive) return; // Don't proceed if listeners are paused
+
+ this.screenHeight = event.target.innerHeight;
+ this.height = this.screenHeight - this.cursorY;
+ this.updateMaskStyles();
+ }
+
+ updateMaskStyles() {
+ const maskTop = document.querySelector('.mask-top');
+ const maskBottom = document.querySelector('.mask-bottom');
+
+ if (maskTop) {
+ this.renderer.setStyle(maskTop, 'height', `${this.cursorY - 57}px`);
+ }
+ if (maskBottom) {
+ this.renderer.setStyle(maskBottom, 'height', `${this.height - 57}px`);
+ }
+ }
+
+ document = inject(DOCUMENT);
+
+ currentState = 0;
+ base = 'Screen Mask';
+ states = [this.base, 'Large Cursor', 'Reading Mask'];
+
+ _style: HTMLStyleElement;
+
+ nextState() {
+ this.currentState += 1;
+ this.currentState = this.currentState % 3;
+
+ this._runStateLogic();
+ }
+
+ private _runStateLogic() {
+ this._style?.remove?.();
+ this._style = this.document.createElement('style');
+
+ if (this.states[this.currentState] === 'Large Cursor') {
+ this._style.textContent = `
+ body, *{
+ cursor: url('data:image/png;base64,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'), auto;
+ }
+ `;
+ }
+
+ if (this.states[this.currentState] === 'Reading Mask') {
+
+ const screenMaskContainer = this.renderer.createElement('div');
+ const maskTop = this.renderer.createElement('div');
+ const maskBottom = this.renderer.createElement('div');
+
+ this.renderer.addClass(screenMaskContainer, 'screen-mask-container');
+ this.renderer.addClass(maskTop, 'mask-top');
+ this.renderer.addClass(maskBottom, 'mask-bottom');
+
+ const maskBottomCss = this.renderer.createElement('style');
+ this.renderer.appendChild(maskBottomCss, this.renderer.createText(this.maskBottomStyle));
+ this.renderer.appendChild(this.document.head, maskBottomCss);
+
+ const maskTopCss = this.renderer.createElement('style');
+ this.renderer.appendChild(maskTopCss, this.renderer.createText(this.maskTopStyle));
+ this.renderer.appendChild(this.document.head, maskTopCss);
+
+ const screenMaskContainerCss = this.renderer.createElement('style');
+ this.renderer.appendChild(screenMaskContainerCss, this.renderer.createText(this.screenMaskContainerStyle));
+ this.renderer.appendChild(this.document.head, screenMaskContainerCss);
+
+ screenMaskContainer.appendChild(maskTop);
+ screenMaskContainer.appendChild(maskBottom);
+ this.document.body.appendChild(screenMaskContainer);
+
+ this.toggleListeners(true);
+
+ } else {
+ const removeMaskContainer = document.querySelector('.screen-mask-container');
+ if (removeMaskContainer) {
+ this.renderer.removeChild(document.body, removeMaskContainer);
+ }
+ this.toggleListeners(false);
+ }
+
+ this.document.body.appendChild(this._style);
+ }
+}
\ No newline at end of file
diff --git a/projects/demo/index.html b/projects/demo/index.html
index 1ad6529..704c267 100644
--- a/projects/demo/index.html
+++ b/projects/demo/index.html
@@ -22,8 +22,49 @@ Welcome to Astral Accessibility!
reading accessibility functionalities like text size, text line
height/spacing, text reader, contrast, invert, saturation. It is
located at the bottom right corner of the application.
-
- Screen Reader
+
+
Screen reader is a tool where it would reads out texts on screen
where user clicks on. For any html elements, if an aria label is
@@ -31,29 +72,240 @@
Screen Reader
otherwise, it reads the text content of the element. There are 3
different speeds, normal, fast and slow.
- Contrast
+
+
Contrast is a tool that removes background and replaces it with
black or white to increase the difference in colours between text
and the background to increase legibility. There are 3 modes, the
invert colours, high contrast, and dark high contrast.
- Saturation
+
+
Saturation is a tool that adjusts how colourful the colours are on
screen, it has 3 different modes to lower saturation, increase
saturation, or remove all the colours on screen (black and white).
- Bigger Text
+
+
Bigger Text is a tool that increases the size of the texts on
screen.
- Text Spacing
+
+
Text Spacing is a tool that increases the spacing between each
character on the screen to increase legibility and readibility.
+
+
+
+ Screen Mask is a tool which dims the background and has a horizontal
+ focus area which follows the cursor sliding horizontally.
+
+
+
+
+ Line height is a tool which increased the line height to increase readibility.
+
Check box demo