1์ฐจ ์๋
ํ๋ฉด๋ง๋ค ์ธ๋ก๋ก ๊ณ ์ ๋๋ ๊ฐ๋ก๋ก ๊ณ ์ ์ด ๋์ผ ํ๋ค๋ ์๊ตฌ์ฌํญ์ ๋ฐ๊ณ iOS์์ ๊ฑฐ์ ์ฝ๋ ํ ์ค๋ง ์ถ๊ฐํ๋ฉด ๋๊ธฐ ๋๋ฌธ์ ๊ธ๋ฐฉ ๋๋ ๊ฑฐ๋ผ๊ณ ์๊ฐํ๋ค.
๋ฐ๋ก ๊ตฌ๊ธ๋ง ํ๋๊น MDN Web APIs ๋ฌธ์์ ScreenOrientation.lock()์ด๋ผ๋ ๋ฉ์๋๊ฐ ๊ฒ์๋์๋ค.
https://developer.mozilla.org/en-US/docs/Web/API/ScreenOrientation/lock
์ API๋ ์๋์ ๊ฐ์ด window์ screen์ ๋ฐฉํฅ์ ์ํ๋ ํ์ portrait(์ธ๋ก) or landscape(๊ฐ๋ก)๋ฅผ ์ค์ ํ ์ ์์๋ค.
(์ด๊ฒ๋ค ์ธ์๋ natural,portrait-primary ๋ฑ ๋ง์ lock type์ด ์กด์ฌํ๋ค.)
window.screen.orientation.lock('portrait').then(
(success) => alert('success!'),
(fail) => alert(`fail... ${fail}`)
);
์ฐ์ ์น ๋ธ๋ผ์ฐ์ ์์ ์คํ์์ผ ๋ณด๋ฉด ์๋์ ๊ฐ์ ์ด์ ๋ก lock์ด ์คํจํ๋ค.
๋ฌธ์๋ฅผ ์ฝ์ด๋ณด๋ฉด ํ๋ฉด lock์ ๋ชจ๋ฐ์ผ ๋๋ฐ์ด์ค์์๋ง ๊ฐ๋ฅํ๋ค๊ณ ๋ช ์๋์ด ์๋ค.
๊ทธ๋ ๋ค๋ฉด ๋ชจ๋ฐ์ผ๋ก ์คํ์ํค๋ฉด ์ ์๋๋๊ฒ ๊ตฌ๋... ํ๊ณ ์คํ์์ผ ๋ณด๋.. ์ฑ๊ณต๋ ์คํจ๋ ํ์ง ์์๋ค.
window.screen.orientation์ ์ถ๋ ฅํด๋ณด๋ undefined๋ก ๋์ lock ๋ฉ์๋๊ฐ ์์ ์คํ์ด ์๋๋ ๊ฒ์ด์๋ค.
์๋ ๊ณต์ ๋ฌธ์์ ๋์์๋๋๋ก ํ๋๋ฐ ์ ์๋๋๊ฑฐ์ง.. ๋ผ๋ ์๊ฐ์ผ๋ก ๋ฉ์๋๋ฅผ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ์์ผ๋ก ์ ์ฉํด ๋ณด์๋๋ฐ ๊ฒฐ๊ตญ ์๋๋ค.
๋ชจ๋ฐ์ผ ๋ธ๋ผ์ฐ์ ์์ ํ ๋ฒ๋ ๊ฐ๋ก๋ชจ๋๊ฐ ๊ฐ์ ๋ก ์ ์ฉ๋๋ ๊ฒฝ์ฐ๋ฅผ ๋ณธ ์ ์ด ์์ด์ ์ด๊ฒ ๊ฐ๋ฅํ ๊ธฐ๋ฅ์ธ์ง ์์ฌ๊น์ง ๋ค์๋ค..
ํด๊ฒฐ๋ฐฉ๋ฒ
๋ชจ๋ฐ์ผ ๋ธ๋ผ์ฐ์ ์์ ํ๋ฉด์ ๊ณ ์ ์ํค๋ ํต์ฌ์ ๋ฐ๋ก "ํ์คํฌ๋ฆฐ" ์ด์๋ค.
ํด๋น ๋๋ ๋ธ๋ผ์ฐ์ ๋ฅผ ํ์คํฌ๋ฆฐ์ผ๋ก ๋ง๋ ๋ค์ ์ ๋ฉ์๋๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
์๋์ ๊ฐ์ด ํด๋น ๋๋ ๋ธ๋ผ์ฐ์ ๋ง๋ค ํ์คํฌ๋ฆฐ์ ์์ฒญํ๋ ๋ฉ์๋๋ฅผ ์คํํ๊ณ ๊ทธ ๋ค์์ผ๋ก screen.orientation.lock ์ ์คํ์์ผ์ผ lock์ด ์๋๋์๋ค.
openFullscreen(type: OrientationLockType) {
if (this.elem.documentElement.requestFullscreen) {
this.elem.documentElement.requestFullscreen();
} else if (this.elem.documentElement.mozRequestFullScreen) {
/* Firefox */
this.elem.documentElementmozRequestFullScreen();
} else if (this.elem.documentElement.webkitRequestFullscreen) {
/* Chrome, Safari and Opera */
this.elem.webkitRequestFullscreen();
} else if (this.elem.documentElement.msRequestFullscreen) {
/* IE/Edge */
this.elem.documentElement.msRequestFullscreen();
}
screen.orientation.lock(type);
}
ํ์คํฌ๋ฆฐ์ ๋๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ์ด ์์ฑํด์ฃผ๋ฉด ๋๋ค.
closeFullscreen() {
if (this.document.exitFullscreen) {
this.document.exitFullscreen();
} else if (this.document.mozCancelFullScreen) {
/* Firefox */
this.document.mozCancelFullScreen();
} else if (this.document.webkitExitFullscreen) {
/* Chrome, Safari and Opera */
this.document.webkitExitFullscreen();
} else if (this.document.msExitFullscreen) {
/* IE/Edge */
this.document.msExitFullscreen();
}
}
์์์ ํ์คํฌ๋ฆฐ์ ์ ๊ณตํ๋ ๋ธ๋ผ์ฐ์ ์ธ์๋ ํ๋ฉด์ ๊ณ ์ ํด์ผ ํ๋๋ฐ
1. Safari
๋จผ์ ์ฌํ๋ฆฌ๋ ์์ ๊ฐ์ ์ฝ๋๋ฅผ ์ ๋ ฅํด๋ ํ์คํฌ๋ฆฐ์ด ์๋๋์ง ์์ ํ๋ฉด ๊ณ ์ ์ ํ ์๊ฐ ์์๋ค.
๊ตฌ๊ธ๋ง ํด ์ฐพ์๋ณด๋ ์ฌํ๋ฆฌ๋ ํ์คํฌ๋ฆฐ๋ ์๋๊ณ screen.orientation.lock ๋ฉ์๋๋ฅผ ์ง์ํ์ง ์๋๋ค๊ณ ํ๋ค.
์ฐ์ ์๋ ์ฝ๋๋ก ์ด๋ค ๋ธ๋ผ์ฐ์ ์ธ์ง ์์๋ธ ๋ค์ ์ฌํ๋ฆฌ๋ผ๋ฉด ์ถ๊ฐ์ ์ธ ์ฝ๋๋ฅผ ์์ฑํด ์ค์ผ ํ๋ค.
๋ธ๋ผ์ฐ์ ์์๋ด๊ธฐ
detectBrowswerName():string {
let userAgent = navigator.userAgent;
let browserName;
if (userAgent.match(/chrome|chromium|crios/i)) {
browserName = 'chrome';
} else if (userAgent.match(/firefox|fxios/i)) {
browserName = 'firefox';
} else if (userAgent.match(/safari/i)) {
browserName = 'safari';
} else if (userAgent.match(/opr\//i)) {
browserName = 'opera';
} else if (userAgent.match(/edg/i)) {
browserName = 'edge';
} else {
browserName = 'No browser detection';
}
alert(`${browserName}`)
return browserName
}
ํ์ฌ ๋๋ฐ์ด์ค ๋ฐฉํฅ ์์๋ด๊ธฐ
window์ addEventListner๋ฅผ ๊ฑธ์ด ํ๋ฉด ๋ฐฉํฅ์ด ๋ฐ๋๋ ๊ฒ์ ๊ฐ์งํ๊ณ
detectChangeOrientation() {
window.addEventListener(
'resize',() => this.readDeviceOrientation(),
false
);
}
ํด๋น ๋๋ฐ์ด์ค ๋ฐฉํฅ์ ์ฝ์ด๋ธ๋ค.
readDeviceOrientation() {
if (Math.abs(window.orientation) === 90 || Math.abs(window.orientation) === 270 ) {
this.orientation = "Landscape"
} else {
this.orientation = "Portrait"
}
}
CSS
๊ทธ ๋ค์ CSS์ ํ๋ฉด์ ํ์ ํ๋ ์ฝ๋๋ฅผ ์์ฑํด ์ํฉ์ ๋ง๊ฒ ํ๋ฉด์ ๋๋ ค์ฃผ์๋ค.
@media only screen and (orientation: portrait) {
body.portrait {
height: 100vw;
transform: rotate(90deg);
}
body.landscape {
height: 100vw;
transform: rotate(0deg);
}
}
html ์ ์ฒด๋ฅผ body๋ก ๊ฐ์ผ ๋ค์ ์๋์ ๊ฐ์ด ์์ฑํด ์ฃผ์๋ค.
@ViewChild('body') body: ElementRef | undefined;
constructor(@Inject(DOCUMENT) private document: any) {}
if (matchMedia('only screen and (orientation: portrait)').matches) {
if (type == 'landscape') {
this.body?.nativeElement.classList.remove('landscape');
this.body?.nativeElement.classList.add('portrait');
} else {
this.body?.nativeElement.classList.remove('portrait');
this.body?.nativeElement.classList.add('landscape');
}
}
2. Zebra Enterprise
ํน์ ๊ธฐ์ ์์๋ ์๋ ค์ง ๋ธ๋ผ์ฐ์ ๋ง๊ณ ๋ ์ค์บํ๋ ์๋๋ฅผ ์ํด Zebra Enterprise ๋ธ๋ผ์ฐ์ ๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๊ฐ ์์๋ค.
ํด๋น ๋ธ๋ผ์ฐ์ ๋ ์ด๋ฏธ ํ๋ฉด์ด ๋ฝ์ด ๊ฑธ๋ฆฐ ์ํ๋ก ๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณต๋์ด CSS๋ฅผ ์ด์ฉํด ์ํฉ์ ๋ง๊ฒ ํ๋ฉด์ ํ์ ํด ์ฃผ๋ฉด ๋๋ค.
Reference
'๐ป Frontend > Angular' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Angular] Custom Pipe ๋ง๋ค์ด ์ ์ฉํ๊ธฐ (with. ngStyle) (0) | 2022.06.02 |
---|---|
[Angular] Pipe๋? (feat. Built-in Pipe) (0) | 2022.05.24 |
[Angular] ํ์๊ฐ์ ์ ๋ ฅํ๋ฉด ๋ง๋ค์ด๋ณด๊ธฐ (Register Validation Form) (1) | 2022.03.24 |
[Angular] Router์ ๋ํด ์์๋ณด๊ธฐ (feat. ํ๋ฉด์ด๋) (0) | 2022.03.24 |
[Angular] NgForm์ด๋? (feat. ngModel,ngSubmit,required) (0) | 2022.03.15 |
๋๊ธ