@playcraft/adsdk 1.0.16 → 1.0.17

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/esm/index.js CHANGED
@@ -510,6 +510,83 @@ function getConfig() {
510
510
  return _cachedConfig;
511
511
  }
512
512
 
513
+ // src/cursor.ts
514
+ var cleanup = null;
515
+ function toCursor(src, size) {
516
+ const hotspot = Math.round(size / 8);
517
+ return new Promise((resolve, reject) => {
518
+ const img = new Image();
519
+ img.onload = () => {
520
+ const c = document.createElement("canvas");
521
+ c.width = size;
522
+ c.height = size;
523
+ const ctx = c.getContext("2d");
524
+ if (!ctx) {
525
+ reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
526
+ return;
527
+ }
528
+ ctx.drawImage(img, 0, 0, size, size);
529
+ resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
530
+ };
531
+ img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
532
+ img.src = src;
533
+ });
534
+ }
535
+ function enableCustomCursor(opts = {}) {
536
+ var _a, _b;
537
+ cleanup == null ? void 0 : cleanup();
538
+ cleanup = null;
539
+ if (typeof document === "undefined") return () => {
540
+ };
541
+ const target = (_a = opts.target) != null ? _a : document.body;
542
+ if (!target) {
543
+ console.warn("[PlayableSDK] enableCustomCursor: target not found");
544
+ return () => {
545
+ };
546
+ }
547
+ const size = (_b = opts.size) != null ? _b : 64;
548
+ const prevCursor = target.style.cursor;
549
+ let disposed = false;
550
+ let down = null;
551
+ let up = null;
552
+ const dispose = () => {
553
+ if (disposed) return;
554
+ disposed = true;
555
+ target.style.cursor = prevCursor;
556
+ if (down) target.removeEventListener("pointerdown", down);
557
+ if (up) {
558
+ target.removeEventListener("pointerup", up);
559
+ target.removeEventListener("pointercancel", up);
560
+ }
561
+ if (cleanup === dispose) cleanup = null;
562
+ };
563
+ cleanup = dispose;
564
+ Promise.all([
565
+ toCursor(FINGER_HOVERING, size),
566
+ toCursor(FINGER_PRESSING, size)
567
+ ]).then(([hover, press]) => {
568
+ if (disposed) return;
569
+ target.style.cursor = hover;
570
+ down = () => {
571
+ target.style.cursor = press;
572
+ };
573
+ up = () => {
574
+ target.style.cursor = hover;
575
+ };
576
+ target.addEventListener("pointerdown", down);
577
+ target.addEventListener("pointerup", up);
578
+ target.addEventListener("pointercancel", up);
579
+ }).catch((err) => {
580
+ console.warn("[PlayableSDK] enableCustomCursor failed:", err);
581
+ dispose();
582
+ });
583
+ return dispose;
584
+ }
585
+ function disableCustomCursor() {
586
+ cleanup == null ? void 0 : cleanup();
587
+ cleanup = null;
588
+ }
589
+
513
590
  // src/core.ts
514
591
  var destinationUrl = "";
515
592
  var isSDKInitialized = false;
