Easy Scratch封装了如上传、加载、菜单配置、云变量接口、自定义素材库等常用的功能。只需简单js基础,即可轻松对接到平台上。You can easy embed scratch to your website with config and javascript
Go to file
2023-10-10 21:51:14 +08:00
doc tiny bug 2021-02-02 18:08:58 +08:00
docs 同步至官方2020-02-29 2020-02-29 15:03:56 +08:00
src 云变量配置 2023-10-10 21:51:14 +08:00
static 更新素材库 2021-09-08 18:39:37 +08:00
test 同步至官方2020-02-29 2020-02-29 15:03:56 +08:00
.babelrc 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.browserslistrc 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.editorconfig 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.eslintignore 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.eslintrc.js 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.gitattributes 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.gitignore 同步至官方2020-02-29 2020-02-29 15:03:56 +08:00
.npmignore 同步到官方#20191231 2019-12-31 17:48:57 +08:00
.travis.yml 同步到官方#20191231 2019-12-31 17:48:57 +08:00
INIT init 2019-12-30 16:02:12 +08:00
LICENSE 同步到官方#20191231 2019-12-31 17:48:57 +08:00
package.json scratch-l10n 2021-09-17 18:51:54 +08:00
prune-gh-pages.sh 同步到官方#20191231 2019-12-31 17:48:57 +08:00
README-EN.md 云变量接口 2023-10-09 15:52:31 +08:00
README-RAW.md 更新文档 2020-01-20 14:34:17 +08:00
README.md 云变量接口 2023-10-09 15:52:31 +08:00
TRADEMARK 同步到官方#20191231 2019-12-31 17:48:57 +08:00
webpack.config.js 书包对接API 2023-07-28 13:19:57 +08:00
webpack.prod.js tpl rename 2021-03-23 19:47:21 +08:00
yarn.lock scratch-l10n 2021-09-17 18:51:54 +08:00

English | 简体中文

项目介绍

使用本项目不需要关注Scratch3.0功能的具体实现只需要简单的js基础即可调用Scratch的相关功能助力项目快速开发。

可以实现的功能

  • 加载项目
  • 上传项目
  • 修改外观
  • 移动端播放器
  • 修改积木大小
  • 显示隐藏积木
  • 自定义素材库
  • 对接背包API
  • And more……

使用案例

开源Teaching在线教学系统便是使用的本项目可以参考具体示例

官网:http://teaching.vip

开源地址:http://github.com/open-scratch/teaching-open

二次开发

  • 安装依赖 npm install

  • 调试 npm start

  • 编译正式版 npm run build:prod

建议在Linux环境下编译开发若windows下编译遇到问题可参见

https://www.213.name/archives/1739

参与本项目

欢迎提交Issues和PR

快速使用

直接使用本DEMO

编译后直接修改index.html和player.html中的配置即可使用

引入到自己的页面

不使用DEMO引入到自己的页面

页面引入lib.min.jschunks/gui.jsscratch将自动渲染至<div id="scratch"></div>内。

别忘了配置 window.scratchConfig

项目文档

初始化配置

初始化配置均通过window.scratchConfig对象完成

需要注意的是需要在引入lib.min.js之前就加入该代码即Scratch主程序加载前就需要定义该配置

