1、决定采取react hooks属性 ,将react升级成 16.12最新版本。 需要重新link scratch-vm
2、决定不采用框架,使用sass进行样式编写。安装node-sass和 sass-loader
3、编辑界面先,左上角logo修改,并链入官网路由。
4、开仿!
需要升级的框架:
react react-dom react-test-renderer
开源库选择:
2019年12月16日15:51:52
经分析GUI和考虑到用户体验感,
需要使用webpack进行多页面生成。
index.html是官网,
editor.html是编辑器。
然后 index.ejs中注入 扩展的配置config
再gui中添加垃圾桶。
经过几小时的研究,终于完成多页面的webpack配置。
但是其中需要注释optimization。如果不注释,则home页面打包的js文件会丢失react和react-dom
本地调式sb3接口:3001
在ReactDOM.render中,
此WappredGui是高阶组件。
其内部是GUI container 状态逻辑层
再内部是 GUI component 样式逻辑层
注意:
之前修改了默认角色,而默认角色需要添加svg*2到2处。
一处在lib/default-project/中
另一处在/static/assets/中
// tag-messages.js里面增加
geekstar: {
defaultMessage: 'Geekstar',
description: 'Tag for filtering a library for geekstar',
id: 'gui.libraryTags.geekstar'
},
geekstar就是新增的按钮;
// backdrops.json
{
"name":"123",
"rawURL":"https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1574859531235&di=2c4c333fda2ddce66dcd88d08a34f149&imgtype=0&src=http%3A%2F%2Fpic27.nipic.com%2F20130313%2F9252150_092049419327_2.jpg",
"type":"backdrop",
"tags":[
"outdoors",
"cold",
"north pole",
"south pole",
"ice",
"antarctica",
"robert hunter",
"geekstar"
],
"info":[
960,
720,
2
]
}
// backdrop-tags.js
{tag: 'geekstar', intlLabel: messages.geekstar}
1、单站点Home开发 使用webpack.config2.js
2、双站点Home与GUI调试,还是使用webpack.config.js
注意1:
双站点开发 需注意路由和链接的区别。
站点之间的跳转是 链接的跳转。 是服务端做的事
而站点内的跳转是 路由的跳转。 是前端一种锚点功能。
2020年1月13日,前端大体完成,进入后端开发部分。
并不断优化前端,优化后端。
1、BrowserRouter为了美化URL以及书签的可收藏,进行了地址栏hash的增加,并且每个组件拥有UseEffect副作用,用于跳转指定选项卡(适配书签)。 // DigitalTabs考虑复杂度就不做了,制作一级路由适配书签。
2、但是有个问题,react-router-dom 提供的 history.listen没有解除绑定的API,故只能暂时通过window去标志。
3、找到了解决办法,官方不是没提供解绑,而是封装成了二阶函数,即将listen实例化执行即可。
管理react路由的history对象的插件history的使用介绍
4、完整实现代码如下:
const [location, setLocation] = useState(props.location);
const prevLocation = usePrev(location);
// ...
// 充当路由守卫
useEffect(() => {
// 挂载完毕后的触发顺序: listener return useEffect回调文
// 3、触发内部逻辑,滚动条跳转
// console.log(location, prevLocation);
if (location.pathname !== prevLocation.pathname) {
window.scrollTo(0, 0);
}
const unListen = props.history.listen(location => {
// 1、触发hashchange,设置location,
// 而prevLocation会因为重新执行闭包,自动记录先前的location
setLocation(location);
});
// 2、触发unListen解绑listener,
return () => unListen();
}, [location]);
仅改变页面的哈希,是不会触发重渲的。
非常适合于拥有选项卡的页面,多级选项卡,配合多个哈希,进行多样数据渲染。
方式有两种:
1、哈希与逻辑强关联
// 所有选项卡的点击,均是路由跳转,路由改变会触发useEffect,useEffect中进行数据的重渲。
// 页面首载:路由定位选项卡
useEffect(() => {
// 一级路由哈希判断,定位次级路由的渲染内容
const { type } = transferHash(props.location.hash);
if (type === 'work') {
setNavActiveIndex(0);
} else if (type === 'collect') {
setNavActiveIndex(1);
} else if (type === 'concern') {
setNavActiveIndex(2);
}
}); // props的location改变会触发
// 作品 收藏 关注
const handleNavClick = (index) => {
// 哈希跳转
props.history.push(`/user#type=${
index === 0 ? 'work' : index === 1 ? 'collect' : 'concern'
}`)
};
2、哈希与逻辑解耦
// 页面首载:路由定位选项卡
useEffect(() => {
// ... 相似
}, []); // 只需要触发一次
const handleTabClick = (index) => {
setTabActiveIndex(index);
};
const handleTagClick = (index) => {
setTagActiveIndex(index);
};
const handleDigitalClick = (index) => {
setDigitalActiveIndex(index);
window.location.hash = `#sha`; // 修改哈希
// .. refreshWorks()
};
1、嵌入基本无问题,但静态资源的地址,需要使用根目录定位,output publicPath: '/'即可
2、注意historyApiFallback: true
3、devServer 资源代理默认 publicPath: ‘/’ 无问题。
4、修改SB3播放器样式
1、进入编辑按钮和隐藏过渡动画
2、播放器尺寸调整
2.1圆角消除
3、stage-only.css盒子宽高采用继承
4、播放器全屏样式优化
5、过渡动画小屏幕化
注:上述样式并非最终样式,主要参考文件的位置。
2020年1月16日14:21:25 杂七杂八原因,样式又进行了修改,从自己的组件开始传入isPlayerOnly并传递给Stage继续向下传递。
其实scratch自身提供了外部链入作品的方法,而且直接暴露给了浏览器的URL 如
/#10001 则访问是服务器的10001文件,但是我想抽离出API.
辗转1小时,我失败了。
所以,还是魔改源码。
注: 理论上sb3_时间戳.sb3 应该不会重名,我不清楚。但是并不想大改,更新数据库的字段。
且使用handleHashChange,并不灵活,如果真发生问题,需要注入loadProject并注入封面,后议。
过了15分钟。
我真实日了狗了,问题很严峻,如果url采用文件名的方式去获取文件,很好,文件来了,那么数据库的字段信息呢,标识是什么? ???
OKOK,
只能采用loadProject方式了,希望坑别太多。
2020年1月17日13:31:32
SB3Player组件 封装完毕。
实现过程和思路基本一致:
loadProject加载完作品后, projectData进入了redux,通过注入vm单例,调用vm.renderer.draw()方法 进行canvas的解析。
2020年2月6日19:39:06
因为站点需要对SB3Player组件的尺寸做设置。故需要开设新prop传递。
在此梳理下文件之间的关系:
其实视频用的就是原生的播放器,没什么花头。
<div className='video-contaniner'>
<video
src={resource} // resource为视频地址
controls="controls"
/>
</div>