@@ -845,6 +922,7 @@ var _sdk = class _sdk {
845
922
  * This must be called as earlier as possible.
846
923
  *
847
924
  * @param callback Optional function called when ad container is ready
925
+ * @param options Optional configuration options
848
926
  * @example
849
927
  * // Basic initialization
850
928
  * sdk.playcraftInit();
@@ -857,12 +935,15 @@ var _sdk = class _sdk {
857
935
  * @fires playcraftInit When SDK initialization starts
858
936
  * @fires playcraftReady When game instance is created and ready to load resources
859
937
  */
860
- static playcraftInit(callback) {
938
+ static playcraftInit(callback, options) {
861
939
  if (isSDKInitialized) return;
862
940
  if (callback) initCallback = callback;
863
941
  initTrackingProtocols();
864
942
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
865
943
  isSDKInitialized = true;
944
+ if ((options == null ? void 0 : options.useCustomCursor) !== false) {
945
+ enableCustomCursor();
946
+ }
866
947
  }
867
948
  /**
868
949
  * Starts the playable ad experience.
@@ -1255,9 +1336,35 @@ var _sdk = class _sdk {
1255
1336
  static getConfig() {
1256
1337
  return getConfig();
1257
1338
  }
1339
+ /**
1340
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
1341
+ * 悬浮显示手指图标,按下时切换为按压态图标。
1342
+ * 多次调用会先清理上一次的状态再重新绑定。
1343
+ *
1344
+ * @param opts 可选配置
1345
+ * - opts.target: 目标元素,未传则默认 document.body
1346
+ * - opts.size: 光标尺寸(像素),默认 64,热点固定为 size 的 1/8
1347
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听
1348
+ *
1349
+ * @example
1350
+ * sdk.enableCustomCursor();
1351
+ * sdk.enableCustomCursor({ size: 96 });
1352
+ */
1353
+ static enableCustomCursor(opts) {
1354
+ return enableCustomCursor(opts);
1355
+ }
1356
+ /**
1357
+ * 关闭自定义鼠标指针,恢复默认光标。
1358
+ *
1359
+ * @example
1360
+ * sdk.disableCustomCursor();
1361
+ */
1362
+ static disableCustomCursor() {
1363
+ disableCustomCursor();
1364
+ }
1258
1365
  };
1259
1366
  /** Current version of the SDK */
1260
- _sdk.version = "1.0.16";
1367
+ _sdk.version = "1.0.17";
1261
1368
  /** Current maximum width of the playable ad container in pixels */
1262
1369
  _sdk.maxWidth = Math.floor(window.innerWidth);
1263
1370
  /** Current maximum height of the playable ad container in pixels */
@@ -1283,83 +1390,6 @@ window["console"].log(
1283
1390
  "background: #e1e4e8; color: #333; font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"
1284
1391
  );
1285
1392
  window.PlayableSDK = sdk;
1286
-
1287
- // src/cursor.ts
1288
- var cleanup = null;
1289
- function toCursor(src, size) {
1290
- const hotspot = Math.round(size / 8);
1291
- return new Promise((resolve, reject) => {
1292
- const img = new Image();
1293
- img.onload = () => {
1294
- const c = document.createElement("canvas");
1295
- c.width = size;
1296
- c.height = size;
1297
- const ctx = c.getContext("2d");
1298
- if (!ctx) {
1299
- reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
1300
- return;
1301
- }
1302
- ctx.drawImage(img, 0, 0, size, size);
1303
- resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
1304
- };
1305
- img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
1306
- img.src = src;
1307
- });
1308
- }
1309
- function enableCustomCursor(opts = {}) {
1310
- var _a, _b;
1311
- cleanup == null ? void 0 : cleanup();
1312
- cleanup = null;
1313
- if (typeof document === "undefined") return () => {
1314
- };
1315
- const target = (_a = opts.target) != null ? _a : document.body;
1316
- if (!target) {
1317
- console.warn("[PlayableSDK] enableCustomCursor: target not found");
1318
- return () => {
1319
- };
1320
- }
1321
- const size = (_b = opts.size) != null ? _b : 64;
1322
- const prevCursor = target.style.cursor;
1323
- let disposed = false;
1324
- let down = null;
1325
- let up = null;
1326
- const dispose = () => {
1327
- if (disposed) return;
1328
- disposed = true;
1329
- target.style.cursor = prevCursor;
1330
- if (down) target.removeEventListener("pointerdown", down);
1331
- if (up) {
1332
- target.removeEventListener("pointerup", up);
1333
- target.removeEventListener("pointercancel", up);
1334
- }
1335
- if (cleanup === dispose) cleanup = null;
1336
- };
1337
- cleanup = dispose;
1338
- Promise.all([
1339
- toCursor(FINGER_HOVERING, size),
1340
- toCursor(FINGER_PRESSING, size)
1341
- ]).then(([hover, press]) => {
1342
- if (disposed) return;
1343
- target.style.cursor = hover;
1344
- down = () => {
1345
- target.style.cursor = press;
1346
- };
1347
- up = () => {
1348
- target.style.cursor = hover;
1349
- };
1350
- target.addEventListener("pointerdown", down);
1351
- target.addEventListener("pointerup", up);
1352
- target.addEventListener("pointercancel", up);
1353
- }).catch((err) => {
1354
- console.warn("[PlayableSDK] enableCustomCursor failed:", err);
1355
- dispose();
1356
- });
1357
- return dispose;
1358
- }
1359
- function disableCustomCursor() {
1360
- cleanup == null ? void 0 : cleanup();
1361
- cleanup = null;
1362
- }
1363
1393
  export {
1364
1394
  sdk as default,
1365
1395
  disableCustomCursor,
@@ -748,6 +748,83 @@
748
748
  return _cachedConfig;
749
749
  }
750
750
 
751
+ // src/cursor.ts
752
+ var cleanup = null;
753
+ function toCursor(src, size) {
754
+ const hotspot = Math.round(size / 8);
755
+ return new Promise((resolve, reject) => {
756
+ const img = new Image();
757
+ img.onload = () => {
758
+ const c = document.createElement("canvas");
759
+ c.width = size;
760
+ c.height = size;
761
+ const ctx = c.getContext("2d");
762
+ if (!ctx) {
763
+ reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
764
+ return;
765
+ }
766
+ ctx.drawImage(img, 0, 0, size, size);
767
+ resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
768
+ };
769
+ img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
770
+ img.src = src;
771
+ });
772
+ }
773
+ function enableCustomCursor(opts = {}) {
774
+ var _a, _b;
775
+ cleanup == null ? void 0 : cleanup();
776
+ cleanup = null;
777
+ if (typeof document === "undefined") return () => {
778
+ };
779
+ const target = (_a = opts.target) != null ? _a : document.body;
780
+ if (!target) {
781
+ console.warn("[PlayableSDK] enableCustomCursor: target not found");
782
+ return () => {
783
+ };
784
+ }
785
+ const size = (_b = opts.size) != null ? _b : 64;
786
+ const prevCursor = target.style.cursor;
787
+ let disposed = false;
788
+ let down = null;
789
+ let up = null;
790
+ const dispose = () => {
791
+ if (disposed) return;
792
+ disposed = true;
793
+ target.style.cursor = prevCursor;
794
+ if (down) target.removeEventListener("pointerdown", down);
795
+ if (up) {
796
+ target.removeEventListener("pointerup", up);
797
+ target.removeEventListener("pointercancel", up);
798
+ }
799
+ if (cleanup === dispose) cleanup = null;
800
+ };
801
+ cleanup = dispose;
802
+ Promise.all([
803
+ toCursor(FINGER_HOVERING, size),
804
+ toCursor(FINGER_PRESSING, size)
805
+ ]).then(([hover, press]) => {
806
+ if (disposed) return;
807
+ target.style.cursor = hover;
808
+ down = () => {
809
+ target.style.cursor = press;
810
+ };
811
+ up = () => {
812
+ target.style.cursor = hover;
813
+ };
814
+ target.addEventListener("pointerdown", down);
815
+ target.addEventListener("pointerup", up);
816
+ target.addEventListener("pointercancel", up);
817
+ }).catch((err) => {
818
+ console.warn("[PlayableSDK] enableCustomCursor failed:", err);
819
+ dispose();
820
+ });
821
+ return dispose;
822
+ }
823
+ function disableCustomCursor() {
824
+ cleanup == null ? void 0 : cleanup();
825
+ cleanup = null;
826
+ }
827
+
751
828
  // src/core.ts
752
829
  var destinationUrl = "";
753
830
  var isSDKInitialized = false;
@@ -1083,6 +1160,7 @@
1083
1160
  * This must be called as earlier as possible.
1084
1161
  *
1085
1162
  * @param callback Optional function called when ad container is ready
1163
+ * @param options Optional configuration options
1086
1164
  * @example
1087
1165
  * // Basic initialization
1088
1166
  * sdk.playcraftInit();
@@ -1095,12 +1173,15 @@
1095
1173
  * @fires playcraftInit When SDK initialization starts
1096
1174
  * @fires playcraftReady When game instance is created and ready to load resources
1097
1175
  */
1098
- static playcraftInit(callback) {
1176
+ static playcraftInit(callback, options) {
1099
1177
  if (isSDKInitialized) return;
1100
1178
  if (callback) initCallback = callback;
1101
1179
  initTrackingProtocols();
1102
1180
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
1103
1181
  isSDKInitialized = true;
1182
+ if ((options == null ? void 0 : options.useCustomCursor) !== false) {
1183
+ enableCustomCursor();
1184
+ }
1104
1185
  }
1105
1186
  /**
1106
1187
  * Starts the playable ad experience.
@@ -1493,9 +1574,35 @@
1493
1574
  static getConfig() {
1494
1575
  return getConfig();
1495
1576
  }
1577
+ /**
1578
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
1579
+ * 悬浮显示手指图标,按下时切换为按压态图标。
1580
+ * 多次调用会先清理上一次的状态再重新绑定。
1581
+ *
1582
+ * @param opts 可选配置
1583
+ * - opts.target: 目标元素,未传则默认 document.body
1584
+ * - opts.size: 光标尺寸(像素),默认 64,热点固定为 size 的 1/8
1585
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听
1586
+ *
1587
+ * @example
1588
+ * sdk.enableCustomCursor();
1589
+ * sdk.enableCustomCursor({ size: 96 });
1590
+ */
1591
+ static enableCustomCursor(opts) {
1592
+ return enableCustomCursor(opts);
1593
+ }
1594
+ /**
1595
+ * 关闭自定义鼠标指针,恢复默认光标。
1596
+ *
1597
+ * @example
1598
+ * sdk.disableCustomCursor();
1599
+ */
1600
+ static disableCustomCursor() {
1601
+ disableCustomCursor();
1602
+ }
1496
1603
  };
1497
1604
  /** Current version of the SDK */
1498
- _sdk.version = "1.0.16";
1605
+ _sdk.version = "1.0.17";
1499
1606
  /** Current maximum width of the playable ad container in pixels */
1500
1607
  _sdk.maxWidth = Math.floor(window.innerWidth);
1501
1608
  /** Current maximum height of the playable ad container in pixels */
@@ -1521,81 +1628,4 @@
1521
1628
  "background: #e1e4e8; color: #333; font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"
1522
1629
  );
1523
1630
  window.PlayableSDK = sdk;
1524
-
1525
- // src/cursor.ts
1526
- var cleanup = null;
1527
- function toCursor(src, size) {
1528
- const hotspot = Math.round(size / 8);
1529
- return new Promise((resolve, reject) => {
1530
- const img = new Image();
1531
- img.onload = () => {
1532
- const c = document.createElement("canvas");
1533
- c.width = size;
1534
- c.height = size;
1535
- const ctx = c.getContext("2d");
1536
- if (!ctx) {
1537
- reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
1538
- return;
1539
- }
1540
- ctx.drawImage(img, 0, 0, size, size);
1541
- resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
1542
- };
1543
- img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
1544
- img.src = src;
1545
- });
1546
- }
1547
- function enableCustomCursor(opts = {}) {
1548
- var _a, _b;
1549
- cleanup == null ? void 0 : cleanup();
1550
- cleanup = null;
1551
- if (typeof document === "undefined") return () => {
1552
- };
1553
- const target = (_a = opts.target) != null ? _a : document.body;
1554
- if (!target) {
1555
- console.warn("[PlayableSDK] enableCustomCursor: target not found");
1556
- return () => {
1557
- };
1558
- }
1559
- const size = (_b = opts.size) != null ? _b : 64;
1560
- const prevCursor = target.style.cursor;
1561
- let disposed = false;
1562
- let down = null;
1563
- let up = null;
1564
- const dispose = () => {
1565
- if (disposed) return;
1566
- disposed = true;
1567
- target.style.cursor = prevCursor;
1568
- if (down) target.removeEventListener("pointerdown", down);
1569
- if (up) {
1570
- target.removeEventListener("pointerup", up);
1571
- target.removeEventListener("pointercancel", up);
1572
- }
1573
- if (cleanup === dispose) cleanup = null;
1574
- };
1575
- cleanup = dispose;
1576
- Promise.all([
1577
- toCursor(FINGER_HOVERING, size),
1578
- toCursor(FINGER_PRESSING, size)
1579
- ]).then(([hover, press]) => {
1580
- if (disposed) return;
1581
- target.style.cursor = hover;
1582
- down = () => {
1583
- target.style.cursor = press;
1584
- };
1585
- up = () => {
1586
- target.style.cursor = hover;
1587
- };
1588
- target.addEventListener("pointerdown", down);
1589
- target.addEventListener("pointerup", up);
1590
- target.addEventListener("pointercancel", up);
1591
- }).catch((err) => {
1592
- console.warn("[PlayableSDK] enableCustomCursor failed:", err);
1593
- dispose();
1594
- });
1595
- return dispose;
1596
- }
1597
- function disableCustomCursor() {
1598
- cleanup == null ? void 0 : cleanup();
1599
- cleanup = null;
1600
- }
1601
1631
  })();