以下是完整示例:

    window.scratchConfig = {
      session: {
        token: "", // 用户Token
        username: "Username" //用户名
      },
      backpack:{
        enable: true, // 是否启用背包
        api: "/api/teaching/scratch/backpack", //背包API接口
      },
      cloudData:{
        enable: true, //是否开启云变量功能
        id: "create", //默认云变量ID可使用window.scratch.setCloudId更换ID
        api: "127.0.0.1:1234/api/websocket/scratch/cloudData" //云变量API地址
      },
      projectInfo: {//作品信息
        projectName: "",
        authorUsername: "admin",
        authorAvatar: './static/avatar.png',
      },
      logo: {
        show: true, //是否显示
        url: "./static/logo.png", //logo地址支持base64图片
        handleClickLogo: () => { //处理LOGO点击事件
        }
      },
      menuBar: {
        //菜单栏样式
        style: {
          background: 'hsla(215, 100%, 65%, 1)',
        },
        //切换语言按钮
        languageButton:{
          show: true, //是否显示
          defaultLanguage: 'zh-cn' //默认语言 en zh-cn zh-tw
        },
        //新建按钮
        newButton:{
          show: true, //是否显示
          handleBefore(){
            //拦截点击事件返回true继续执行
            return true
          }
        },
        //从计算机加载按钮
        loadFileButton:{
          show: true, //是否显示
          handleBefore(){
            //拦截点击事件返回true继续执行
            return true
          }
        },
        //保存到计算机按钮
        saveFileButton:{
          show: true, //是否显示
          handleBefore(){
            //拦截点击事件返回true继续执行
            return true
          }
        },
        //加速模式按钮
        turboModeButton:{
          show: true //是否显示
        },
        //教程按钮
        helpButton:{
          show: true, //是否显示
          handleBefore:()=>{
            //拦截点击事件返回true继续执行
            return true
          }
        },
        //我的物品按钮
        myStuff:{
          show: true, //是否显示
          url: '/myProject' //跳转的连接
        },
        //用户头像按钮
        userAvatar:{
          show: true, //是否显示
          username: '未登录', //用户名
          avatar: './static/avatar.png', //用户头像
          handleClick(){
            //点击头像,可以弹出登录框等操作
          }
        },
        //自定义按钮
        customButtons: [
          {
            show: true, //是否显示
            buttonName: '分享', //按钮名
            style:{ //按钮样式
              color: 'white',
              background: 'hsla(30, 100%, 55%, 1)',
            },
            handleClick:()=>{ //按钮事件
              console.log("自定义按钮1");
              console.log('分享按钮')
              window.scratch.getProjectCover(cover => {
                //TODO 获取到作品截图
              })
              window.scratch.getProjectFile(file => {
                //TODO 获取到项目文件
              })
              // 获取到项目名
              var projectName = window.scratch.getProjectName()
              console.log(projectName);
            }
          },
          //可继续新增按钮
        ]
      }, 
      blocks:{
         // 积木缩放比例
        scale: 0.8,
        // 隐藏分类 费雷见README附录
        // 如需动态隐藏显示分类或积木,修改此配置后需手动执行 window.vm.emitWorkspaceUpdate()
        hideCatagorys:[], 
        //隐藏积木 积木代码见README附录
        hideBlocks:[],
      },
      stageArea:{ //舞台设置
        fullscreenButton:{ //全屏按钮
          show: true,
          handleBeforeSetStageUnFull(){ //拦截退出全屏返回true继续执行
            return true
          },
          handleBeforeSetStageFull(){ //拦截全屏返回true继续执行
            return true
          }
        },
        startButton:{ //开始按钮
          show: true,
          handleBeforeStart(){ //拦截开始按钮返回true继续执行
            return true
          }
        },
        stopButton:{ // 停止按钮
          show: true,
          handleBeforeStop(){ //拦截停止按钮返回true继续执行
            return true
          }
        }
      },
      //scratch vm初始化完毕
      handleVmInitialized: (vm) => {
        window.vm = vm
      },
      //作品加载完毕
      handleProjectLoaded:() => {
      },
      //默认作品加载完毕
      handleDefaultProjectLoaded:() => {
      },
      //默认项目地址,不需要修请删除本配置项
      defaultProjectURL: "./static/project.sb3",
      //素材库配置
      assets:{
        //附Scratch素材库采集和处理工具 https://github.com/open-scratch/scratch-asset-utils
        //素材库地址,默认为/static下的素材库
        assetHost: './static',
        //素材库索引地址
        defaultIndex:{
          sprites: "./static/json_index/sprites.json",
          costumes: "./static/json_index/costumes.json",
          backdrops: "./static/json_index/backdrops.json",
          sounds: "./static/json_index/sounds.json"
        },
        //拦截角色库打开
        handleBeforeSpriteLibraryOpen(){
          console.log("角色库打开")
          //追加素材库
          // window.scratch.pushSpriteLibrary(Arrays)
          return true;
        },
        //拦截造型库打开
        handleBeforeCostumesLibraryOpen(){
          return true;
        },
        //拦截背景库打开
        handleBeforeBackdropsLibraryOpen(){
          return true;
        },
        //拦截声音库打开
        handleBeforeSoundLibraryOpen(){
          return true;
        }
      },
    }

