html垃圾分类⽹页制作,HTML5+WebGL实现的垃圾分类系统前⾔
垃圾分类,⼀般是指按⼀定规定或标准将垃圾分类储存、分类投放和分类搬运,从⽽转变成公共资源的⼀系列活动的总称。分类的⽬的是提⾼垃圾的资源价值和经济价值,⼒争物尽其⽤。垃圾在分类储存阶段属于公众的私有品,垃圾经公众分类投放后成为公众所在⼩区或社区的区域性准公共资源,垃圾分类搬运到垃圾集中点或转运站后成为没有排除性的公共资源。从国内外各城市对⽣活垃圾分类的⽅法来看,⼤致都是根据垃圾的成分、产⽣量,结合本地垃圾的资源利⽤和处理⽅式来进⾏分类的。到2019年6⽉25⽇,⽣活垃圾分类制度将⼊法。⼀套应⽤于⼯业物联⽹的智能⼀体化的垃圾分类机械臂将随之⽽来,由此,我应⽤ HT for Web 的图型化编辑⼯具打造了⼀款形象⽣动的例⼦:Garbage classification,也借此机会与⼤家⼀起分享和学习。
代码实现
(注:gif 的上传⼤⼩有限,实际效果与还请参考 demo 链接)
⾸先,我应⽤已经精⼼布置好的 3D 场景,为了有更好的操作体验感,我们要从它的基本设置开始:
gv.setMovableFunc(() => { return false }) // 禁⽌拖动
gv.setEye([583, -212, -789]) // 设置眼睛
gv.setCenter([-76, -654, -133]) // 设置中⼼点
gv.setFar(100000) // 设置远端位置
gv.setNear(10) // 设置近端位置
gv.setInteractors([ aph3d.MapInteractor(gv) ]) // 设置交互限制
gv.DataByTag('skyBox')) // 设置天空球
extmenu = () => { return false } // 全局设置右键菜单禁⽤
gv.scene = { // 复制初始位置
eye: ht.Default.Eye()),
center: ht.Default.Center()),
far: ht.Default.Far()),
near: ht.Default.Near()),
}
我复制了⼀下整个场景的初始视⾓情况⽅便我做稍后的处理,我监听了部分⿏标事件来形成⾃⼰的操作风格(⽐如双击背景还原视⾓以及双击模型拉近视⾓):
gv.mi(e => {
let data = e.data
let kind = e.kind
if (kind === 'doubleClickBackground') { // 双击背景
}
else if (kind === 'doubleClickData') { // 双击模型
gv.flyTo(data, {animation : {duration : 500}, distance : 800}) // 拉近视⾓
}
})
好了,准备⼯作做好了,下⾯来实现动画部分,除了了解 垃圾分类 的⽅式外我还参考了⽹上很多机械臂的视频,学习它的运动模式和动作细节,对每个结构和部位的动画进⾏步骤的排序和构思。这⾥我挑选⼏处动画的实现⽅式来展⽰:
function mechanicalArmAnim1() {
ht.Default.startAnim({
duration: 1000,
easing: (t) => { return t },
action: (v, t) => {
postbrachium.r3(degrees(0) + (degrees(20) - degrees(0)) * v, postbrachium.r3()[1], postbrachium.r3()[2]) // 后臂向下移
},
finishFunc: () => {
setTimeout(() => {
mechanicalArmAnim2()
}, 300)
}
})
}
function mechanicalArmAnim2() {
ht.Default.startAnim({
duration: 1000,
easing: (t) => { return t },
action: (v, t) => {
postbrachium.p3(-208 + (-184 + 208) * v, postbrachium.p3()[1], postbrachium.p3()[2]) // 后臂前伸
hydraulicRod1.r3(degrees(0) + (degrees(8) - degrees(0)) * v, hydraulicRod1.r3()[1], hydraulicRod1.r3()[2]) // 液压杆1倾斜extensionRod1.r3(degrees(0) + (degrees(8) - degrees(0)) * v, extensionRod1.r3()[1], extensionRod1.r3()[2]) // 伸长杆1倾斜extensionRod1.p3(-169 + (-185 + 169) * v, -516 + (-511 + 516) * v, extensionRod1.p3()[2]) // 伸长杆1伸长
hydraulicRod2.r3(degrees(0) + (degrees(-8) - degrees(0)) * v, hydraulicRod2.r3()[1], hydraulicRod2.r
3()[2]) // 液压杆2倾斜extensionRod2.r3(degrees(0) + (degrees(-8) - degrees(0)) * v, extensionRod2.r3()[1], extensionRod2.r3()[2]) // 伸长杆2倾斜extensionRod2.p3(-169 + (-185 + 169) * v, -516 + (-511 + 516) * v, extensionRod2.p3()[2]) // 伸长杆2伸长
},
finishFunc: () => {
setTimeout(() => {
mechanicalArmAnim3()
}, 300)
}
})
}
function mechanicalArmAnim3() {
let oldValue = antebrachium.r3()[0]
ht.Default.startAnim({
duration: 1000,
easing: (t) => { return t },html frame
action: (v, t) => {
hydraulicRod1.r3(degrees(8) + (degrees(7) - degrees(8)) * v, hydraulicRod1.r3()[1], hydraulicRod1.r3()[2]) // 液压杆1倾斜
extensionRod1.r3(degrees(8) + (degrees(7) - degrees(8)) * v, extensionRod1.r3()[1], extensionRod1.r3()[2]) // 伸长杆1倾斜
extensionRod1.p3(-185 + (-186 + 185) * v, -511 + (-507 + 511) * v, extensionRod1.p3()[2]) // 伸长杆1伸长
hydraulicRod2.r3(degrees(-8) + (degrees(-7) - degrees(-8)) * v, hydraulicRod2.r3()[1], hydraulicRod2.r3()[2]) // 液压杆2倾斜
extensionRod2.r3(degrees(-8) + (degrees(-7) - degrees(-8)) * v, extensionRod2.r3()[1], extensionRod2.r3()[2]) // 伸长杆2倾斜
extensionRod2.p3(-185 + (-186 + 185) * v, -511 + (-507 + 511) * v, extensionRod2.p3()[2]) // 伸长杆2伸长
postbrachium.r3(degrees(20) + (degrees(25) - degrees(20)) * v, postbrachium.r3()[1], postbrachium.r3()[2]) // 后臂向下移antebrachium.r3(oldValue + (degrees(-40) - oldValue) * v, antebrachium.r3()[1], antebrachium.r3()[2]) // 前臂向下移
claw1.r3(degrees(-20) + (degrees(-60) - degrees(-20)) * v, claw1.r3()[1], claw1.r3()[2]) // 上⽖抓取
claw2.r3(degrees(-60) + (degrees(-30) - degrees(-60)) * v, claw2.r3()[1], claw2.r3()[2]) // 下⽖抓取
},
finishFunc: () => {
mechanicalArmAnim4()
}
})
}
这⼀段动画是机械臂从初始化状态到向下抓取的⼀个过程,我将每段动画分成函数来写⽐较⽅便后续管理,每⼀处也代表了⼀个步骤。这其中最复杂且细微的步骤要数液压杆的运动了,为了让动画看起来更加真实,我除了将⼿臂单独运动的过程中加⼊了延时执⾏下⼀段动画以体现机器运动的特点外,
也把液压杆的部分也做了动画,如果不做处理,那么机械臂在上下移动的时候就会有不科学的效果出现。动画函
数 在这种 demo 中应⽤的最⼴,⽽且⾥⾯也包含了⼀些缓动函数,有兴趣的博友们可以 点此处 ⾃⼰亲⾃动⼿玩⼀玩~
这⾥⾯的拾取垃圾步骤还应⽤了我过去介绍过的 吸附 功能,这个⽅法⾮常的适合抓取物体的动作,通过 setHost使节点吸附于宿主,这样就相当于⼦节点跟随⽗节点移动,此时只需要对机械臂进⾏偏移和旋转的操作,垃圾便会随之⼀起运动了,⼤⼤减少了⼯作量!
还有⼀部分更酷的属性设置给⼤家展⽰⼀下,可以让 3D 场景整体有更真实的阴影处理效果。⾸先我们要注意将⽆关的节点阴影通
过 node.s('shadow.cast', false) 关闭,⽐如编组⽤的box,背景,地板和⾯板等。
最后我们就把阴影的细节做下调整,达到⽐较好的效果:
degreeX : 0, // 投影 x 轴⾓度
degreeZ : -25, // 投影 z 轴⾓度
intensity : 0.3, // 阴影强度, 1 为⿊⾊
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论