package/dist/index.d.mts CHANGED
@@ -1,5 +1,33 @@
1
1
  type EventName = 'playcraftInit' | 'playcraftReady' | 'playcraftStart' | 'playcraftInteractive' | 'playcraftInteraction' | 'playcraftChallengeStart' | 'playcraftChallengeProgress' | 'playcraftChallengeSuccess' | 'playcraftChallengeFailed' | 'playcraftResize' | 'playcraftPause' | 'playcraftResume' | 'playcraftVolume' | 'playcraftRetry' | 'playcraftFinish' | 'playcraftInstall';
2
2
 
3
+ /**
4
+ * 自定义鼠标指针模块。
5
+ *
6
+ * 默认挂载到 `document.body`,把整页的默认光标替换为内置的手指图标:
7
+ * - 悬浮时显示 FingerHovering
8
+ * - 按下时显示 FingerPressing
9
+ *
10
+ * 图片以 base64 dataURL 形式内置到产物中,无需额外加载资源。
11
+ */
12
+ interface CursorOptions {
13
+ /** 目标元素,未传则默认挂载到 document.body */
14
+ target?: HTMLElement;
15
+ /** 光标尺寸(像素),默认 64。热点固定为 size 的 1/8 */
16
+ size?: number;
17
+ }
18
+ /**
19
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
20
+ *
21
+ * 多次调用时,会先清理上一次的状态再重新绑定。
22
+ *
23
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听。
24
+ */
25
+ declare function enableCustomCursor(opts?: CursorOptions): () => void;
26
+ /**
27
+ * 关闭自定义鼠标指针,恢复默认光标。
28
+ */
29
+ declare function disableCustomCursor(): void;
30
+
3
31
  type InitCallbackType = (maxWidth: number, maxHeight: number) => void;