API

ScratchVm对象

scratch-vm实例化的对象可以从外部直接操作部分scratch-vm虚拟机功能

该对象常用API列表

  • vm.saveProjectSb3() //获取SB3格式项目
  • vm.loadProject(file) //加载SB3项目
  • vm.greenFlag() //点击小绿旗
  • vm.stopAll() //停止运行项目
  • vm.emitWorkspaceUpdate() //刷新工作区
  • ……

Scratch-vm介绍

Scratch-vm官方文档

加载项目

window.scratch.loadProject(url, callback)

也可以使用vm对象的loadProject方法载入scratch项目

示例

window.scratch.loadProject(url, ()=>{
    //加载文件完成后的操作
})

获取项目文件

window.scratch.getProjectFile(callback)

也可以使用vm对象的saveProjectSb3方法

示例

window.scratch.getProjectFile((file)=>{
    console.log(file)
    //上传file文件
})

获取项目截图

window.scratch.getProjectCover(callback)

示例

window.scratch.getProjectCover((file)=>{
    console.log(file)
    //上传截图文件
})

获取项目名称

window.scratch.getProjectName()

设置项目名称

window.scratch.setProjectName(projectName)

设置为仅播放模式

示例

window.scratch.setPlayerOnly(true)

设置为全屏

示例

window.scratch.setFullScreen(true)

追加素材库

可以动态新增素材库索引,需要等待用户打开素材库后再调用本方法,否则无法追加成功。 增加索引后还需要assetHost中增加对应的素材文件。

参数为素材索引的数组具体格式参见json_index下文件的内容。

追加角色库

window.scratch.pushSpritesLibrary(Arrays)

追加造型库

window.scratch.pushCostumesLibrary(Arrays)

追加背景库

window.scratch.pushBackdropsLibrary(Arrays)

追加声音库

window.scratch.pushSoundsLibrary(Arrays)

示例

window.scratch.pushSoundsLibrary(
  [{
        "name": "自定义声音",
        "tags": [
            "music",
        ],
        "assetId": "5cb46ddd903fc2c9976ff881df9273c9",
        "dataFormat": "",
        "md5ext": "5cb46ddd903fc2c9976ff881df9273c9.wav",
        "sampleCount": 11840,
        "rate": 44100
    }]
)

设置云变量ID

window.scratch.setCloudId(id)

附录

Scratch项目结构

各个模块

scratch-vm 虚拟机

解析加载序列化项目文件、扩展功能实现、根据相应事件渲染舞台

scratch-audio 声音引擎

解析、播放声音

scratch-blocks 代码积木块

创建积木操作块区域和每个积木对应的代码

scratch-l10n 国际化

多语言支持

scratch-paint 画图引擎

图片编辑器

scratch-render

舞台渲染

scratch-storage 存储引擎

项目和对应素材的存储加载

scratch-svg-renderer

svg文件处理

项目结构

