(function (global) { 'use strict'; /** * shell(按真机形态做 CSS 边框): * - classic Home 键(iPhone 8 / SE) * - notch 刘海(iPhone X~14 标准) * - island 灵动岛(iPhone 14 Pro 起) * - punch 居中挖孔(多数安卓) * - punchL 左上挖孔(部分三星/小米) * - teardrop 水滴(中端安卓) * - tablet 平板 * - tabletCam 平板+前摄 * - flat 无装饰框 */ var SHELL = { classic: { padX: 0.055, padY: 0.12, minPadX: 14, minPadY: 32, radius: 0.1 }, notch: { padX: 0.032, padY: 0.032, minPadX: 10, minPadY: 10, radius: 0.13 }, island: { padX: 0.028, padY: 0.028, minPadX: 10, minPadY: 10, radius: 0.14 }, punch: { padX: 0.022, padY: 0.022, minPadX: 8, minPadY: 8, radius: 0.11 }, punchL: { padX: 0.022, padY: 0.022, minPadX: 8, minPadY: 8, radius: 0.11 }, teardrop: { padX: 0.024, padY: 0.024, minPadX: 8, minPadY: 8, radius: 0.11 }, android: { padX: 0.022, padY: 0.022, minPadX: 8, minPadY: 8, radius: 0.11 }, tablet: { padX: 0.036, padY: 0.036, minPadX: 16, minPadY: 16, radius: 0.05 }, tabletCam: { padX: 0.036, padY: 0.036, minPadX: 16, minPadY: 16, radius: 0.05 }, flat: { padX: 0.018, padY: 0.018, minPadX: 6, minPadY: 6, radius: 0.08 }, }; /** 主流厂商代表性 / 较新机型(逻辑分辨率) */ var DEVICES = [ { id: 'fit', name: '适应窗口', w: 0, h: 0, frame: false, shell: 'flat', brand: '—' }, // —— Apple iPhone —— { id: 'iphone-se', name: 'iPhone SE 3', w: 375, h: 667, frame: true, shell: 'classic', brand: 'Apple' }, { id: 'iphone-8', name: 'iPhone 8', w: 375, h: 667, frame: true, shell: 'classic', brand: 'Apple' }, { id: 'iphone-x', name: 'iPhone X / XS', w: 375, h: 812, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-xr', name: 'iPhone XR / 11', w: 414, h: 896, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-12', name: 'iPhone 12 / 13', w: 390, h: 844, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-12p', name: 'iPhone 12 / 13 Pro', w: 390, h: 844, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-12pm', name: 'iPhone 12 / 13 Pro Max', w: 428, h: 926, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-14', name: 'iPhone 14', w: 390, h: 844, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-14-plus', name: 'iPhone 14 Plus', w: 428, h: 926, frame: true, shell: 'notch', brand: 'Apple' }, { id: 'iphone-14-pro', name: 'iPhone 14 Pro', w: 393, h: 852, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-14-promax', name: 'iPhone 14 Pro Max', w: 430, h: 932, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-15', name: 'iPhone 15 / 15 Plus', w: 393, h: 852, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-15-pro', name: 'iPhone 15 Pro', w: 393, h: 852, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-15-promax', name: 'iPhone 15 Pro Max', w: 430, h: 932, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-16', name: 'iPhone 16', w: 393, h: 852, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-16-pro', name: 'iPhone 16 Pro', w: 402, y: 0, h: 874, frame: true, shell: 'island', brand: 'Apple' }, { id: 'iphone-16-promax', name: 'iPhone 16 Pro Max', w: 440, h: 956, frame: true, shell: 'island', brand: 'Apple' }, // —— Apple iPad —— { id: 'ipad', name: 'iPad 10', w: 820, h: 1180, frame: true, shell: 'tabletCam', brand: 'Apple' }, { id: 'ipad-9', name: 'iPad 9', w: 768, h: 1024, frame: true, shell: 'classic', brand: 'Apple' }, { id: 'ipad-air', name: 'iPad Air', w: 820, h: 1180, frame: true, shell: 'tabletCam', brand: 'Apple' }, { id: 'ipad-pro', name: 'iPad Pro 11', w: 834, h: 1194, frame: true, shell: 'tabletCam', brand: 'Apple' }, { id: 'ipad-pro13', name: 'iPad Pro 12.9', w: 1024, h: 1366, frame: true, shell: 'tabletCam', brand: 'Apple' }, // —— Samsung —— { id: 'galaxy-s20', name: 'Galaxy S20', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Samsung' }, { id: 'galaxy-s21', name: 'Galaxy S21 / S22', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Samsung' }, { id: 'galaxy-s23', name: 'Galaxy S23 / S24', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Samsung' }, { id: 'galaxy-s24u', name: 'Galaxy S24 Ultra', w: 412, h: 915, frame: true, shell: 'punch', brand: 'Samsung' }, { id: 'galaxy-note20', name: 'Galaxy Note 20', w: 412, h: 915, frame: true, shell: 'punch', brand: 'Samsung' }, { id: 'galaxy-a54', name: 'Galaxy A54', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Samsung' }, // —— Google —— { id: 'pixel-5', name: 'Pixel 5', w: 393, h: 851, frame: true, shell: 'punch', brand: 'Google' }, { id: 'pixel-6', name: 'Pixel 6 / 7', w: 412, h: 915, frame: true, shell: 'punch', brand: 'Google' }, { id: 'pixel-8', name: 'Pixel 8 / 8 Pro', w: 412, h: 915, frame: true, shell: 'punch', brand: 'Google' }, // —— 小米 / Redmi —— { id: 'mi-13', name: '小米 13 / 14', w: 393, h: 873, frame: true, shell: 'punch', brand: 'Xiaomi' }, { id: 'mi-14-pro', name: '小米 14 Pro', w: 400, h: 882, frame: true, shell: 'punch', brand: 'Xiaomi' }, { id: 'redmi-note12', name: 'Redmi Note 12 / 13', w: 360, h: 800, frame: true, shell: 'teardrop', brand: 'Xiaomi' }, { id: 'redmi-k60', name: 'Redmi K60 / K70', w: 393, h: 873, frame: true, shell: 'punch', brand: 'Xiaomi' }, // —— 华为 / 荣耀 —— { id: 'huawei-mate60', name: 'Mate 60 Pro', w: 400, h: 880, frame: true, shell: 'punch', brand: 'Huawei' }, { id: 'huawei-p60', name: 'P60 / nova', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Huawei' }, { id: 'honor-magic6', name: '荣耀 Magic6', w: 360, h: 800, frame: true, shell: 'punch', brand: 'Honor' }, // —— OPPO / 一加 / realme —— { id: 'oppo-find', name: 'Find X6 / X7', w: 360, h: 800, frame: true, shell: 'punch', brand: 'OPPO' }, { id: 'oppo-reno', name: 'Reno 11', w: 360, h: 800, frame: true, shell: 'punch', brand: 'OPPO' }, { id: 'oneplus-12', name: '一加 12', w: 450, h: 1000, frame: true, shell: 'punch', brand: 'OnePlus' }, // —— vivo / iQOO —— { id: 'vivo-x100', name: 'vivo X100', w: 412, h: 915, frame: true, shell: 'punch', brand: 'vivo' }, { id: 'iqoo-12', name: 'iQOO 12', w: 393, h: 873, frame: true, shell: 'punch', brand: 'iQOO' }, // —— 其它常见分辨率 —— { id: 'android-360', name: 'Android 360×800', w: 360, h: 800, frame: true, shell: 'punch', brand: '通用' }, { id: 'android-412', name: 'Android 412×915', w: 412, h: 915, frame: true, shell: 'punch', brand: '通用' }, { id: 'android-720', name: '720×1280', w: 720, h: 1280, frame: true, shell: 'flat', brand: '通用' }, { id: 'android-1080', name: '1080×1920', w: 1080, h: 1920, frame: true, shell: 'flat', brand: '通用' }, { id: 'design', name: '设计分辨率', w: 750, h: 1600, frame: true, shell: 'island', brand: '通用' }, ]; /** * 设备预览:真实机型边框 + 画布铺满屏幕容器(无 CSS transform 缩放)。 * @constructor */ function DevicePreview() { this.deviceId = 'iphone-x'; this.rotated = false; this._capsuleOn = true; this._capsuleStyle = 'douyin'; this._stage = null; this._bezel = null; this._screen = null; this._cutout = null; this._homeBar = null; this._homeBtn = null; this._scaleLabel = null; this._center = null; this._applying = false; this._notifyTimer = 0; this._lastKey = ''; this._frameW = 0; this._frameH = 0; this._ro = null; this._onWinResize = this._onWinResize.bind(this); } DevicePreview.prototype.mount = function (centerEl, contentEl) { var stage = document.createElement('div'); stage.className = 'pw-device-stage'; stage.id = 'pw-device-stage'; var bezel = document.createElement('div'); bezel.className = 'pw-device-bezel'; bezel.id = 'pw-device-bezel'; bezel.innerHTML = '' + '' + '' + '' + '' + '
' + '' + '' + '
' + '' + ''; var scaleLabel = document.createElement('div'); scaleLabel.className = 'pw-device-scale'; scaleLabel.id = 'pw-device-scale'; stage.appendChild(bezel); stage.appendChild(scaleLabel); var screen = bezel.querySelector('#pw-device-screen'); // 内容与挖孔/胶囊同在 screen 内,保证位置相对屏幕 if (contentEl.parentNode) contentEl.parentNode.insertBefore(stage, contentEl); screen.insertBefore(contentEl, screen.firstChild); this._stage = stage; this._bezel = bezel; this._screen = screen; this._cutout = bezel.querySelector('#pw-device-cutout'); this._homeBar = bezel.querySelector('#pw-device-home-bar'); this._homeBtn = bezel.querySelector('#pw-device-home-btn'); this._capsule = bezel.querySelector('#pw-device-capsule'); this._scaleLabel = scaleLabel; this._center = centerEl; window.addEventListener('resize', this._onWinResize); if (typeof ResizeObserver !== 'undefined' && centerEl) { var self = this; this._ro = new ResizeObserver(function () { self.apply(true); }); this._ro.observe(centerEl); } return stage; }; DevicePreview.prototype._onWinResize = function () { this.apply(true); }; /** @returns {Array} */ DevicePreview.prototype.list = function () { return DEVICES.slice(); }; /** * @param {string} id */ DevicePreview.prototype.setDevice = function (id) { this.deviceId = id || 'iphone-x'; this.apply(false); try { localStorage.setItem('preview-workbench-device', this.deviceId); } catch (e) { /* */ } }; /** 微信/抖音等小程序右上角胶囊按钮开关 */ DevicePreview.prototype.setCapsule = function (on) { this._capsuleOn = !!on; if (this._capsule) { this._capsule.hidden = !this._capsuleOn; this._capsule.className = 'pw-device-capsule' + (this._capsuleOn ? ' show' : '') + ' cap-' + (this._capsuleStyle || 'wechat'); this._capsule.setAttribute('data-style', this._capsuleStyle || 'wechat'); } try { localStorage.setItem('preview-workbench-capsule', this._capsuleOn ? '1' : '0'); } catch (e) { /* */ } return this._capsuleOn; }; /** 胶囊样式:none=不显示;douyin 默认。wechat / wechat-dark 对齐微信官方菜单 */ DevicePreview.prototype.setCapsuleStyle = function (style) { var allow = { none: 1, douyin: 1, wechat: 1, 'wechat-dark': 1, alipay: 1, qq: 1, kuaishou: 1, bilibili: 1, }; this._capsuleStyle = allow[style] ? style : 'douyin'; // 「无」= 不显示;其它样式默认显示 if (this._capsuleStyle === 'none') { this._capsuleOn = false; } else { this._capsuleOn = true; } this.setCapsule(this._capsuleOn); if (this._capsule) { this._capsule.setAttribute('data-style', this._capsuleStyle); this._capsule.className = 'pw-device-capsule' + ((this._capsuleOn && this._capsuleStyle !== 'none') ? ' show' : '') + ' cap-' + this._capsuleStyle; } try { localStorage.setItem('preview-workbench-capsule-style', this._capsuleStyle); } catch (e) { /* */ } return this._capsuleStyle; }; DevicePreview.prototype.getCapsuleStyle = function () { return this._capsuleStyle || 'douyin'; }; DevicePreview.prototype.isCapsule = function () { return !!this._capsuleOn && this._capsuleStyle !== 'none'; }; DevicePreview.capsuleStyles = function () { return [ { id: 'none', name: '无' }, { id: 'douyin', name: '抖音' }, { id: 'wechat', name: '微信·浅' }, { id: 'wechat-dark', name: '微信·深' }, { id: 'alipay', name: '支付宝' }, { id: 'qq', name: 'QQ' }, { id: 'kuaishou', name: '快手' }, { id: 'bilibili', name: 'B站' }, ]; }; DevicePreview.prototype.toggleRotate = function () { this.rotated = !this.rotated; this.apply(false); return this.rotated; }; DevicePreview.prototype._find = function () { for (var i = 0; i < DEVICES.length; i++) { if (DEVICES[i].id === this.deviceId) return DEVICES[i]; } return DEVICES[3]; }; DevicePreview.prototype._shellOf = function (d) { var key = (d && d.shell) || 'island'; return SHELL[key] || SHELL.island; }; /** * 安全区(逻辑分辨率单位,与 w/h 同一坐标系)。 * 供 Cocos SafeArea / getSafeAreaEdge 使用。 */ DevicePreview.prototype._safeOf = function (d) { if (d && d.safe) { return { top: d.safe.top || 0, bottom: d.safe.bottom || 0, left: d.safe.left || 0, right: d.safe.right || 0, }; } var shell = (d && d.shell) || 'island'; var h = (d && d.h) || 812; var w = (d && d.w) || 375; // 以 iPhone 点值为基准按高度比例换算 var s = h / 852; if (shell === 'island') { return { top: Math.round(59 * s), bottom: Math.round(34 * s), left: 0, right: 0 }; } if (shell === 'notch') { return { top: Math.round(47 * s), bottom: Math.round(34 * s), left: 0, right: 0 }; } if (shell === 'classic') { return { top: 20, bottom: 0, left: 0, right: 0 }; } if (shell === 'punch' || shell === 'punchL' || shell === 'android') { return { top: Math.round(28 * s), bottom: Math.round(16 * s), left: 0, right: 0 }; } if (shell === 'teardrop') { return { top: Math.round(24 * s), bottom: Math.round(12 * s), left: 0, right: 0 }; } if (shell === 'tablet' || shell === 'tabletCam') { return { top: 24, bottom: 20, left: 0, right: 0 }; } return { top: 0, bottom: 0, left: 0, right: 0 }; }; /** 把安全区注入引擎,供 cc.SafeArea / view.getSafeAreaEdge 使用 */ DevicePreview.prototype._applySafeArea = function () { var cc = global.cc; if (!cc) return; var d = this._find(); var safe = this._safeOf(d); if (this.rotated) { // 横屏:上下安全区对应侧边 safe = { top: 0, bottom: 0, left: this._safeOf(d).bottom, right: 0, }; // 保持 notch/island 在横屏左侧时的上/左边距 var base = this._safeOf(d); safe = { top: 0, bottom: 0, left: base.bottom || 0, right: base.top || 0 }; } this._safeEdge = safe; var applyEdge = function () { return { top: safe.top, bottom: safe.bottom, left: safe.left, right: safe.right, }; }; try { if (cc.view) { cc.view.getSafeAreaEdge = applyEdge; if (typeof cc.view.getSafeAreaRect === 'function') { var origRect = cc.view.getSafeAreaRect; cc.view.getSafeAreaRect = function () { var vs = cc.view.getVisibleSize ? cc.view.getVisibleSize() : { width: 0, height: 0 }; var origin = cc.view.getVisibleOrigin ? cc.view.getVisibleOrigin() : { x: 0, y: 0 }; var e = applyEdge(); // 逻辑点:与设计分辨率同一尺度(view 一般用设计/可见单位) return { x: origin.x + e.left, y: origin.y + e.bottom, width: Math.max(1, vs.width - e.left - e.right), height: Math.max(1, vs.height - e.top - e.bottom), contains: origRect ? undefined : undefined, }; }; } } // 部分机型走 screen.safeAreaEdge if (global.screen && global.screen.safeAreaEdge !== undefined) { global.screen.safeAreaEdge = applyEdge(); } } catch (e) { /* */ } // 胶囊:贴齐安全区右上 if (this._capsule) { var capTop = Math.max(6, safe.top + 6); this._capsule.style.top = capTop + 'px'; this._capsule.style.right = '10px'; } }; /** * @param {string} shell * @param {boolean} useFrame * @param {boolean} landscape */ DevicePreview.prototype._applyShellClass = function (shell, useFrame, landscape) { var bezel = this._bezel; bezel.className = 'pw-device-bezel'; if (!useFrame) { bezel.classList.add('no-frame'); return; } bezel.classList.add('pw-shell-' + shell); if (landscape) bezel.classList.add('is-landscape'); if (shell === 'notch' && !landscape) bezel.classList.add('has-cutout', 'has-notch'); if (shell === 'island' && !landscape) bezel.classList.add('has-cutout', 'has-island'); if ((shell === 'punch' || shell === 'android') && !landscape) { bezel.classList.add('has-cutout', 'has-punch'); } if (shell === 'punchL' && !landscape) bezel.classList.add('has-cutout', 'has-punch', 'has-punch-l'); if (shell === 'teardrop' && !landscape) bezel.classList.add('has-cutout', 'has-teardrop'); if (shell === 'classic') bezel.classList.add('has-home-btn'); if (shell === 'notch' || shell === 'island' || shell === 'tablet' || shell === 'tabletCam') { bezel.classList.add('has-home-bar'); } if (shell === 'tabletCam' && !landscape) bezel.classList.add('has-tablet-cam'); }; /** * @param {number} w * @param {number} h */ DevicePreview.prototype._fillScreen = function (w, h) { if (this._screen) { this._screen.style.width = w + 'px'; this._screen.style.height = h + 'px'; } var gameDiv = document.getElementById('GameDiv'); var content = document.getElementById('content'); var wrap = content ? content.querySelector('.contentWrap') : null; var container = document.getElementById('Cocos3dGameContainer'); var canvas = document.getElementById('GameCanvas'); var list = [content, wrap, gameDiv, container, canvas]; for (var i = 0; i < list.length; i++) { var el = list[i]; if (!el) continue; el.style.setProperty('width', '100%', 'important'); el.style.setProperty('height', '100%', 'important'); el.style.setProperty('max-width', 'none', 'important'); el.style.setProperty('max-height', 'none', 'important'); el.style.margin = '0'; } if (gameDiv) { gameDiv.style.position = 'relative'; gameDiv.style.overflow = 'hidden'; } this._frameW = w; this._frameH = h; }; /** * @param {boolean} [fromWindowResize] */ DevicePreview.prototype.apply = function (fromWindowResize) { if (this._applying) return; var d = this._find(); if (!this._bezel || !this._stage || !this._screen) return; this._applying = true; try { var logicW = d.w; var logicH = d.h; if (this.rotated && logicW && logicH) { var swap = logicW; logicW = logicH; logicH = swap; } var useFrame = !!d.frame && logicW > 0 && logicH > 0; var shellKey = d.shell || 'island'; var shell = this._shellOf(d); this._applyShellClass(shellKey, useFrame, !!this.rotated); var stageW = this._center ? this._center.clientWidth : window.innerWidth; var stageH = this._center ? this._center.clientHeight : window.innerHeight; var pad = useFrame ? 48 : 12; var availW = Math.max(120, stageW - pad); var availH = Math.max(120, stageH - pad); var screenW; var screenH; if (!logicW || !logicH) { screenW = Math.floor(availW); screenH = Math.floor(availH); this._bezel.style.padding = '0'; this._bezel.style.width = screenW + 'px'; this._bezel.style.height = screenH + 'px'; this._bezel.style.borderRadius = '0'; if (this._scaleLabel) this._scaleLabel.textContent = '适应窗口 ' + screenW + '×' + screenH; } else { var padX0 = Math.max(shell.minPadX, logicW * shell.padX); var padY0 = Math.max(shell.minPadY, logicH * shell.padY); if (this.rotated && shellKey === 'classic') { // 横屏经典机:左右加宽留给 Home 键区域感 padX0 = Math.max(shell.minPadY, logicW * shell.padY * 0.55); padY0 = Math.max(shell.minPadX, logicH * shell.padX); } var totalW0 = logicW + padX0 * 2; var totalH0 = logicH + padY0 * 2; var fit = Math.min(availW / totalW0, availH / totalH0, 1); screenW = Math.max(80, Math.floor(logicW * fit)); screenH = Math.max(80, Math.floor(logicH * fit)); var bezelPadX = Math.max(8, Math.floor(padX0 * fit)); var bezelPadY = Math.max(8, Math.floor(padY0 * fit)); var radius = Math.max(12, Math.floor(Math.min(screenW, screenH) * shell.radius)); var screenRadius = Math.max(6, Math.floor(radius * 0.72)); this._bezel.style.padding = bezelPadY + 'px ' + bezelPadX + 'px'; this._bezel.style.width = (screenW + bezelPadX * 2) + 'px'; this._bezel.style.height = (screenH + bezelPadY * 2) + 'px'; this._bezel.style.borderRadius = radius + 'px'; this._screen.style.borderRadius = screenRadius + 'px'; this._bezel.style.setProperty('--pw-shell-r', radius + 'px'); this._bezel.style.setProperty('--pw-screen-r', screenRadius + 'px'); this._bezel.style.setProperty('--pw-bezel-x', bezelPadX + 'px'); this._bezel.style.setProperty('--pw-bezel-y', bezelPadY + 'px'); if (this._scaleLabel) { this._scaleLabel.textContent = d.name + (this.rotated ? '(横屏)' : '(竖屏)') + ' ' + screenW + '×' + screenH + (fit < 1 ? ' · ' + Math.round(fit * 100) + '%' : ''); } } this._bezel.style.transform = 'none'; this._fillScreen(screenW, screenH); this._applySafeArea(); var key = this.deviceId + '|' + (this.rotated ? 1 : 0) + '|' + screenW + 'x' + screenH + '|' + stageW + 'x' + stageH; var changed = key !== this._lastKey; this._lastKey = key; if (changed || !fromWindowResize) this._scheduleEngineNotify(); } finally { this._applying = false; } }; DevicePreview.prototype._scheduleEngineNotify = function () { var self = this; if (this._notifyTimer) clearTimeout(this._notifyTimer); this._notifyTimer = setTimeout(function () { self._notifyTimer = 0; self._notifyEngine(); }, 50); }; DevicePreview.prototype._notifyEngine = function () { var screen = this._screen; var w = screen ? screen.clientWidth : this._frameW; var h = screen ? screen.clientHeight : this._frameH; if (!w || !h) { w = this._frameW; h = this._frameH; } if (!w || !h) return; this._frameW = w; this._frameH = h; this._applySafeArea(); var cc = global.cc; try { if (cc && cc.view) { if (typeof cc.view.resizeWithBrowserSize === 'function') { cc.view.resizeWithBrowserSize(false); } if (typeof cc.view.setFrameSize === 'function') { cc.view.setFrameSize(w, h); } var dr = null; if (typeof cc.view.getDesignResolutionSize === 'function') { dr = cc.view.getDesignResolutionSize(); } if (dr && dr.width > 0 && dr.height > 0 && typeof cc.view.setDesignResolutionSize === 'function') { var policy = null; if (typeof cc.view.getResolutionPolicy === 'function') { policy = cc.view.getResolutionPolicy(); } if (policy != null) { cc.view.setDesignResolutionSize(dr.width, dr.height, policy); } else if (cc.ResolutionPolicy && cc.ResolutionPolicy.SHOW_ALL != null) { cc.view.setDesignResolutionSize(dr.width, dr.height, cc.ResolutionPolicy.SHOW_ALL); } else { cc.view.setDesignResolutionSize(dr.width, dr.height); } } if (typeof cc.view.emit === 'function') { try { cc.view.emit('canvas-resize'); } catch (e1) { /* */ } } } window.dispatchEvent(new CustomEvent('pw-device-resized', { detail: { width: w, height: h } })); } catch (e) { console.warn('[调试工作台] 通知引擎尺寸失败', e); } }; DevicePreview.prototype.restore = function () { try { var id = localStorage.getItem('preview-workbench-device'); if (id) this.deviceId = id; var capStyle = localStorage.getItem('preview-workbench-capsule-style'); this._capsuleStyle = capStyle || 'douyin'; // 默认显示抖音;仅样式为 none 时隐藏 this._capsuleOn = this._capsuleStyle !== 'none'; if (this._capsule) { this._capsule.hidden = !this._capsuleOn; this._capsule.setAttribute('data-style', this._capsuleStyle); this._capsule.className = 'pw-device-capsule' + (this._capsuleOn ? ' show' : '') + ' cap-' + this._capsuleStyle; } } catch (e) { /* */ } }; /** * 隐藏官方预览工具栏。 * @returns {HTMLSelectElement|null} */ DevicePreview.hideOfficialToolbar = function () { var root = document.getElementById('pw-root'); var el = document.body.firstElementChild; while (el && el !== root) { var next = el.nextElementSibling; if (el.tagName !== 'SCRIPT' && el.tagName !== 'STYLE' && el.tagName !== 'LINK') { el.classList.add('pw-official-toolbar-hidden'); el.setAttribute('aria-hidden', 'true'); } el = next; } return document.querySelector('.pw-official-toolbar-hidden select, #toolbar select, .toolbar select'); }; global.PWDevicePreview = DevicePreview; })(window);