4
32
  /**
5
33
  * Main SDK class providing playable ad functionality and state management.
@@ -31,6 +59,7 @@ declare class sdk {
31
59
  * This must be called as earlier as possible.
32
60
  *
33
61
  * @param callback Optional function called when ad container is ready
62
+ * @param options Optional configuration options
34
63
  * @example
35
64
  * // Basic initialization
36
65
  * sdk.playcraftInit();
@@ -43,7 +72,9 @@ declare class sdk {
43
72
  * @fires playcraftInit When SDK initialization starts
44
73
  * @fires playcraftReady When game instance is created and ready to load resources
45
74
  */
46
- static playcraftInit(callback?: InitCallbackType): void;
75
+ static playcraftInit(callback?: InitCallbackType, options?: {
76
+ useCustomCursor?: boolean;
77
+ }): void;
47
78
  /**
48
79
  * Starts the playable ad experience.
49
80
  * Should be called after all resources are loaded and first frame is rendered.
@@ -251,6 +282,28 @@ declare class sdk {
251
282
  * console.log(config.primaryColor); // '#ff0000'
252
283
  */
253
284
  static getConfig(): Record<string, any>;
285
+ /**
286
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
287
+ * 悬浮显示手指图标,按下时切换为按压态图标。
288
+ * 多次调用会先清理上一次的状态再重新绑定。
289
+ *
290
+ * @param opts 可选配置
291
+ * - opts.target: 目标元素,未传则默认 document.body
292
+ * - opts.size: 光标尺寸(像素),默认 64,热点固定为 size 的 1/8
293
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听
294
+ *
295
+ * @example
296
+ * sdk.enableCustomCursor();
297
+ * sdk.enableCustomCursor({ size: 96 });
298
+ */
299
+ static enableCustomCursor(opts?: CursorOptions): () => void;
300
+ /**
301
+ * 关闭自定义鼠标指针,恢复默认光标。
302
+ *
303
+ * @example
304
+ * sdk.disableCustomCursor();
305
+ */
306
+ static disableCustomCursor(): void;
254
307
  }