├── build                    # 编译后的文件夹
│   ├── static               # 静态资源
│   ├── chunks               # scratch核心加载器
│   ├── index.html           # scratch编辑器
│   ├── player.html          # scratch播放器
│   ├── lib.min.js           # scratch核心
├── src
│   ├── components           # UI组件
│   ├── containers           # 容器组件,承载容器组件业务逻辑
│   ├── css                  # 全局通用css
│   ├── examples             # 集成测试用例
│       ├── extensions       # 拓展案例
│   ├── lib                  # 插件及高阶组件
│       ├── audio            # 声音插件
│       ├── backpack         # 背包插件
│       ├── default-project  # 默认项目
│       ├── libraries        # 素材库相关
│       ├── video            # 视频模块
│   ├── playground           # 编译后页面的模版
│   ├── reducers             # 全局状态控制
├── test                     # 测试用例
├── translations             # 翻译库
├── README.md
├── README-RAW.md            #
└── package.json
└── webpack.config.js
└── webpack.prod.js

积木分类代码

motion looks sound events control sensing operators variables myBlocks

积木代码

运动分类

motion_movesteps motion_turnright motion_turnleft motion_goto motion_gotoxy motion_glideto motion_glidesecstoxy motion_pointindirection motion_pointtowards motion_changexby motion_setx motion_changeyby motion_sety motion_ifonedgebounce motion_setrotationstyle motion_xposition motion_yposition motion_direction

外观分类

looks_sayforsecs looks_say looks_thinkforsecs looks_think looks_switchbackdropto looks_switchbackdroptoandwait looks_nextbackdrop looks_switchcostumeto looks_nextcostume looks_switchbackdropto looks_nextbackdrop looks_changesizeby looks_setsizeto looks_changeeffectby looks_seteffectto looks_cleargraphiceffects looks_show looks_hide looks_gotofrontback looks_goforwardbackwardlayers looks_backdropnumbername looks_costumenumbername looks_backdropnumbername looks_size

声音分类

sound_playuntildone sound_play sound_stopallsounds sound_changeeffectby sound_seteffectto sound_cleareffects sound_changevolumeby sound_setvolumeto sound_volume

事件分类

event_whenflagclicked event_whenkeypressed event_whenstageclicked event_whenthisspriteclicked event_whenbackdropswitchesto event_whengreaterthan event_whenbroadcastreceived event_broadcast event_broadcastandwait

控制分类

control_wait control_repeat control_forever control_if control_if_else control_wait_until control_repeat_until control_stop control_create_clone_of control_start_as_clone control_create_clone_of control_delete_this_clone

侦测分类

sensing_touchingobject sensing_touchingcolor sensing_coloristouchingcolor sensing_distanceto sensing_askandwait sensing_answer sensing_keypressed sensing_mousedown sensing_mousex sensing_mousey sensing_setdragmode sensing_loudness sensing_timer sensing_resettimer sensing_of sensing_current sensing_dayssince2000 sensing_username

运算分类

operator_add operator_subtract operator_multiply operator_divide operator_random operator_gt operator_lt operator_equals operator_and operator_or operator_not operator_join operator_letter_of operator_length operator_contains operator_mod operator_round operator_mathop

手机端虚拟按键实现案例

绑定某个dom为移动端的虚拟键盘需要先引入jQuery

function regKeyEvent(selector, key, keyCode) {
    console.log("注册按键事件:" + key)
    $(selector).on("touchstart", function(event) {
        vm.postIOData("keyboard", {
          keyCode: keyCode,
          key: key,
          isDown: true,
        });
        event.preventDefault();
      });
      $(selector).on("touchend", function() {
        vm.postIOData("keyboard", {
          keyCode: keyCode,
          key: key,
          isDown: false,
        });
        event.preventDefault();
      });
  }

  // 配置上下左右空格键
  regKeyEvent(".button_space", " ", 32)
  regKeyEvent(".button_down", "ArrowDown", 40)
  regKeyEvent(".button_up", "ArrowUp", 38)
  regKeyEvent(".button_left", "ArrowLeft", 37)
  regKeyEvent(".button_right", "ArrowRight", 39)