有个网站需要用到scratch图形化上传到网站上然后供用户来实时浏览游玩Scratch,Wordpress插件库里面只有个支持Scratch官网分享的链接来运行。但是国内是屏蔽了官网的。所以这个是不行的。就想办法来实现自建Scratch播放器来引用sb3文件浏览。大家有需要的可以拿去试试。
# 基于 Turbowarp 的 Scratch 播放器实现方案
## 项目概述
本项目实现了一个功能完善的 Scratch 项目播放器,基于 Turbowarp 引擎,支持全屏自适应布局、URL 参数加载、管理员配置面板,以及针对 WordPress 嵌入场景的键盘控制优化。播放器采用深色主题设计,具备内容防护功能,可安全地嵌入到网站中供用户使用。
## 核心特性
- ✅ **全屏自适应布局**:响应式设计,完美适配各种屏幕尺寸
- ✅ **URL 参数加载**:支持通过 `project_url` 参数直接加载 Scratch 项目
- ✅ **管理员模式**:可配置自动播放、Turbo 模式、FPS 等参数
- ✅ **键盘控制优化**:解决 WordPress 嵌入场景下的键盘焦点问题
- ✅ **状态实时显示**:播放状态徽章显示在播放器右上角
- ✅ **内容防护**:禁用右键菜单和常见保存快捷键
- ✅ **设置持久化**:使用 localStorage 保存用户偏好设置
## 技术架构
### 技术栈
- **前端框架**:纯 HTML/CSS/JavaScript(无依赖)
- **播放引擎**:Turbowarp.org Embed API
- **存储方案**:localStorage(用户设置)
- **布局方案**:Flexbox + CSS Grid
### 项目结构
```
scratch/
└── player/
└── embed.html # 播放器主文件
```
## 核心功能实现
### 1. 全屏自适应布局
播放器采用全屏布局设计,使用 Flexbox 实现响应式结构:
```css
html, body {
width: 100%;
height: 100%;
}
.shell {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
padding: clamp(16px, 4vw, 42px);
}
.player-shell {
flex: 1;
position: relative;
min-height: clamp(320px, 60vh, 800px);
}
#playerFrame {
width: 100%;
height: 100%;
border: 0;
}
```
关键点:
- 使用 `clamp()` 函数实现响应式尺寸
- `flex: 1` 让播放器区域占据剩余空间
- 100% 宽高确保完美填充容器
### 2. URL 参数加载机制
播放器支持通过 URL 参数直接加载项目:
```javascript
const qs = new URLSearchParams(location.search);
const initialUrl = qs.get('project_url');
if (initialUrl) {
input.value = initialUrl;
loadProject(initialUrl);
}
```
使用示例:
```
https://your-domain.com/player/embed.html?project_url=https://example.com/demo.sb3
```
### 3. Turbowarp 播放器构建
动态构建 Turbowarp 播放器 URL,支持多种参数:
```javascript
function buildPlayerSrc(url) {
const params = new URLSearchParams();
if (autoplayToggle.checked) params.set('autoplay', '');
if (turboToggle.checked) params.set('turbo', '');
const fps = Number(fpsInput.value) || 60;
params.set('fps', fps);
params.set('project_url', url);
return `${BASE_PLAYER}?${params.toString()}`;
}
```
支持的参数:
- `autoplay`:自动播放
- `turbo`:Turbo 模式(加速运行)
- `fps`:帧率设置(30-240)
- `project_url`:项目文件地址
### 4. 管理员模式
通过 URL 参数 `admin=1` 启用管理员面板:
```javascript
const isAdmin = qs.get('admin') === '1';
if (isAdmin) {
document.body.classList.add('admin-mode');
}
```
管理员功能:
- 项目地址输入框
- 自动播放开关
- Turbo 模式开关
- FPS 设置
- 重新载入按钮
- 复制分享链接
### 5. 状态显示系统
状态徽章显示在播放器右上角,实时反馈加载状态:
```css
#statusBadge {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
backdrop-filter: blur(6px);
box-shadow: 0 8px 24px rgba(0,0,0,0.35);
}
```
状态类型:
- `闲置`:初始状态
- `加载中…`:正在加载项目
- `播放中`(success):加载成功
- `错误`(error):加载失败
### 6. 键盘控制优化(WordPress 嵌入场景)
这是项目的核心难点。在 WordPress 文章中嵌入 iframe 时,键盘事件无法正常传递到播放器。我们实现了多层次的焦点管理方案:
#### 6.1 iframe 权限配置
```html
<iframe
id="playerFrame"
allow="autoplay; fullscreen; gamepad; keyboard-lock; pointer-lock"
allowfullscreen
tabindex="-1"
></iframe>
```
关键属性:
- `keyboard-lock`:允许键盘锁定
- `pointer-lock`:允许鼠标锁定
- `tabindex="-1"`:使 iframe 可通过编程方式获得焦点
#### 6.2 焦点管理机制
```javascript
function focusPlayerFrame() {
if (!player) return;
player.focus();
try {
player.contentWindow?.focus();
} catch (_) {
// 忽略跨域焦点问题
}
}
function primeKeyboardControl() {
keyboardPrimed = true;
hideKeyboardHint();
focusPlayerFrame();
}
```
#### 6.3 事件监听策略
监听多种用户交互事件,确保键盘控制能够激活:
```javascript
// 点击播放器区域时激活
playerShell?.addEventListener('pointerdown', primeKeyboardControl);
playerShell?.addEventListener('touchstart', primeKeyboardControl, { passive: true });
// 全局点击时激活
window.addEventListener('pointerdown', () => {
if (!keyboardPrimed) {
primeKeyboardControl();
}
});
// 键盘按下时激活并确保焦点
window.addEventListener('keydown', (event) => {
if (!keyboardPrimed) {
primeKeyboardControl();
return;
}
if (document.activeElement !== player) {
focusPlayerFrame();
event.preventDefault();
}
}, { capture: true });
```
#### 6.4 WordPress 集成方案
由于 WordPress 会过滤文章中的 `<script>` 标签,需要在主题层面添加支持代码。
**WordPress 文章嵌入代码:**
```html
<div class="scratch-player-embed" style="position: relative; padding-top: 56.25%; margin: 20px 0;">
<iframe
style="position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 16px; overflow: hidden;"
tabindex="-1"
title="Scratch 播放器"
src="https://your-domain.com/player/embed.html?project_url=https%3A%2F%2Fexample.com%2Fdemo.sb3&admin=0"
allowfullscreen="allowfullscreen"
allow="autoplay; fullscreen; gamepad; keyboard-lock; pointer-lock"
></iframe>
</div>
```
**主题 JavaScript 代码(添加到主题的 footer.php 或自定义 JS 文件):**
```javascript
document.addEventListener('pointerdown', e => {
const wrapper = e.target.closest('.scratch-player-embed');
if (!wrapper) return;
const iframe = wrapper.querySelector('iframe');
if (!iframe) return;
iframe.focus();
try {
iframe.contentWindow && iframe.contentWindow.focus();
} catch (_) {}
}, { passive: true });
```
这样,当用户在 WordPress 文章中点击播放器区域时,焦点会自动转移到 iframe,键盘控制即可正常工作。
### 7. 内容防护机制
为防止用户轻易获取项目资源地址,实现了基础防护:
```javascript
// 禁用右键菜单
window.addEventListener('contextmenu', e => e.preventDefault());
// 禁用常见保存快捷键
window.addEventListener('keydown', e => {
if ((e.ctrlKey || e.metaKey) && ['s','u','p','Shift','i','c'].includes(e.key.toLowerCase())) {
e.preventDefault();
}
if (e.key === 'F12') {
e.preventDefault();
}
});
```
注意:这只是基础防护,真正的资源地址仍然可以通过浏览器开发者工具获取。如需更强的防护,建议使用服务器端代理或 CDN 签名 URL。
### 8. 设置持久化
使用 localStorage 保存用户偏好设置:
```javascript
const LS_KEY = 'scratch-player-settings';
function persistSettings() {
const payload = {
autoplay: autoplayToggle.checked,
turbo: turboToggle.checked,
fps: fpsInput.value
};
localStorage.setItem(LS_KEY, JSON.stringify(payload));
}
function restoreSettings() {
try {
const saved = JSON.parse(localStorage.getItem(LS_KEY) || '{}');
if (typeof saved.autoplay === 'boolean') autoplayToggle.checked = saved.autoplay;
if (typeof saved.turbo === 'boolean') turboToggle.checked = saved.turbo;
if (saved.fps) fpsInput.value = saved.fps;
} catch (_) {
// 忽略损坏的存储
}
}
```
## 使用指南
### 基础使用
1. **直接访问**:将 `embed.html` 部署到服务器
2. **URL 参数加载**:
```
https://your-domain.com/player/embed.html?project_url=https://example.com/demo.sb3
```
3. **管理员模式**:
```
https://your-domain.com/player/embed.html?project_url=...&admin=1
```
### WordPress 集成步骤
1. **上传文件**:将 `embed.html` 上传到 WordPress 主题目录或自定义位置
2. **添加主题 JavaScript**:
- 编辑主题的 `footer.php` 或在自定义 JS 文件中添加焦点管理代码
- 或使用 WordPress 插件(如 "Insert Headers and Footers")添加代码
3. **在文章中使用**:
- 切换到"文本"或"自定义 HTML"编辑模式
- 插入提供的 HTML 代码
- 替换 `project_url` 为实际的 .sb3 文件地址
4. **URL 编码**:
- 确保 `project_url` 参数经过 URL 编码
- 例如:`https://example.com/demo.sb3` → `https%3A%2F%2Fexample.com%2Fdemo.sb3`
### WordPress 引用代码示例
#### 完整代码模板
**步骤 1:在 WordPress 主题中添加 JavaScript 支持**
将以下代码添加到主题的 `footer.php` 文件(在 `</body>` 标签之前),或使用 "Insert Headers and Footers" 插件添加到页脚:
```javascript
<script>
document.addEventListener('pointerdown', e => {
const wrapper = e.target.closest('.scratch-player-embed');
if (!wrapper) return;
const iframe = wrapper.querySelector('iframe');
if (!iframe) return;
iframe.focus();
try {
iframe.contentWindow && iframe.contentWindow.focus();
} catch (_) {}
}, { passive: true });
</script>
```
**步骤 2:在 WordPress 文章中使用**
在文章编辑器中切换到"文本"或"自定义 HTML"模式,插入以下代码:
```html
<div class="scratch-player-embed" style="position: relative; padding-top: 56.25%; margin: 20px 0;">
<iframe
style="position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 16px; overflow: hidden;"
tabindex="-1"
title="Scratch 播放器"
src="https://your-domain.com/player/embed.html?project_url=https%3A%2F%2Fyour-domain.com%2Fscratch%2Fdemo.sb3&admin=0"
allowfullscreen="allowfullscreen"
allow="autoplay; fullscreen; gamepad; keyboard-lock; pointer-lock"
loading="lazy"
></iframe>
</div>
```
#### 代码参数说明
**需要修改的部分:**
1. **播放器地址**:将 `https://your-domain.com/player/embed.html` 替换为你的实际播放器地址
2. **项目文件地址**:将 `https%3A%2F%2Fyour-domain.com%2Fscratch%2Fdemo.sb3` 替换为你的 .sb3 文件地址(需 URL 编码)
**URL 编码工具:**
可以使用在线工具或 JavaScript 进行编码:
```javascript
encodeURIComponent('https://your-domain.com/scratch/demo.sb3')
// 结果: https%3A%2F%2Fyour-domain.com%2Fscratch%2Fdemo.sb3
```
#### 实际使用示例
假设你的网站是 `https://3vf.cn`,项目文件在 `https://3vf.cn/scratch/tcs.sb3`,则完整代码如下:
```html
<div class="scratch-player-embed" style="position: relative; padding-top: 56.25%; margin: 20px 0;">
<iframe
style="position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 16px; overflow: hidden;"
tabindex="-1"
title="Scratch 播放器"
src="https://3vf.cn/player/embed.html?project_url=https%3A%2F%2F3vf.cn%2Fscratch%2Ftcs.sb3&admin=0"
allowfullscreen="allowfullscreen"
allow="autoplay; fullscreen; gamepad; keyboard-lock; pointer-lock"
loading="lazy"
></iframe>
</div>
```
#### 自定义尺寸
如果需要自定义播放器高度,可以修改 `padding-top` 值:
- **16:9 比例**(默认):`padding-top: 56.25%;`
- **4:3 比例**:`padding-top: 75%;`
- **固定高度**:将 `padding-top: 56.25%;` 改为 `height: 600px;` 或 `height: 80vh;`
示例(固定高度 600px):
```html
<div class="scratch-player-embed" style="position: relative; height: 600px; margin: 20px 0;">
<iframe
style="position: absolute; inset: 0; width: 100%; height: 100%; border: 0; border-radius: 16px; overflow: hidden;"
tabindex="-1"
title="Scratch 播放器"
src="https://your-domain.com/player/embed.html?project_url=..."
allowfullscreen="allowfullscreen"
allow="autoplay; fullscreen; gamepad; keyboard-lock; pointer-lock"
loading="lazy"
></iframe>
</div>
```
#### 启用管理员模式
如果需要显示管理员控制面板,将 URL 中的 `admin=0` 改为 `admin=1`:
```html
src="https://your-domain.com/player/embed.html?project_url=...&admin=1"
```
#### 注意事项
1. **WordPress 编辑器模式**:必须使用"文本"或"自定义 HTML"模式,可视化编辑器可能会过滤代码
2. **JavaScript 支持**:确保已在主题中添加了焦点管理的 JavaScript 代码
3. **跨域问题**:确保项目文件服务器允许跨域访问(CORS)
4. **文件格式**:项目文件必须是 `.sb3` 格式
5. **HTTPS**:建议使用 HTTPS 协议,某些浏览器功能需要安全上下文
### 参数说明
| 参数 | 说明 | 示例 |
|------|------|------|
| `project_url` | Scratch 项目文件地址(必需) | `https://example.com/demo.sb3` |
| `admin` | 启用管理员面板 | `1` 或 `0`(默认 `0`) |
管理员模式下可配置的参数:
- `autoplay`:自动播放(通过界面设置)
- `turbo`:Turbo 模式(通过界面设置)
- `fps`:帧率(通过界面设置,默认 60)
## 技术亮点
### 1. 响应式设计
使用 `clamp()` 函数实现流畅的响应式尺寸:
```css
font-size: clamp(26px, 4vw, 36px);
padding: clamp(16px, 4vw, 42px);
min-height: clamp(320px, 60vh, 800px);
```
### 2. 深色主题
采用 CSS 变量实现主题系统:
```css
:root {
color-scheme: dark;
--bg: #0d1117;
--panel: #161b22;
--accent: #2ea043;
--text: #f0f4f8;
}
```
### 3. 状态管理
使用事件驱动的方式管理播放器状态:
```javascript
player.addEventListener('load', () => {
setStatus('播放中', 'success');
focusPlayerFrame();
});
player.addEventListener('error', () => {
setStatus('加载失败', 'error');
messageEl.textContent = '播放器载入失败,请检查链接或稍后再试。';
messageEl.classList.add('error');
});
```
### 4. 用户体验优化
- 键盘提示:首次使用时显示提示信息
- 自动聚焦:加载完成后自动聚焦播放器
- 错误处理:友好的错误提示和状态反馈
- 设置记忆:自动保存和恢复用户偏好
## 浏览器兼容性
- ✅ Chrome/Edge(推荐)
- ✅ Firefox
- ✅ Safari
- ✅ 移动端浏览器
注意:某些旧版浏览器可能不支持 `clamp()` 函数,建议使用 PostCSS 或 Autoprefixer 进行兼容处理。
## 安全考虑
1. **内容安全策略(CSP)**:建议在服务器端设置适当的 CSP 头
2. **XSS 防护**:所有用户输入都经过 URL 编码处理
3. **跨域限制**:Turbowarp 需要从可信源加载项目文件
4. **资源保护**:基础防护无法完全阻止技术用户获取资源,建议使用服务器端代理
## 性能优化
1. **懒加载**:iframe 仅在需要时加载
2. **事件委托**:使用事件捕获减少事件监听器数量
3. **CSS 优化**:使用 `transform` 和 `opacity` 实现动画,避免重排
4. **存储优化**:仅保存必要的设置数据
## 常见问题
### Q: 键盘控制不工作?
A: 确保:
1. 已添加主题 JavaScript 代码
2. iframe 的 `allow` 属性包含 `keyboard-lock`
3. 用户已点击播放器区域激活焦点
### Q: 项目加载失败?
A: 检查:
1. `project_url` 是否正确且可访问
2. 服务器是否允许跨域访问(CORS)
3. 文件格式是否为 `.sb3`
### Q: 管理员面板不显示?
A: 确保 URL 中包含 `admin=1` 参数
### Q: 在移动端显示异常?
A: 检查 `viewport` meta 标签是否正确设置
## 未来改进方向
- [ ] 支持多个项目切换
- [ ] 添加项目预览图
- [ ] 实现播放历史记录
- [ ] 支持自定义主题
- [ ] 添加项目评分/评论功能
- [ ] 实现项目收藏功能
- [ ] 支持全屏模式切换
- [ ] 添加键盘快捷键提示
## 总结
本项目实现了一个功能完善、用户体验良好的 Scratch 播放器解决方案。通过精心设计的焦点管理机制,成功解决了 WordPress 嵌入场景下的键盘控制问题。代码结构清晰,易于维护和扩展,适合作为网站内容的一部分供用户使用。
## 许可证
本项目采用 MIT 许可证,可自由使用和修改。
---
本站https://ygz.ink文章https://ygz.ink/archives/3520.html中提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。本站部分信息来自博主网络收集整理,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解!
邮箱:gouweicaosheji@163.com
宗宗酱