255
308
 
256
309
  /**
@@ -270,32 +323,4 @@ declare function hideWechatGuide(): void;
270
323
  */
271
324
  declare function removeWechatGuide(): void;
272
325
 
273
- /**
274
- * 自定义鼠标指针模块。
275
- *
276
- * 默认挂载到 `document.body`,把整页的默认光标替换为内置的手指图标:
277
- * - 悬浮时显示 FingerHovering
278
- * - 按下时显示 FingerPressing
279
- *
280
- * 图片以 base64 dataURL 形式内置到产物中,无需额外加载资源。
281
- */
282
- interface CursorOptions {
283
- /** 目标元素,未传则默认挂载到 document.body */
284
- target?: HTMLElement;
285
- /** 光标尺寸(像素),默认 64。热点固定为 size 的 1/8 */
286
- size?: number;
287
- }
288
- /**
289
- * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
290
- *
291
- * 多次调用时,会先清理上一次的状态再重新绑定。
292
- *
293
- * @returns 清理函数,调用后会恢复默认光标并解除事件监听。
294
- */
295
- declare function enableCustomCursor(opts?: CursorOptions): () => void;
296
- /**
297
- * 关闭自定义鼠标指针,恢复默认光标。
298
- */
299
- declare function disableCustomCursor(): void;
300
-
301
326
  export { type CursorOptions, sdk as default, disableCustomCursor, enableCustomCursor, hideWechatGuide, removeWechatGuide, sdk, showWechatGuide };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,33 @@
1
1
  type EventName = 'playcraftInit' | 'playcraftReady' | 'playcraftStart' | 'playcraftInteractive' | 'playcraftInteraction' | 'playcraftChallengeStart' | 'playcraftChallengeProgress' | 'playcraftChallengeSuccess' | 'playcraftChallengeFailed' | 'playcraftResize' | 'playcraftPause' | 'playcraftResume' | 'playcraftVolume' | 'playcraftRetry' | 'playcraftFinish' | 'playcraftInstall';
2
2
 
