@adstage/web-sdk 2.1.2 โ 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +364 -22
- package/dist/index.d.ts +40 -0
- package/dist/index.esm.js +364 -22
- package/dist/index.standalone.js +364 -22
- package/package.json +1 -1
- package/src/modules/ads/AdsModule.ts +427 -22
package/dist/index.cjs.js
CHANGED
|
@@ -2054,7 +2054,7 @@ class AdsModule {
|
|
|
2054
2054
|
this.ensureReady();
|
|
2055
2055
|
const adstageOptions = {
|
|
2056
2056
|
width: options?.width || '100%',
|
|
2057
|
-
height: options?.height ||
|
|
2057
|
+
height: options?.height || 'auto', // ๐ง ๋์ ํฌ๊ธฐ ์กฐ์ ํ์ฉ
|
|
2058
2058
|
autoSlide: options?.autoSlide || false,
|
|
2059
2059
|
slideInterval: options?.slideInterval || 5000,
|
|
2060
2060
|
onClick: options?.onClick,
|
|
@@ -2221,8 +2221,10 @@ class AdsModule {
|
|
|
2221
2221
|
adElement.setAttribute('data-adstage-container', 'true');
|
|
2222
2222
|
adElement.setAttribute('data-adstage-type', type);
|
|
2223
2223
|
adElement.setAttribute('data-adstage-slot', slotId);
|
|
2224
|
-
|
|
2225
|
-
|
|
2224
|
+
// ์ค๋งํธํ ํฌ๊ธฐ ์ค์
|
|
2225
|
+
const { width, height } = this.calculateAdSize(container, type, options);
|
|
2226
|
+
adElement.style.width = width;
|
|
2227
|
+
adElement.style.height = height;
|
|
2226
2228
|
adElement.style.border = '1px dashed #ccc';
|
|
2227
2229
|
adElement.style.display = 'flex';
|
|
2228
2230
|
adElement.style.alignItems = 'center';
|
|
@@ -2232,7 +2234,267 @@ class AdsModule {
|
|
|
2232
2234
|
adElement.innerHTML = `<span>Loading ${type} ad...</span>`;
|
|
2233
2235
|
container.appendChild(adElement);
|
|
2234
2236
|
if (this._config?.debug) {
|
|
2235
|
-
console.log(`๐ฆ Placeholder created for slot: ${slotId}`);
|
|
2237
|
+
console.log(`๐ฆ Placeholder created for slot: ${slotId} (${width} x ${height})`);
|
|
2238
|
+
}
|
|
2239
|
+
}
|
|
2240
|
+
/**
|
|
2241
|
+
* ์ปจํ
์ด๋์ ๊ด๊ณ ํ์
์ ๋ฐ๋ฅธ ์ค๋งํธํ ํฌ๊ธฐ ๊ณ์ฐ
|
|
2242
|
+
*/
|
|
2243
|
+
calculateAdSize(container, type, options) {
|
|
2244
|
+
// ์ฌ์ฉ์๊ฐ ๋ช
์์ ์ผ๋ก ํฌ๊ธฐ๋ฅผ ์ง์ ํ ๊ฒฝ์ฐ
|
|
2245
|
+
const explicitWidth = options.width;
|
|
2246
|
+
const explicitHeight = options.height;
|
|
2247
|
+
// ๋๋น ์ฒ๋ฆฌ
|
|
2248
|
+
let width;
|
|
2249
|
+
if (typeof explicitWidth === 'number') {
|
|
2250
|
+
width = `${explicitWidth}px`;
|
|
2251
|
+
}
|
|
2252
|
+
else if (typeof explicitWidth === 'string') {
|
|
2253
|
+
width = explicitWidth;
|
|
2254
|
+
}
|
|
2255
|
+
else {
|
|
2256
|
+
width = '100%'; // ๊ธฐ๋ณธ๊ฐ์ 100%
|
|
2257
|
+
}
|
|
2258
|
+
// ๋์ด ์ฒ๋ฆฌ - ํต์ฌ ๋ก์ง
|
|
2259
|
+
let height;
|
|
2260
|
+
if (typeof explicitHeight === 'number') {
|
|
2261
|
+
height = `${explicitHeight}px`;
|
|
2262
|
+
}
|
|
2263
|
+
else if (typeof explicitHeight === 'string' && explicitHeight !== '100%' && explicitHeight !== 'auto') {
|
|
2264
|
+
// ๋ช
์์ ์ธ ํฌ๊ธฐ ๋ฌธ์์ด (์: '200px', '50vh' ๋ฑ)
|
|
2265
|
+
height = explicitHeight;
|
|
2266
|
+
}
|
|
2267
|
+
else {
|
|
2268
|
+
// 100%, auto์ด๊ฑฐ๋ ๋์ด๊ฐ ์ง์ ๋์ง ์์ ๊ฒฝ์ฐ ์ค๋งํธ ๊ณ์ฐ
|
|
2269
|
+
const containerHeight = this.getContainerHeight(container);
|
|
2270
|
+
if (containerHeight > 0) {
|
|
2271
|
+
// ์ปจํ
์ด๋์ ๋์ด๊ฐ ์์ผ๋ฉด 100% ์ฌ์ฉ
|
|
2272
|
+
height = '100%';
|
|
2273
|
+
if (this._config?.debug) {
|
|
2274
|
+
console.log(`๐ Using 100% height (container: ${containerHeight}px)`);
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
else {
|
|
2278
|
+
// ์ปจํ
์ด๋์ ๋์ด๊ฐ ์์ผ๋ฉด ํ์
๋ณ ๊ธฐ๋ณธ๊ฐ ์ฌ์ฉ (๋์ค์ ๋์ ์กฐ์ ๋จ)
|
|
2279
|
+
height = this.getDefaultHeightForAdType(type);
|
|
2280
|
+
if (this._config?.debug) {
|
|
2281
|
+
console.log(`๐ Using default height ${height} (will be optimized for ${type})`);
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2285
|
+
return { width, height };
|
|
2286
|
+
}
|
|
2287
|
+
/**
|
|
2288
|
+
* ์ปจํ
์ด๋์ ์ค์ ๋์ด ๊ณ์ฐ
|
|
2289
|
+
*/
|
|
2290
|
+
getContainerHeight(container) {
|
|
2291
|
+
// ํ์ฌ ๊ณ์ฐ๋ ์คํ์ผ์์ ๋์ด ํ์ธ
|
|
2292
|
+
const computedStyle = window.getComputedStyle(container);
|
|
2293
|
+
const height = parseFloat(computedStyle.height);
|
|
2294
|
+
// height๊ฐ auto์ด๊ฑฐ๋ 0์ด๋ฉด ๋ค๋ฅธ ๋ฐฉ๋ฒ๋ค ์๋
|
|
2295
|
+
if (!height || height === 0) {
|
|
2296
|
+
// min-height ํ์ธ
|
|
2297
|
+
const minHeight = parseFloat(computedStyle.minHeight);
|
|
2298
|
+
if (minHeight > 0)
|
|
2299
|
+
return minHeight;
|
|
2300
|
+
// CSS๋ก ์ค์ ๋ ๊ณ ์ ๋์ด ํ์ธ
|
|
2301
|
+
if (container.style.height && container.style.height !== 'auto') {
|
|
2302
|
+
const styleHeight = parseFloat(container.style.height);
|
|
2303
|
+
if (styleHeight > 0)
|
|
2304
|
+
return styleHeight;
|
|
2305
|
+
}
|
|
2306
|
+
// ์์ฑ์ผ๋ก ์ค์ ๋ ๋์ด ํ์ธ
|
|
2307
|
+
const heightAttr = container.getAttribute('height');
|
|
2308
|
+
if (heightAttr) {
|
|
2309
|
+
const attrHeight = parseFloat(heightAttr);
|
|
2310
|
+
if (attrHeight > 0)
|
|
2311
|
+
return attrHeight;
|
|
2312
|
+
}
|
|
2313
|
+
}
|
|
2314
|
+
return height || 0;
|
|
2315
|
+
}
|
|
2316
|
+
/**
|
|
2317
|
+
* ๊ด๊ณ ํ์
๋ณ ๊ธฐ๋ณธ ๋์ด ๋ฐํ
|
|
2318
|
+
*/
|
|
2319
|
+
getDefaultHeightForAdType(type) {
|
|
2320
|
+
switch (type) {
|
|
2321
|
+
case AdType.BANNER:
|
|
2322
|
+
return '250px'; // ์ผ๋ฐ ๋ฐฐ๋
|
|
2323
|
+
case AdType.TEXT:
|
|
2324
|
+
return '120px'; // ํ
์คํธ๋ ์ข ๋ ์๊ฒ
|
|
2325
|
+
case AdType.VIDEO:
|
|
2326
|
+
return '360px'; // ๋น๋์ค๋ 16:9 ๋น์จ ๊ณ ๋ ค
|
|
2327
|
+
case AdType.NATIVE:
|
|
2328
|
+
return '200px'; // ๋ค์ดํฐ๋ธ๋ ์ค๊ฐ ํฌ๊ธฐ
|
|
2329
|
+
case AdType.INTERSTITIAL:
|
|
2330
|
+
return '400px'; // ์ ๋ฉด๊ด๊ณ ๋ ํฌ๊ฒ
|
|
2331
|
+
default:
|
|
2332
|
+
return '250px';
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
/**
|
|
2336
|
+
* ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ๋ณด ๋ก๋ (ํ๋ฆฌ๋ก๋ฉ)
|
|
2337
|
+
*/
|
|
2338
|
+
async loadImageDimensions(imageUrl) {
|
|
2339
|
+
return new Promise((resolve, reject) => {
|
|
2340
|
+
const img = new Image();
|
|
2341
|
+
img.onload = () => {
|
|
2342
|
+
resolve({ width: img.naturalWidth, height: img.naturalHeight });
|
|
2343
|
+
};
|
|
2344
|
+
img.onerror = () => {
|
|
2345
|
+
reject(new Error(`Failed to load image: ${imageUrl}`));
|
|
2346
|
+
};
|
|
2347
|
+
img.src = imageUrl;
|
|
2348
|
+
});
|
|
2349
|
+
}
|
|
2350
|
+
/**
|
|
2351
|
+
* ์ฌ๋ฌ ๊ด๊ณ ์ ์ต์ ์ปจํ
์ด๋ ํฌ๊ธฐ ๊ณ์ฐ (๋์ ํฌ๊ธฐ ์กฐ์ )
|
|
2352
|
+
*/
|
|
2353
|
+
async calculateOptimalContainerSize(advertisements, containerWidth, adType) {
|
|
2354
|
+
if (!advertisements.length || adType !== AdType.BANNER) {
|
|
2355
|
+
// ๋ฐฐ๋๊ฐ ์๋๊ฑฐ๋ ๊ด๊ณ ๊ฐ ์์ผ๋ฉด ๊ธฐ๋ณธ๊ฐ
|
|
2356
|
+
return {
|
|
2357
|
+
width: '100%',
|
|
2358
|
+
height: this.getDefaultHeightForAdType(adType),
|
|
2359
|
+
aspectRatio: 16 / 9
|
|
2360
|
+
};
|
|
2361
|
+
}
|
|
2362
|
+
try {
|
|
2363
|
+
// ๋ชจ๋ ๋ฐฐ๋ ์ด๋ฏธ์ง์ ํฌ๊ธฐ ์ ๋ณด ๋ก๋
|
|
2364
|
+
const imageDimensions = await Promise.allSettled(advertisements
|
|
2365
|
+
.filter(ad => ad.imageUrl)
|
|
2366
|
+
.map(ad => this.loadImageDimensions(ad.imageUrl)));
|
|
2367
|
+
const validDimensions = imageDimensions
|
|
2368
|
+
.filter((result) => result.status === 'fulfilled')
|
|
2369
|
+
.map(result => result.value);
|
|
2370
|
+
if (validDimensions.length === 0) {
|
|
2371
|
+
// ์ด๋ฏธ์ง ๋ก๋ ์คํจ์ ๊ธฐ๋ณธ๊ฐ
|
|
2372
|
+
return {
|
|
2373
|
+
width: '100%',
|
|
2374
|
+
height: this.getDefaultHeightForAdType(adType),
|
|
2375
|
+
aspectRatio: 16 / 9
|
|
2376
|
+
};
|
|
2377
|
+
}
|
|
2378
|
+
// ์ต์ ์ ๋ต ์ ํ
|
|
2379
|
+
const strategy = this.selectOptimalSizeStrategy(validDimensions);
|
|
2380
|
+
const optimalHeight = this.calculateOptimalHeight(validDimensions, containerWidth, strategy);
|
|
2381
|
+
if (this._config?.debug) {
|
|
2382
|
+
console.log(`๐ Optimal container calculated: ${containerWidth}x${optimalHeight} (strategy: ${strategy})`);
|
|
2383
|
+
}
|
|
2384
|
+
return {
|
|
2385
|
+
width: '100%',
|
|
2386
|
+
height: `${optimalHeight}px`,
|
|
2387
|
+
aspectRatio: containerWidth / optimalHeight
|
|
2388
|
+
};
|
|
2389
|
+
}
|
|
2390
|
+
catch (error) {
|
|
2391
|
+
console.warn('Failed to calculate optimal size, using defaults:', error);
|
|
2392
|
+
return {
|
|
2393
|
+
width: '100%',
|
|
2394
|
+
height: this.getDefaultHeightForAdType(adType),
|
|
2395
|
+
aspectRatio: 16 / 9
|
|
2396
|
+
};
|
|
2397
|
+
}
|
|
2398
|
+
}
|
|
2399
|
+
/**
|
|
2400
|
+
* ์ต์ ํฌ๊ธฐ ์กฐ์ ์ ๋ต ์ ํ
|
|
2401
|
+
*/
|
|
2402
|
+
selectOptimalSizeStrategy(dimensions) {
|
|
2403
|
+
const aspectRatios = dimensions.map(d => d.width / d.height);
|
|
2404
|
+
// 1. ๊ณตํต ๋น์จ์ด ์๋์ง ํ์ธ (ยฑ0.1 ํ์ฉ)
|
|
2405
|
+
const ratioGroups = new Map();
|
|
2406
|
+
aspectRatios.forEach(ratio => {
|
|
2407
|
+
const roundedRatio = Math.round(ratio * 10) / 10;
|
|
2408
|
+
const key = roundedRatio.toString();
|
|
2409
|
+
ratioGroups.set(key, (ratioGroups.get(key) || 0) + 1);
|
|
2410
|
+
});
|
|
2411
|
+
const maxGroup = Math.max(...ratioGroups.values());
|
|
2412
|
+
const totalImages = dimensions.length;
|
|
2413
|
+
// 70% ์ด์์ด ๋น์ทํ ๋น์จ์ด๋ฉด dominant ์ ๋ต
|
|
2414
|
+
if (maxGroup / totalImages >= 0.7) {
|
|
2415
|
+
return 'dominant';
|
|
2416
|
+
}
|
|
2417
|
+
// ํ์ค ๋น์จ๋ค์ด ๋ง์ผ๋ฉด common ์ ๋ต
|
|
2418
|
+
const standardRatios = [16 / 9, 4 / 3, 1 / 1, 3 / 2];
|
|
2419
|
+
const standardCount = aspectRatios.filter(ratio => standardRatios.some(standard => Math.abs(ratio - standard) < 0.1)).length;
|
|
2420
|
+
if (standardCount / totalImages >= 0.5) {
|
|
2421
|
+
return 'common';
|
|
2422
|
+
}
|
|
2423
|
+
// ๊ธฐ๋ณธ์ ํ๊ท ์ ๋ต
|
|
2424
|
+
return 'average';
|
|
2425
|
+
}
|
|
2426
|
+
/**
|
|
2427
|
+
* ์ ๋ต์ ๋ฐ๋ฅธ ์ต์ ๋์ด ๊ณ์ฐ
|
|
2428
|
+
*/
|
|
2429
|
+
calculateOptimalHeight(dimensions, containerWidth, strategy) {
|
|
2430
|
+
const aspectRatios = dimensions.map(d => d.width / d.height);
|
|
2431
|
+
switch (strategy) {
|
|
2432
|
+
case 'dominant':
|
|
2433
|
+
// ๊ฐ์ฅ ๋ง์ ๋น์จ์ ๊ธฐ์ค์ผ๋ก
|
|
2434
|
+
const ratioGroups = new Map();
|
|
2435
|
+
aspectRatios.forEach(ratio => {
|
|
2436
|
+
const roundedRatio = Math.round(ratio * 10) / 10;
|
|
2437
|
+
const key = roundedRatio.toString();
|
|
2438
|
+
const existing = ratioGroups.get(key);
|
|
2439
|
+
if (existing) {
|
|
2440
|
+
existing.count++;
|
|
2441
|
+
}
|
|
2442
|
+
else {
|
|
2443
|
+
ratioGroups.set(key, { ratio: roundedRatio, count: 1 });
|
|
2444
|
+
}
|
|
2445
|
+
});
|
|
2446
|
+
const dominantGroup = Array.from(ratioGroups.values())
|
|
2447
|
+
.reduce((max, current) => current.count > max.count ? current : max);
|
|
2448
|
+
return Math.round(containerWidth / dominantGroup.ratio);
|
|
2449
|
+
case 'common':
|
|
2450
|
+
// ํ์ค ๋น์จ ์ค ๊ฐ์ฅ ์ ํฉํ ๊ฒ ์ ํ
|
|
2451
|
+
const standardRatios = [
|
|
2452
|
+
{ ratio: 16 / 9, name: '16:9' },
|
|
2453
|
+
{ ratio: 4 / 3, name: '4:3' },
|
|
2454
|
+
{ ratio: 1 / 1, name: '1:1' },
|
|
2455
|
+
{ ratio: 3 / 2, name: '3:2' }
|
|
2456
|
+
];
|
|
2457
|
+
const avgRatio = aspectRatios.reduce((sum, ratio) => sum + ratio, 0) / aspectRatios.length;
|
|
2458
|
+
const bestStandard = standardRatios.reduce((best, current) => Math.abs(current.ratio - avgRatio) < Math.abs(best.ratio - avgRatio) ? current : best);
|
|
2459
|
+
if (this._config?.debug) {
|
|
2460
|
+
console.log(`๐ Using standard ratio: ${bestStandard.name} (avg: ${avgRatio.toFixed(2)})`);
|
|
2461
|
+
}
|
|
2462
|
+
return Math.round(containerWidth / bestStandard.ratio);
|
|
2463
|
+
case 'average':
|
|
2464
|
+
default:
|
|
2465
|
+
// ํ๊ท ๋น์จ ์ฌ์ฉ
|
|
2466
|
+
const averageRatio = aspectRatios.reduce((sum, ratio) => sum + ratio, 0) / aspectRatios.length;
|
|
2467
|
+
return Math.round(containerWidth / averageRatio);
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
/**
|
|
2471
|
+
* ๊ฐ๋ณ ์ด๋ฏธ์ง์ ์ต์ ํ๋ ๋ ๋๋ง ์คํ์ผ ์ ์ฉ
|
|
2472
|
+
*/
|
|
2473
|
+
applyOptimizedImageStyle(img, imageAspectRatio, containerAspectRatio) {
|
|
2474
|
+
const ratio = imageAspectRatio / containerAspectRatio;
|
|
2475
|
+
if (Math.abs(ratio - 1) < 0.1) {
|
|
2476
|
+
// ๋น์จ์ด ๊ฑฐ์ ๊ฐ์ผ๋ฉด cover ์ฌ์ฉ
|
|
2477
|
+
img.style.objectFit = 'cover';
|
|
2478
|
+
img.style.objectPosition = 'center';
|
|
2479
|
+
}
|
|
2480
|
+
else if (ratio > 1.3) {
|
|
2481
|
+
// ์ด๋ฏธ์ง๊ฐ ํจ์ฌ ๊ฐ๋กํ์ด๋ฉด contain์ผ๋ก ์ ์ฒด ๋ณด์ด๊ธฐ
|
|
2482
|
+
img.style.objectFit = 'contain';
|
|
2483
|
+
img.style.objectPosition = 'center';
|
|
2484
|
+
img.style.backgroundColor = '#f0f0f0'; // ๋น ๊ณต๊ฐ ๋ฐฐ๊ฒฝ์
|
|
2485
|
+
}
|
|
2486
|
+
else if (ratio < 0.7) {
|
|
2487
|
+
// ์ด๋ฏธ์ง๊ฐ ํจ์ฌ ์ธ๋กํ์ด๋ฉด cover๋ก ์ฑ์ฐ๊ธฐ
|
|
2488
|
+
img.style.objectFit = 'cover';
|
|
2489
|
+
img.style.objectPosition = 'center';
|
|
2490
|
+
}
|
|
2491
|
+
else {
|
|
2492
|
+
// ์ ๋นํ ์ฐจ์ด๋ฉด ์ค๋งํธ cover
|
|
2493
|
+
img.style.objectFit = 'cover';
|
|
2494
|
+
img.style.objectPosition = 'center';
|
|
2495
|
+
}
|
|
2496
|
+
if (this._config?.debug) {
|
|
2497
|
+
console.log(`๐จ Image style applied: objectFit=${img.style.objectFit}, ratio=${ratio.toFixed(2)}`);
|
|
2236
2498
|
}
|
|
2237
2499
|
}
|
|
2238
2500
|
/**
|
|
@@ -2246,6 +2508,10 @@ class AdsModule {
|
|
|
2246
2508
|
this.renderFallback(slot);
|
|
2247
2509
|
return;
|
|
2248
2510
|
}
|
|
2511
|
+
// ๐ ๋์ ํฌ๊ธฐ ์กฐ์ : ๋ฐฐ๋ ๊ด๊ณ ์ ๊ฒฝ์ฐ ์ด๋ฏธ์ง ํฌ๊ธฐ ๊ธฐ๋ฐ์ผ๋ก ์ปจํ
์ด๋ ์ต์ ํ
|
|
2512
|
+
if (slot.adType === AdType.BANNER && adstageData.length > 0) {
|
|
2513
|
+
await this.optimizeContainerForBannerAds(slot, adstageData);
|
|
2514
|
+
}
|
|
2249
2515
|
// ๊ด๊ณ ๊ฐ ์ฌ๋ฌ ๊ฐ์ด๊ฑฐ๋ autoSlide ์ต์
์ด ์์ผ๋ฉด ์ฌ๋ผ์ด๋๋ก ๋ ๋๋ง
|
|
2250
2516
|
if (adstageData.length > 1 || slot.config?.autoSlide) {
|
|
2251
2517
|
await this.renderAdSlider(slot, adstageData);
|
|
@@ -2267,6 +2533,32 @@ class AdsModule {
|
|
|
2267
2533
|
this.renderFallback(slot);
|
|
2268
2534
|
}
|
|
2269
2535
|
}
|
|
2536
|
+
/**
|
|
2537
|
+
* ๋ฐฐ๋ ๊ด๊ณ ๋ฅผ ์ํ ์ปจํ
์ด๋ ์ต์ ํ
|
|
2538
|
+
*/
|
|
2539
|
+
async optimizeContainerForBannerAds(slot, advertisements) {
|
|
2540
|
+
try {
|
|
2541
|
+
const container = document.getElementById(slot.containerId);
|
|
2542
|
+
const adElement = document.getElementById(slot.id);
|
|
2543
|
+
if (!container || !adElement)
|
|
2544
|
+
return;
|
|
2545
|
+
// ํ์ฌ ์ปจํ
์ด๋ ๋๋น ํ์ธ
|
|
2546
|
+
const containerWidth = container.getBoundingClientRect().width || 300;
|
|
2547
|
+
// ์ต์ ํฌ๊ธฐ ๊ณ์ฐ
|
|
2548
|
+
const optimalSize = await this.calculateOptimalContainerSize(advertisements, containerWidth, slot.adType);
|
|
2549
|
+
// ์ปจํ
์ด๋ ํฌ๊ธฐ ๋์ ์กฐ์
|
|
2550
|
+
adElement.style.height = optimalSize.height;
|
|
2551
|
+
// ์ฌ๋กฏ ์ ๋ณด ์
๋ฐ์ดํธ
|
|
2552
|
+
slot.optimizedHeight = optimalSize.height;
|
|
2553
|
+
slot.aspectRatio = optimalSize.aspectRatio;
|
|
2554
|
+
if (this._config?.debug) {
|
|
2555
|
+
console.log(`๐ง Container optimized for ${advertisements.length} banner ads: ${optimalSize.height}`);
|
|
2556
|
+
}
|
|
2557
|
+
}
|
|
2558
|
+
catch (error) {
|
|
2559
|
+
console.warn('Container optimization failed, using default size:', error);
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2270
2562
|
/**
|
|
2271
2563
|
* ๊ธฐ๋ณธ viewability ์ถ์ ์์
|
|
2272
2564
|
*/
|
|
@@ -2489,23 +2781,25 @@ class AdsModule {
|
|
|
2489
2781
|
}
|
|
2490
2782
|
};
|
|
2491
2783
|
let sliderElement;
|
|
2784
|
+
// ์ต์ ํ๋ ์ฌ๋ผ์ด๋ ์ต์
์ค๋น
|
|
2785
|
+
const optimizedSliderOptions = {
|
|
2786
|
+
autoSlideInterval: (slot.config?.slideInterval || 5000) / 1000,
|
|
2787
|
+
...slot.config,
|
|
2788
|
+
// ๐ ๋์ ํฌ๊ธฐ ์ ๋ณด ์ ๋ฌ
|
|
2789
|
+
optimizedHeight: slot.optimizedHeight,
|
|
2790
|
+
aspectRatio: slot.aspectRatio
|
|
2791
|
+
};
|
|
2492
2792
|
// ํ
์คํธ ๊ด๊ณ ๋ TextTransitionManager ์ฌ์ฉ, ๊ทธ ์ธ๋ CarouselSliderManager ์ฌ์ฉ
|
|
2493
2793
|
if (slot.adType === AdType.TEXT) {
|
|
2494
|
-
sliderElement = TextTransitionManager.createTextTransitionContainer(slot, advertisements,
|
|
2495
|
-
autoSlideInterval: (slot.config?.slideInterval || 5000) / 1000,
|
|
2496
|
-
...slot.config
|
|
2497
|
-
}, trackEventCallback);
|
|
2794
|
+
sliderElement = TextTransitionManager.createTextTransitionContainer(slot, advertisements, optimizedSliderOptions, trackEventCallback);
|
|
2498
2795
|
if (this._config?.debug) {
|
|
2499
2796
|
console.log(`โจ Text transition created for TEXT slot: ${slot.id} with ${advertisements.length} ads`);
|
|
2500
2797
|
}
|
|
2501
2798
|
}
|
|
2502
2799
|
else {
|
|
2503
|
-
sliderElement = CarouselSliderManager.createSliderContainer(slot, advertisements,
|
|
2504
|
-
autoSlideInterval: (slot.config?.slideInterval || 5000) / 1000,
|
|
2505
|
-
...slot.config
|
|
2506
|
-
}, trackEventCallback);
|
|
2800
|
+
sliderElement = CarouselSliderManager.createSliderContainer(slot, advertisements, optimizedSliderOptions, trackEventCallback);
|
|
2507
2801
|
if (this._config?.debug) {
|
|
2508
|
-
console.log(`๐ Carousel slider created for ${slot.adType} slot: ${slot.id} with ${advertisements.length} ads`);
|
|
2802
|
+
console.log(`๐ Carousel slider created for ${slot.adType} slot: ${slot.id} with ${advertisements.length} ads (optimized: ${slot.optimizedHeight || 'default'})`);
|
|
2509
2803
|
}
|
|
2510
2804
|
}
|
|
2511
2805
|
// ๊ธฐ์กด ๋ด์ฉ ์ ๊ฑฐํ๊ณ ์ฌ๋ผ์ด๋ ์ถ๊ฐ
|
|
@@ -2532,19 +2826,23 @@ class AdsModule {
|
|
|
2532
2826
|
// ๊ธฐ๋ณธ HTML ๊ตฌ์กฐ ์์ฑ
|
|
2533
2827
|
const adElement = document.createElement('div');
|
|
2534
2828
|
adElement.className = 'adstage-ad';
|
|
2535
|
-
|
|
2536
|
-
|
|
2829
|
+
// ์ค๋งํธํ ํฌ๊ธฐ ์ค์ - ์ต์ ํ๋ ํฌ๊ธฐ๊ฐ ์์ผ๋ฉด ์ฌ์ฉ
|
|
2830
|
+
const optimizedHeight = slot.optimizedHeight;
|
|
2831
|
+
const containerElement = container.parentElement || container;
|
|
2832
|
+
if (optimizedHeight) {
|
|
2833
|
+
adElement.style.width = '100%';
|
|
2834
|
+
adElement.style.height = optimizedHeight;
|
|
2835
|
+
}
|
|
2836
|
+
else {
|
|
2837
|
+
const { width, height } = this.calculateAdSize(containerElement, slot.adType, slot.config || {});
|
|
2838
|
+
adElement.style.width = width;
|
|
2839
|
+
adElement.style.height = height;
|
|
2840
|
+
}
|
|
2537
2841
|
// ๊ด๊ณ ํ์
๋ณ ๋ ๋๋ง
|
|
2538
2842
|
switch (slot.adType) {
|
|
2539
2843
|
case AdType.BANNER:
|
|
2540
2844
|
if (ad.imageUrl) {
|
|
2541
|
-
|
|
2542
|
-
img.src = ad.imageUrl;
|
|
2543
|
-
img.alt = ad.title;
|
|
2544
|
-
img.style.width = '100%';
|
|
2545
|
-
img.style.height = '100%';
|
|
2546
|
-
img.style.objectFit = 'cover';
|
|
2547
|
-
adElement.appendChild(img);
|
|
2845
|
+
await this.renderOptimizedBannerImage(adElement, ad, slot);
|
|
2548
2846
|
}
|
|
2549
2847
|
break;
|
|
2550
2848
|
case AdType.TEXT:
|
|
@@ -2579,6 +2877,50 @@ class AdsModule {
|
|
|
2579
2877
|
container.innerHTML = '';
|
|
2580
2878
|
container.appendChild(adElement);
|
|
2581
2879
|
}
|
|
2880
|
+
/**
|
|
2881
|
+
* ์ต์ ํ๋ ๋ฐฐ๋ ์ด๋ฏธ์ง ๋ ๋๋ง
|
|
2882
|
+
*/
|
|
2883
|
+
async renderOptimizedBannerImage(adElement, ad, slot) {
|
|
2884
|
+
try {
|
|
2885
|
+
// ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ๋ณด ๋ก๋
|
|
2886
|
+
const imageDimensions = await this.loadImageDimensions(ad.imageUrl);
|
|
2887
|
+
const imageAspectRatio = imageDimensions.width / imageDimensions.height;
|
|
2888
|
+
// ์ปจํ
์ด๋ ๋น์จ ๊ณ์ฐ
|
|
2889
|
+
const containerAspectRatio = slot.aspectRatio || 16 / 9;
|
|
2890
|
+
// ์ด๋ฏธ์ง ์์ ์์ฑ
|
|
2891
|
+
const img = document.createElement('img');
|
|
2892
|
+
img.src = ad.imageUrl;
|
|
2893
|
+
img.alt = ad.title;
|
|
2894
|
+
img.style.width = '100%';
|
|
2895
|
+
img.style.height = '100%';
|
|
2896
|
+
// ๐จ ์ต์ ํ๋ ์คํ์ผ ์ ์ฉ
|
|
2897
|
+
this.applyOptimizedImageStyle(img, imageAspectRatio, containerAspectRatio);
|
|
2898
|
+
// ์ด๋ฏธ์ง ๋ก๋ ์๋ฃ ์ฒ๋ฆฌ
|
|
2899
|
+
img.onload = () => {
|
|
2900
|
+
if (this._config?.debug) {
|
|
2901
|
+
console.log(`๐ผ๏ธ Optimized banner image loaded: ${imageDimensions.width}x${imageDimensions.height} (ratio: ${imageAspectRatio.toFixed(2)})`);
|
|
2902
|
+
}
|
|
2903
|
+
};
|
|
2904
|
+
// ์๋ฌ ์ฒ๋ฆฌ
|
|
2905
|
+
img.onerror = () => {
|
|
2906
|
+
console.warn(`Failed to load banner image: ${ad.imageUrl}`);
|
|
2907
|
+
// ํด๋ฐฑ ํ
์คํธ ํ์
|
|
2908
|
+
adElement.innerHTML = `<div style="display: flex; align-items: center; justify-content: center; background: #f0f0f0; color: #666;">${ad.title}</div>`;
|
|
2909
|
+
};
|
|
2910
|
+
adElement.appendChild(img);
|
|
2911
|
+
}
|
|
2912
|
+
catch (error) {
|
|
2913
|
+
console.warn('Failed to optimize banner image, using fallback:', error);
|
|
2914
|
+
// ๊ธฐ๋ณธ ์ด๋ฏธ์ง ๋ ๋๋ง (ํด๋ฐฑ)
|
|
2915
|
+
const img = document.createElement('img');
|
|
2916
|
+
img.src = ad.imageUrl;
|
|
2917
|
+
img.alt = ad.title;
|
|
2918
|
+
img.style.width = '100%';
|
|
2919
|
+
img.style.height = '100%';
|
|
2920
|
+
img.style.objectFit = 'cover';
|
|
2921
|
+
adElement.appendChild(img);
|
|
2922
|
+
}
|
|
2923
|
+
}
|
|
2582
2924
|
/**
|
|
2583
2925
|
* ๊ด๊ณ ์ฌ๋กฏ ์๋ก๊ณ ์นจ
|
|
2584
2926
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -282,10 +282,46 @@ declare class AdsModule implements BaseModule {
|
|
|
282
282
|
* ์ฆ์ ๊ด๊ณ ์ฌ๋กฏ ์์ฑ (placeholder)
|
|
283
283
|
*/
|
|
284
284
|
private createAdSlot;
|
|
285
|
+
/**
|
|
286
|
+
* ์ปจํ
์ด๋์ ๊ด๊ณ ํ์
์ ๋ฐ๋ฅธ ์ค๋งํธํ ํฌ๊ธฐ ๊ณ์ฐ
|
|
287
|
+
*/
|
|
288
|
+
private calculateAdSize;
|
|
289
|
+
/**
|
|
290
|
+
* ์ปจํ
์ด๋์ ์ค์ ๋์ด ๊ณ์ฐ
|
|
291
|
+
*/
|
|
292
|
+
private getContainerHeight;
|
|
293
|
+
/**
|
|
294
|
+
* ๊ด๊ณ ํ์
๋ณ ๊ธฐ๋ณธ ๋์ด ๋ฐํ
|
|
295
|
+
*/
|
|
296
|
+
private getDefaultHeightForAdType;
|
|
297
|
+
/**
|
|
298
|
+
* ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ๋ณด ๋ก๋ (ํ๋ฆฌ๋ก๋ฉ)
|
|
299
|
+
*/
|
|
300
|
+
private loadImageDimensions;
|
|
301
|
+
/**
|
|
302
|
+
* ์ฌ๋ฌ ๊ด๊ณ ์ ์ต์ ์ปจํ
์ด๋ ํฌ๊ธฐ ๊ณ์ฐ (๋์ ํฌ๊ธฐ ์กฐ์ )
|
|
303
|
+
*/
|
|
304
|
+
private calculateOptimalContainerSize;
|
|
305
|
+
/**
|
|
306
|
+
* ์ต์ ํฌ๊ธฐ ์กฐ์ ์ ๋ต ์ ํ
|
|
307
|
+
*/
|
|
308
|
+
private selectOptimalSizeStrategy;
|
|
309
|
+
/**
|
|
310
|
+
* ์ ๋ต์ ๋ฐ๋ฅธ ์ต์ ๋์ด ๊ณ์ฐ
|
|
311
|
+
*/
|
|
312
|
+
private calculateOptimalHeight;
|
|
313
|
+
/**
|
|
314
|
+
* ๊ฐ๋ณ ์ด๋ฏธ์ง์ ์ต์ ํ๋ ๋ ๋๋ง ์คํ์ผ ์ ์ฉ
|
|
315
|
+
*/
|
|
316
|
+
private applyOptimizedImageStyle;
|
|
285
317
|
/**
|
|
286
318
|
* ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๊ด๊ณ ์ฝํ
์ธ ๋ก๋
|
|
287
319
|
*/
|
|
288
320
|
private loadAdContentInBackground;
|
|
321
|
+
/**
|
|
322
|
+
* ๋ฐฐ๋ ๊ด๊ณ ๋ฅผ ์ํ ์ปจํ
์ด๋ ์ต์ ํ
|
|
323
|
+
*/
|
|
324
|
+
private optimizeContainerForBannerAds;
|
|
289
325
|
/**
|
|
290
326
|
* ๊ธฐ๋ณธ viewability ์ถ์ ์์
|
|
291
327
|
*/
|
|
@@ -318,6 +354,10 @@ declare class AdsModule implements BaseModule {
|
|
|
318
354
|
* ๊ด๊ณ ์์ ๋ ๋๋ง (๊ธฐ๋ณธ ๊ตฌํ)
|
|
319
355
|
*/
|
|
320
356
|
private renderAdElement;
|
|
357
|
+
/**
|
|
358
|
+
* ์ต์ ํ๋ ๋ฐฐ๋ ์ด๋ฏธ์ง ๋ ๋๋ง
|
|
359
|
+
*/
|
|
360
|
+
private renderOptimizedBannerImage;
|
|
321
361
|
/**
|
|
322
362
|
* ๊ด๊ณ ์ฌ๋กฏ ์๋ก๊ณ ์นจ
|
|
323
363
|
*/
|