ESG 스크롤 복귀와 기술 역량 이미지 정렬·지도 표시 개선
- ESG 푸터에서 위로 스크롤하면 문서 영역이 먼저 복귀하도록 처리 - 섹션 전환 중 문서 내부 스크롤을 막아 상단 잘림 방지 - 기술 역량 이미지의 상단 여백과 가용 높이를 본문 기준으로 정렬 - 이미지 진입 애니메이션을 고려해 텍스트 겹침과 화면 이탈 방지 - 기술 역량 프로젝트 순서·설명 및 개별 이미지 배치 설정 정리 - 기술 역량 데이터에 맞춰 검색용 정적 HTML 동기화 - 지도 검색용 도로명 주소와 층·호수 안내를 분리해 건물 위치 핀 표시 - 지도 기본 확대 수준을 16으로 설정하고 한국어 표시 적용 - 회사 소개·조직도와 개인정보 동의 거부 안내 문구 정리 검증: - JavaScript 구문 검사 및 git diff --check 통과 - ESG 세 문서의 푸터 복귀·내부 스크롤·키보드 이동 확인 - 기술 역량 29개 슬라이드의 데스크톱 이미지 정렬 및 모바일 이동 확인 - 본사·지사 지도 위치 핀, 상세 주소, 외부 지도 링크 확인
This commit is contained in:
@@ -16,7 +16,7 @@ MATLAB Simulink를 활용한 Model 기반 Application Software 설계 및 검증
|
||||
|
||||
ISO 26262 기능 안전 개발 프로세스 기반 업무 (ASIL, FMEA, DFA) 를 수행하였습니다.
|
||||
`,
|
||||
scope: "Safety mechanism · Platform",
|
||||
scope: "Side Body Control Module",
|
||||
output: "SW module · Verification",
|
||||
image: "assets/images/automotive/automotive_01_background.jpeg",
|
||||
objectImage: "assets/images/automotive/automotive_01_object.png",
|
||||
@@ -44,6 +44,27 @@ RTE( Runtime Environment)를 Generate하고 BSW 영역과 연계하여 Applicati
|
||||
output: "Issue report · Tool flow",
|
||||
image: "assets/images/automotive/automotive_02_background.png",
|
||||
objectImage: "assets/images/automotive/automotive_02_object.png",
|
||||
},
|
||||
// P.15
|
||||
{
|
||||
id: "hvac-autosar-bsw-development",
|
||||
type: "automotive",
|
||||
category: "AUTOSAR BSW DEVELOPMENT",
|
||||
title: "차량용 공조제어기 SW 개발",
|
||||
subtitle: "H-VAC Controller Basic Software",
|
||||
description: `차량용 공조제어기의 안정적인 소프트웨어 동작과 차량 전장 시스템과의 원활한 연계를 위해 AUTOSAR 기반의 BSW 및 Middleware를 개발하고, 제어기의 핵심 기능과 진단·보안·업데이트 기능을 통합 구현하였습니다.
|
||||
|
||||
FBL(Flash Boot Loader) 기능을 구현하고 Sleep & Wake-up 사양을 개발하여 차량의 전원 상태 변화에 따른 제어기의 안정적인 동작 환경을 확보하였습니다. BSW Configuration 및 Implementation을 수행하고 Middleware를 구현하였으며, M-CAL Port를 비롯하여 ADC, PWM, ICU, IoHwAb, OS 등 주요 AUTOSAR 모듈을 설정하고 제어기 사양에 맞게 통합하였습니다.
|
||||
|
||||
또한 CAN 요구사항을 반영하여 관련 DB를 Import하고 Generate 및 Harmonize 과정을 수행함으로써 차량 네트워크 환경과 제어기 소프트웨어 간의 통신 연계성을 구현하였습니다.
|
||||
|
||||
보안 기능 강화를 위해 HSM, ASK, SFM 및 Crypto Library를 포팅하고 기능 검증을 수행하여 차량용 제어기에 요구되는 보안 기능을 안정적으로 적용하였습니다. 진단 영역에서는 DiagDCM 및 DEM Configuration을 수행하고 관련 기능을 검증하여 차량 진단 시스템과 제어기 간의 안정적인 진단 환경을 구축하였습니다.
|
||||
|
||||
OTA(Over-The-Air) 기반 Background 및 Reprogramming 기능을 개발하고 검증하여 차량 소프트웨어를 안정적으로 업데이트할 수 있는 환경을 구현하였습니다. Watch-Dog 요구사항을 반영 개발하였습니다.`,
|
||||
scope: "H-VAC Controller Basic Software",
|
||||
output: "Control module · QA",
|
||||
image: "assets/images/automotive/automotive_04_background.jpeg",
|
||||
objectImage: "assets/images/automotive/automotive_04_object.png",
|
||||
},
|
||||
// P.14
|
||||
{
|
||||
@@ -67,27 +88,6 @@ ISO 및 OEM 요구사항을 기반으로 DoCAN 및 DoIP Stack을 개발하여 CA
|
||||
image: "assets/images/automotive/automotive_03_background.png",
|
||||
objectImage: "assets/images/automotive/automotive_03_object.png",
|
||||
},
|
||||
// P.15
|
||||
{
|
||||
id: "hvac-autosar-bsw-development",
|
||||
type: "automotive",
|
||||
category: "AUTOSAR BSW DEVELOPMENT",
|
||||
title: "차량용 공조제어기 SW 개발",
|
||||
subtitle: "H-VAC Controller Basic Software",
|
||||
description: `차량용 공조제어기의 안정적인 소프트웨어 동작과 차량 전장 시스템과의 원활한 연계를 위해 AUTOSAR 기반의 BSW 및 Middleware를 개발하고, 제어기의 핵심 기능과 진단·보안·업데이트 기능을 통합 구현하였습니다.
|
||||
|
||||
FBL(Flash Boot Loader) 기능을 구현하고 Sleep & Wake-up 사양을 개발하여 차량의 전원 상태 변화에 따른 제어기의 안정적인 동작 환경을 확보하였습니다. BSW Configuration 및 Implementation을 수행하고 Middleware를 구현하였으며, M-CAL Port를 비롯하여 ADC, PWM, ICU, IoHwAb, OS 등 주요 AUTOSAR 모듈을 설정하고 제어기 사양에 맞게 통합하였습니다.
|
||||
|
||||
또한 CAN 요구사항을 반영하여 관련 DB를 Import하고 Generate 및 Harmonize 과정을 수행함으로써 차량 네트워크 환경과 제어기 소프트웨어 간의 통신 연계성을 구현하였습니다.
|
||||
|
||||
보안 기능 강화를 위해 HSM, ASK, SFM 및 Crypto Library를 포팅하고 기능 검증을 수행하여 차량용 제어기에 요구되는 보안 기능을 안정적으로 적용하였습니다. 진단 영역에서는 DiagDCM 및 DEM Configuration을 수행하고 관련 기능을 검증하여 차량 진단 시스템과 제어기 간의 안정적인 진단 환경을 구축하였습니다.
|
||||
|
||||
OTA(Over-The-Air) 기반 Background 및 Reprogramming 기능을 개발하고 검증하여 차량 소프트웨어를 안정적으로 업데이트할 수 있는 환경을 구현하였습니다. Watch-Dog 요구사항을 반영 개발하였습니다.`,
|
||||
scope: "H-VAC Controller Basic Software",
|
||||
output: "Control module · QA",
|
||||
image: "assets/images/automotive/automotive_04_background.jpeg",
|
||||
objectImage: "assets/images/automotive/automotive_04_object.png",
|
||||
},
|
||||
// P.16
|
||||
{
|
||||
id: "a-spice-swe5-integration-verification",
|
||||
@@ -427,13 +427,6 @@ GPS 기반의 위치 정보를 활용하여 대중교통의 이동 상황을 실
|
||||
output: "Control room · Alert",
|
||||
image: "assets/images/solution/solution_05_background.png",
|
||||
objectImage: "assets/images/solution/solution_05_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
// P.33
|
||||
{
|
||||
@@ -454,13 +447,6 @@ GPS 기반의 위치 정보를 활용하여 대중교통의 이동 상황을 실
|
||||
output: "Capture flow · Viewer",
|
||||
image: "assets/images/solution/solution_06_background.jpeg",
|
||||
objectImage: "assets/images/solution/solution_06_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
// P.34
|
||||
{
|
||||
@@ -481,13 +467,6 @@ GPS 기반의 위치 정보를 활용하여 대중교통의 이동 상황을 실
|
||||
output: "Pipeline · Dashboard",
|
||||
image: "assets/images/solution/solution_07_background.jpeg",
|
||||
objectImage: "assets/images/solution/solution_07_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
// P.35
|
||||
{
|
||||
@@ -508,13 +487,7 @@ GPS 기반의 위치 정보를 활용하여 대중교통의 이동 상황을 실
|
||||
output: "Recognition module",
|
||||
image: "assets/images/solution/solution_08_background.jpg",
|
||||
objectImage: "assets/images/solution/solution_08_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
|
||||
},
|
||||
// Certifications
|
||||
{
|
||||
@@ -589,13 +562,6 @@ AUTOSAR 표준 기반의 플랫폼 환경에서 ECU 기능에 필요한 모듈
|
||||
output: "Admin · Approval flow",
|
||||
image: "assets/images/si/si_02_background.jpg",
|
||||
objectImage: "assets/images/si/si_02_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
// P.40
|
||||
{
|
||||
@@ -642,13 +608,6 @@ AUTOSAR 표준 기반의 플랫폼 환경에서 ECU 기능에 필요한 모듈
|
||||
output: "iOS/Android · API",
|
||||
image: "assets/images/si/si_04_background.png",
|
||||
objectImage: "assets/images/si/si_04_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
// P.42
|
||||
{
|
||||
@@ -711,13 +670,13 @@ GPS 기반의 자녀 안심존 관리 기능을 통해 지정된 안전 구역
|
||||
output: "Backend · Docs",
|
||||
image: "assets/images/si/si_07_background.png",
|
||||
objectImage: "assets/images/si/si_07_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
// objectLayout: {
|
||||
// x: "50%",
|
||||
// y: "50%",
|
||||
// anchorX: "-50%",
|
||||
// anchorY: "-50%",
|
||||
// maxHeight: "560px",
|
||||
// },
|
||||
},
|
||||
// P.45
|
||||
{
|
||||
@@ -740,12 +699,5 @@ GPS 기반의 자녀 안심존 관리 기능을 통해 지정된 안전 구역
|
||||
output: "Backend · Docs",
|
||||
image: "assets/images/si/si_08_background.png",
|
||||
objectImage: "assets/images/si/si_08_object.png",
|
||||
objectLayout: {
|
||||
x: "50%",
|
||||
y: "50%",
|
||||
anchorX: "-50%",
|
||||
anchorY: "-50%",
|
||||
maxHeight: "560px",
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
37
js/main.js
37
js/main.js
@@ -176,6 +176,10 @@
|
||||
function canScrollPolicy(target, direction) {
|
||||
const panel = target.closest(".esg-policy-panel");
|
||||
if (!panel || panel.hidden) return false;
|
||||
const workspace = panel.closest(".esg-workspace");
|
||||
// Restore the whole reader below the header before scrolling its document.
|
||||
if (workspace && Math.abs(window.scrollY - sectionStop(workspace)) > 4) return false;
|
||||
if (performance.now() < transitionUntil) return false;
|
||||
const remaining = panel.scrollHeight - panel.clientHeight - panel.scrollTop;
|
||||
return direction > 0 ? remaining > 2 : panel.scrollTop > 2;
|
||||
}
|
||||
@@ -238,10 +242,8 @@
|
||||
<p>수집된 개인정보는 문의 처리 완료 후 1년간 보관하며, 보유 기간이 지나면 지체 없이 파기합니다.</p>
|
||||
<h3>4. 정보 제공 및 처리 위탁</h3>
|
||||
<p>제공된 정보는 문의 응대 목적으로 사용합니다. 외부 서비스에 처리를 위탁하는 경우 해당 서비스와 처리 범위를 운영 방침에 명시합니다.</p>
|
||||
<h3>5. 동의 거부 및 정보 확인</h3>
|
||||
<p>개인정보 수집 및 이용에 동의하지 않을 수 있습니다. 동의하지 않으면 온라인 문의를 전송할 수 없으며, 고객센터로 직접 연락할 수 있습니다. 제공한 정보의 확인, 수정, 삭제 요청도 고객센터로 문의할 수 있습니다.</p>
|
||||
<h3>6. 개인정보 관련 문의</h3>
|
||||
<p>주식회사 모비핀테크놀러지 · 고객센터 <a href="tel:0532140592">053-214-0592</a><br />평일 09:00 ~ 18:00</p>`,
|
||||
<h3>5. 동의 거부</h3>
|
||||
<p>개인정보 수집 및 이용에 동의하지 않을 수 있습니다. 다만, 동의하지 않을 경우 온라인 문의 서비스를 이용할 수 없습니다.</p>`,
|
||||
},
|
||||
sitemap: {
|
||||
title: "사이트맵",
|
||||
@@ -350,10 +352,11 @@
|
||||
trigger.addEventListener("click", () => {
|
||||
const office = trigger.dataset.mapTitle;
|
||||
const address = trigger.dataset.mapAddress;
|
||||
const query = encodeURIComponent(address);
|
||||
// Search for the building; floor/unit details can prevent a map pin from resolving.
|
||||
const query = encodeURIComponent(trigger.dataset.mapQuery || address);
|
||||
title.textContent = `${office} 오시는 길`;
|
||||
frame.title = `${office} 위치 지도`;
|
||||
frame.src = `https://maps.google.com/maps?q=${query}&z=15&output=embed`;
|
||||
frame.src = `https://maps.google.com/maps?q=${query}&z=16&hl=ko&output=embed`;
|
||||
addressLabel.textContent = address;
|
||||
mapLink.href = `https://www.google.com/maps/search/?api=1&query=${query}`;
|
||||
dialog.showModal();
|
||||
@@ -752,29 +755,43 @@
|
||||
const titleBottom = featureTitle.getBoundingClientRect().bottom - stageBounds.top;
|
||||
capabilitiesWorkbench.style.setProperty("--certificate-top", `${titleBottom + 24}px`);
|
||||
}
|
||||
const contentRight = featureContent.getBoundingClientRect().right + 32;
|
||||
const contentBounds = featureContent.getBoundingClientRect();
|
||||
const contentRight = contentBounds.right + 32;
|
||||
const contentTop = contentBounds.top;
|
||||
const contentBottom = stageBounds.bottom - parseFloat(window.getComputedStyle(stage).paddingBottom);
|
||||
[featureObject, featureObjectSecondary].forEach((element) => {
|
||||
if (!element) return;
|
||||
element.style.removeProperty("width");
|
||||
element.style.removeProperty("height");
|
||||
element.style.removeProperty("--object-fit-x");
|
||||
element.style.removeProperty("--object-fit-y");
|
||||
if (!desktop || !hasDescription || !element.getAttribute("src")) return;
|
||||
const style = window.getComputedStyle(element);
|
||||
const width = parseFloat(style.width);
|
||||
const height = parseFloat(style.height);
|
||||
const available = Math.max(0, stageBounds.right - contentRight);
|
||||
const availableHeight = Math.max(0, contentBottom - contentTop);
|
||||
if (!width || !height) return;
|
||||
// Fit the actual image ratio, not the potentially letterboxed CSS rectangle.
|
||||
const naturalWidth = element.naturalWidth;
|
||||
const naturalHeight = element.naturalHeight;
|
||||
if (!naturalWidth || !naturalHeight) return;
|
||||
const ratio = Math.min(width / naturalWidth, height / naturalHeight, available / naturalWidth);
|
||||
const ratio = Math.min(width / naturalWidth, height / naturalHeight,
|
||||
available / naturalWidth, availableHeight / naturalHeight);
|
||||
element.style.width = `${naturalWidth * ratio}px`;
|
||||
element.style.height = `${naturalHeight * ratio}px`;
|
||||
const bounds = element.getBoundingClientRect();
|
||||
const motionX = parseFloat(window.getComputedStyle(element).translate) || 0;
|
||||
const settledLeft = bounds.left - motionX;
|
||||
const fittedStyle = window.getComputedStyle(element);
|
||||
const [motionX = 0, motionY = 0] = fittedStyle.translate.split(" ").map(parseFloat);
|
||||
const transform = new DOMMatrixReadOnly(fittedStyle.transform);
|
||||
const [originX, originY] = fittedStyle.transformOrigin.split(" ").map(parseFloat);
|
||||
// Measure the final position, excluding entry translation and scale.
|
||||
const settledLeft = bounds.left - motionX + (transform.a - 1) * originX;
|
||||
const settledTop = bounds.top - motionY + (transform.d - 1) * originY;
|
||||
const settledBottom = settledTop + naturalHeight * ratio;
|
||||
element.style.setProperty("--object-fit-x", `${Math.max(0, contentRight - settledLeft)}px`);
|
||||
element.style.setProperty("--object-fit-y", `${Math.max(contentTop - settledTop,
|
||||
Math.min(0, contentBottom - settledBottom))}px`);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user