3
+ /**
4
+ * 自定义鼠标指针模块。
5
+ *
6
+ * 默认挂载到 `document.body`,把整页的默认光标替换为内置的手指图标:
7
+ * - 悬浮时显示 FingerHovering
8
+ * - 按下时显示 FingerPressing
9
+ *
10
+ * 图片以 base64 dataURL 形式内置到产物中,无需额外加载资源。
11
+ */
12
+ interface CursorOptions {
13
+ /** 目标元素,未传则默认挂载到 document.body */
14
+ target?: HTMLElement;
15
+ /** 光标尺寸(像素),默认 64。热点固定为 size 的 1/8 */
16
+ size?: number;
17
+ }
18
+ /**
19
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
20
+ *
21
+ * 多次调用时,会先清理上一次的状态再重新绑定。
22
+ *
23
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听。
24
+ */
25
+ declare function enableCustomCursor(opts?: CursorOptions): () => void;
26
+ /**
27
+ * 关闭自定义鼠标指针,恢复默认光标。
28
+ */
29
+ declare function disableCustomCursor(): void;
30
+
3
31
  type InitCallbackType = (maxWidth: number, maxHeight: number) => void;
4
32
  /**
5
33
  * Main SDK class providing playable ad functionality and state management.
@@ -31,6 +59,7 @@ declare class sdk {
31
59
  * This must be called as earlier as possible.
32
60
  *
33
61
  * @param callback Optional function called when ad container is ready
62
+ * @param options Optional configuration options
34
63
  * @example
35
64
  * // Basic initialization
36
65
  * sdk.playcraftInit();
@@ -43,7 +72,9 @@ declare class sdk {
43
72
  * @fires playcraftInit When SDK initialization starts
44
73
  * @fires playcraftReady When game instance is created and ready to load resources
45
74
  */
46
- static playcraftInit(callback?: InitCallbackType): void;
75
+ static playcraftInit(callback?: InitCallbackType, options?: {
76
+ useCustomCursor?: boolean;
77
+ }): void;
47
78
  /**
48
79
  * Starts the playable ad experience.
49
80
  * Should be called after all resources are loaded and first frame is rendered.
@@ -251,6 +282,28 @@ declare class sdk {
251
282
  * console.log(config.primaryColor); // '#ff0000'
252
283
  */
253
284
  static getConfig(): Record<string, any>;
285
+ /**
286
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
287
+ * 悬浮显示手指图标,按下时切换为按压态图标。
288
+ * 多次调用会先清理上一次的状态再重新绑定。
289
+ *
290
+ * @param opts 可选配置
291
+ * - opts.target: 目标元素,未传则默认 document.body
292
+ * - opts.size: 光标尺寸(像素),默认 64,热点固定为 size 的 1/8
293
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听
294
+ *
295
+ * @example
296
+ * sdk.enableCustomCursor();
297
+ * sdk.enableCustomCursor({ size: 96 });
298
+ */
299
+ static enableCustomCursor(opts?: CursorOptions): () => void;
300
+ /**
301
+ * 关闭自定义鼠标指针,恢复默认光标。
302
+ *
303
+ * @example
304
+ * sdk.disableCustomCursor();
305
+ */
306
+ static disableCustomCursor(): void;
254
307
  }
255
308
 
256
309
  /**
@@ -270,32 +323,4 @@ declare function hideWechatGuide(): void;
270
323
  */
271
324
  declare function removeWechatGuide(): void;
272
325
 
273
- /**
274
- * 自定义鼠标指针模块。
275
- *
276
- * 默认挂载到 `document.body`,把整页的默认光标替换为内置的手指图标:
277
- * - 悬浮时显示 FingerHovering
278
- * - 按下时显示 FingerPressing
279
- *
280
- * 图片以 base64 dataURL 形式内置到产物中,无需额外加载资源。
281
- */
282
- interface CursorOptions {
283
- /** 目标元素,未传则默认挂载到 document.body */
284
- target?: HTMLElement;
285
- /** 光标尺寸(像素),默认 64。热点固定为 size 的 1/8 */
286
- size?: number;
287
- }
288
- /**
289
- * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
290
- *
291
- * 多次调用时,会先清理上一次的状态再重新绑定。
292
- *
293
- * @returns 清理函数,调用后会恢复默认光标并解除事件监听。
294
- */
295
- declare function enableCustomCursor(opts?: CursorOptions): () => void;
296
- /**
297
- * 关闭自定义鼠标指针,恢复默认光标。
298
- */
299
- declare function disableCustomCursor(): void;
300
-
301
326
  export { type CursorOptions, sdk as default, disableCustomCursor, enableCustomCursor, hideWechatGuide, removeWechatGuide, sdk, showWechatGuide };
package/dist/index.js CHANGED
@@ -542,6 +542,83 @@ function getConfig() {
542
542
  return _cachedConfig;
543
543
  }
544
544
 
