如何解决如何使项目可拖动和可点击?
我是Matter JS的新手,所以请多多包涵。我将以下示例和其他来源的代码放在一起以满足我的需求:
function biscuits(width,height,items,gutter) {
const {
Engine,Render,Runner,Composites,MouseConstraint,Mouse,World,Bodies,} = Matter
const engine = Engine.create()
const world = engine.world
const render = Render.create({
element: document.getElementById('canvas'),engine,options: {
width,showAngleIndicator: true,},})
Render.run(render)
const runner = Runner.create()
Runner.run(runner,engine)
const columns = media({ bp: 'xs' }) ? 3 : 1
const stack = Composites.stack(
getRandom(gutter,gutter * 2),gutter,columns,items.length,(x,y,a,b,c,i) => {
const item = items[i]
if (!item) {
return null
}
const {
width: itemWidth,height: itemHeight,} = item.getBoundingClientRect()
const radiusAmount = media({ bp: 'sm' }) ? 100 : 70
const radius = item.classList.contains('is-biscuit-4')
? radiusAmount
: 0
const shape = item.classList.contains('is-biscuit-2')
? Bodies.circle(x,itemWidth / 2)
: Bodies.rectangle(x,itemWidth,itemHeight,{
chamfer: { radius },})
return shape
}
)
World.add(world,stack)
function positionDomElements() {
Engine.update(engine,20)
stack.bodies.forEach((block,index) => {
const item = items[index]
const xTrans = block.position.x - item.offsetWidth / 2 - gutter / 2
const yTrans = block.position.y - item.offsetHeight / 2 - gutter / 2
item.style.transform = `translate3d(${xTrans}px,${yTrans}px,0) rotate(${block.angle}rad)`
})
window.requestAnimationFrame(positionDomElements)
}
positionDomElements()
World.add(world,[
Bodies.rectangle(width / 2,width,{ isstatic: true }),Bodies.rectangle(width / 2,Bodies.rectangle(width,height / 2,Bodies.rectangle(0,])
const mouse = Mouse.create(render.canvas)
const mouseConstraint = MouseConstraint.create(engine,{
mouse,constraint: {
stiffness: 0.2,render: {
visible: false,})
World.add(world,mouseConstraint)
render.mouse = mouse
Render.lookAt(render,{
min: { x: 0,y: 0 },max: { x: width,y: height },})
}
我有一个HTML链接列表,该链接模仿了Matter JS(positionDomElements函数)中各项的运动。我这样做是出于SEO的目的,也是为了使导航可访问和可点击。
但是,因为我的画布位于HTML的顶部(不透明度为零),所以我需要能够使这些项目可点击和可拖动,以便我可以执行一些其他操作,例如导航到链接(以及其他事件)。
我不确定该怎么做。我已经搜寻过,但没有运气。
是否可以使每个项目都可拖动(并且已经存在)并执行某种点击事件?
我们将不胜感激任何帮助或指导正确的方向。
解决方法
似乎您的任务是将物理添加到一组DOM导航列表节点中。您可能会觉得,需要为subject.js提供一个画布以起作用,如果您想忽略它,则有必要隐藏画布或将其不透明度设置为0。
实际上,您可以使用自己的更新循环无头运行MJS,而无需在引擎中注入任何元素。实际上,不需要任何与Matter.Render
或Matter.Runner
相关的东西,并且您可以使用对Matter.Engine.update(engine);
的调用来使引擎在requestAnimationFrame
循环中向前移动一个刻度。然后,您可以使用从MJS主体提取的值来定位DOM元素。您已经做完了这两项工作,因此主要是切掉画布并渲染调用。
这是一个可运行的示例,您可以参考该示例并使其适应您的用例。
定位是困难的部分;确保MJS坐标与您的鼠标和元素坐标匹配需要花些时间。 MJS将x / y坐标视为身体的中心,因此我在左上角使用body.vertices[0]
来更好地匹配DOM。我认为这些渲染决定中有很多是针对特定应用程序的,因此请考虑一下这是一个概念证明。
const listEls = document.querySelectorAll("#mjs-wrapper li");
const engine = Matter.Engine.create();
const stack = Matter.Composites.stack(
// xx,yy,columns,rows,columnGap,rowGap,cb
0,listEls.length,1,(xx,i) => {
const {x,y,width,height} = listEls[i].getBoundingClientRect();
return Matter.Bodies.rectangle(x,height,{
isStatic: i === 0 || i + 1 === listEls.length
});
}
);
Matter.Composites.chain(stack,0.5,-0.5,{
stiffness: 0.5,length: 20
});
const mouseConstraint = Matter.MouseConstraint.create(
engine,{element: document.querySelector("#mjs-wrapper")}
);
Matter.World.add(engine.world,[stack,mouseConstraint]);
listEls.forEach(e => {
e.style.position = "absolute";
e.addEventListener("click",e =>
console.log(e.target.textContent)
);
});
(function update() {
requestAnimationFrame(update);
stack.bodies.forEach((block,i) => {
const li = listEls[i];
const {x,y} = block.vertices[0];
li.style.top = `${y}px`;
li.style.left = `${x}px`;
li.style.transform = `translate(-50%,-50%)
rotate(${block.angle}rad)
translate(50%,50%)`;
});
Matter.Engine.update(engine);
})();
* {
box-sizing: border-box;
margin: 0;
padding: 0;
}
html,body {
height: 100%;
}
body {
min-width: 600px;
}
#mjs-wrapper {
/* position this element */
margin: 1em;
height: 100%;
}
#mjs-wrapper ul {
font-size: 14pt;
list-style: none;
user-select: none;
position: relative;
}
#mjs-wrapper li {
background: #fff;
border: 1px solid #555;
display: inline-block;
padding: 1em;
cursor: move;
}
#mjs-wrapper li:hover {
background: #f2f2f2;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/matter-js/0.14.2/matter.min.js" integrity="sha512-pi0tSRZdlNRZeANPwdAIHRAYg6gZZV6QlAiyHXn5TYqLzBKE9jlttO/QgYLMhISD6oNv2kPsVelx+n5nw0FqKA==" crossorigin="anonymous"></script>
<div id="mjs-wrapper">
<ul>
<li>Foo</li>
<li>Bar</li>
<li>Baz</li>
<li>Quux</li>
<li>Garply</li>
<li>Corge</li>
</ul>
</div>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。