545
+ // src/cursor.ts
546
+ var cleanup = null;
547
+ function toCursor(src, size) {
548
+ const hotspot = Math.round(size / 8);
549
+ return new Promise((resolve, reject) => {
550
+ const img = new Image();
551
+ img.onload = () => {
552
+ const c = document.createElement("canvas");
553
+ c.width = size;
554
+ c.height = size;
555
+ const ctx = c.getContext("2d");
556
+ if (!ctx) {
557
+ reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
558
+ return;
559
+ }
560
+ ctx.drawImage(img, 0, 0, size, size);
561
+ resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
562
+ };
563
+ img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
564
+ img.src = src;
565
+ });
566
+ }
567
+ function enableCustomCursor(opts = {}) {
568
+ var _a, _b;
569
+ cleanup == null ? void 0 : cleanup();
570
+ cleanup = null;
571
+ if (typeof document === "undefined") return () => {
572
+ };
573
+ const target = (_a = opts.target) != null ? _a : document.body;
574
+ if (!target) {
575
+ console.warn("[PlayableSDK] enableCustomCursor: target not found");
576
+ return () => {
577
+ };
578
+ }
579
+ const size = (_b = opts.size) != null ? _b : 64;
580
+ const prevCursor = target.style.cursor;
581
+ let disposed = false;
582
+ let down = null;
583
+ let up = null;
584
+ const dispose = () => {
585
+ if (disposed) return;
586
+ disposed = true;
587
+ target.style.cursor = prevCursor;
588
+ if (down) target.removeEventListener("pointerdown", down);
589
+ if (up) {
590
+ target.removeEventListener("pointerup", up);
591
+ target.removeEventListener("pointercancel", up);
592
+ }
593
+ if (cleanup === dispose) cleanup = null;
594
+ };
595
+ cleanup = dispose;
596
+ Promise.all([
597
+ toCursor(FINGER_HOVERING, size),
598
+ toCursor(FINGER_PRESSING, size)
599
+ ]).then(([hover, press]) => {
600
+ if (disposed) return;
601
+ target.style.cursor = hover;
602
+ down = () => {
603
+ target.style.cursor = press;
604
+ };
605
+ up = () => {
606
+ target.style.cursor = hover;
607
+ };
608
+ target.addEventListener("pointerdown", down);
609
+ target.addEventListener("pointerup", up);
610
+ target.addEventListener("pointercancel", up);
611
+ }).catch((err) => {
612
+ console.warn("[PlayableSDK] enableCustomCursor failed:", err);
613
+ dispose();
614
+ });
615
+ return dispose;
616
+ }
617
+ function disableCustomCursor() {
618
+ cleanup == null ? void 0 : cleanup();
619
+ cleanup = null;
620
+ }
621
+
545
622
  // src/core.ts
546
623
  var destinationUrl = "";
547
624
  var isSDKInitialized = false;
@@ -877,6 +954,7 @@ var _sdk = class _sdk {
877
954
  * This must be called as earlier as possible.
878
955
  *
879
956
  * @param callback Optional function called when ad container is ready
957
+ * @param options Optional configuration options
880
958
  * @example
881
959
  * // Basic initialization
882
960
  * sdk.playcraftInit();
@@ -889,12 +967,15 @@ var _sdk = class _sdk {
889
967
  * @fires playcraftInit When SDK initialization starts
890
968
  * @fires playcraftReady When game instance is created and ready to load resources
891
969
  */
892
- static playcraftInit(callback) {
970
+ static playcraftInit(callback, options) {
893
971
  if (isSDKInitialized) return;
894
972
  if (callback) initCallback = callback;
895
973
  initTrackingProtocols();
896
974
  document.readyState === "loading" ? window.addEventListener("DOMContentLoaded", initSDK) : initSDK();
897
975
  isSDKInitialized = true;
976
+ if ((options == null ? void 0 : options.useCustomCursor) !== false) {
977
+ enableCustomCursor();
978
+ }
898
979
  }
899
980
  /**
900
981
  * Starts the playable ad experience.
@@ -1287,9 +1368,35 @@ var _sdk = class _sdk {
1287
1368
  static getConfig() {
1288
1369
  return getConfig();
1289
1370
  }
1371
+ /**
1372
+ * 启用自定义鼠标指针。默认挂载到 `document.body`,作用于整个页面。
1373
+ * 悬浮显示手指图标,按下时切换为按压态图标。
1374
+ * 多次调用会先清理上一次的状态再重新绑定。
1375
+ *
1376
+ * @param opts 可选配置
1377
+ * - opts.target: 目标元素,未传则默认 document.body
1378
+ * - opts.size: 光标尺寸(像素),默认 64,热点固定为 size 的 1/8
1379
+ * @returns 清理函数,调用后会恢复默认光标并解除事件监听
1380
+ *
1381
+ * @example
1382
+ * sdk.enableCustomCursor();
1383
+ * sdk.enableCustomCursor({ size: 96 });
1384
+ */
1385
+ static enableCustomCursor(opts) {
1386
+ return enableCustomCursor(opts);
1387
+ }
1388
+ /**
1389
+ * 关闭自定义鼠标指针,恢复默认光标。
1390
+ *
1391
+ * @example
1392
+ * sdk.disableCustomCursor();
1393
+ */
1394
+ static disableCustomCursor() {
1395
+ disableCustomCursor();
1396
+ }
1290
1397
  };
1291
1398
  /** Current version of the SDK */
1292
- _sdk.version = "1.0.16";
1399
+ _sdk.version = "1.0.17";
1293
1400
  /** Current maximum width of the playable ad container in pixels */
1294
1401
  _sdk.maxWidth = Math.floor(window.innerWidth);
1295
1402
  /** Current maximum height of the playable ad container in pixels */
@@ -1315,83 +1422,6 @@ window["console"].log(
1315
1422
  "background: #e1e4e8; color: #333; font-size: 14px; padding: 4px 8px; border-top-right-radius: 4px; border-bottom-right-radius: 4px;"
1316
1423
  );
1317
1424
  window.PlayableSDK = sdk;
1318
-
1319
- // src/cursor.ts
1320
- var cleanup = null;
1321
- function toCursor(src, size) {
1322
- const hotspot = Math.round(size / 8);
1323
- return new Promise((resolve, reject) => {
1324
- const img = new Image();
1325
- img.onload = () => {
1326
- const c = document.createElement("canvas");
1327
- c.width = size;
1328
- c.height = size;
1329
- const ctx = c.getContext("2d");
1330
- if (!ctx) {
1331
- reject(new Error("[PlayableSDK] Failed to get 2d context for cursor"));
1332
- return;
1333
- }
1334
- ctx.drawImage(img, 0, 0, size, size);
1335
- resolve(`url(${c.toDataURL("image/png")}) ${hotspot} ${hotspot}, pointer`);
1336
- };
1337
- img.onerror = () => reject(new Error("[PlayableSDK] Failed to load cursor image"));
1338
- img.src = src;
1339
- });
1340
- }
1341
- function enableCustomCursor(opts = {}) {
1342
- var _a, _b;
1343
- cleanup == null ? void 0 : cleanup();
1344
- cleanup = null;
1345
- if (typeof document === "undefined") return () => {
1346
- };
1347
- const target = (_a = opts.target) != null ? _a : document.body;
1348
- if (!target) {
1349
- console.warn("[PlayableSDK] enableCustomCursor: target not found");
1350
- return () => {
1351
- };
1352
- }
1353
- const size = (_b = opts.size) != null ? _b : 64;
1354
- const prevCursor = target.style.cursor;
1355
- let disposed = false;
1356
- let down = null;
1357
- let up = null;
1358
- const dispose = () => {
1359
- if (disposed) return;
1360
- disposed = true;
1361
- target.style.cursor = prevCursor;
1362
- if (down) target.removeEventListener("pointerdown", down);
1363
- if (up) {
1364
- target.removeEventListener("pointerup", up);
1365
- target.removeEventListener("pointercancel", up);
1366
- }
1367
- if (cleanup === dispose) cleanup = null;
1368
- };
1369
- cleanup = dispose;
1370
- Promise.all([
1371
- toCursor(FINGER_HOVERING, size),
1372
- toCursor(FINGER_PRESSING, size)
1373
- ]).then(([hover, press]) => {
1374
- if (disposed) return;
1375
- target.style.cursor = hover;
1376
- down = () => {
1377
- target.style.cursor = press;
1378
- };
1379
- up = () => {
1380
- target.style.cursor = hover;
1381
- };
1382
- target.addEventListener("pointerdown", down);
1383
- target.addEventListener("pointerup", up);
1384
- target.addEventListener("pointercancel", up);
1385
- }).catch((err) => {
1386
- console.warn("[PlayableSDK] enableCustomCursor failed:", err);
1387
- dispose();
1388
- });
1389
- return dispose;
1390
- }
1391
- function disableCustomCursor() {
1392
- cleanup == null ? void 0 : cleanup();
1393
- cleanup = null;
1394
- }
1395
1425
  // Annotate the CommonJS export names for ESM import in node:
1396
1426
  0 && (module.exports = {
1397
1427
  disableCustomCursor,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@playcraft/adsdk",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "统一的 Playable SDK,支持 MRAID、Google、Facebook、Vungle、BigoAds 等多广告渠道",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/esm/index.js",