canvas实现帘子吊灯鼠标交互物理碰撞效果代码
代码语言:html
所属分类:其他
代码描述:canvas实现帘子吊灯鼠标交互物理碰撞效果代码
代码标签: canvas 帘子 吊灯 鼠标 交互 物理 碰撞
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html> <html lang="en" > <head> <meta charset="UTF-8"> <style> html, body, canvas { -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } html, body { width: 100%; height: 100%; overflow: hidden; margin: 0; display: flex; align-items: center; justify-content: center; background: #191919; } .asset-img { display: none; } </style> </head> <body > <canvas></canvas> <!-- glowing image base64 --> <img class="asset-img" id="light-img" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABkAAAAZCAMAAADzN3VRAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAACnVBMVEUAAAD40ED40D740Dv40En40Dr40FH40Df40D/40D340Dn40Dz40Dj40AD40Ff40Db40DT40EH40EL40ED40ED40Dv40D/4zz/4zz74zz/4zz/40D74zz/4zz/4zz/40UH40kD40UL40kH4zz/4zz340D34zz740kH41UT410f410j410j410f40D/40D/4zz/40ED40EH400T410f42Er4103410/411D41UT40kH40D/4z0D4zz/41UX410j42E7411L42Ff42Vv42Vz42En41kb40UH4zz/40Dz40ED41UT42Ej4107411b42l743WT432r4323432r410/42En4zz340Dn400H410f42mD432v44nf45IP45Yn45IT44nj432r411b400L40D/4zz/41UT42Er411P432v44oD46Zv47q/48Lj46Zr432n40UH410f42Ff44nf48r/499T4997499T48r744nf43WP40D741EH42Vv4+O34+PP4+O347q745IL432j40UD432345Yj48LX49934+PP4+Pj4993477T45Ib432z411D400D40D/40UH432n45IP47a7432j42Vv410/400H40Dr4zz340UD410b410346Zj48r343WP42Ff410f40D/41kT42Er42l744nv46Zf42l3411L410r41kX40ED410f42E7411b421/45IL45Ib432n421740UH40D340Dz4zz741EP410j410743WT432f432v43mj43GT42Ej41kT4zz740ED41EX411P42Ff42Fv411f410j41kX400P41034107411D42E340D740UH410j41kb41ET400H40D/40ED4z0D4zz74zz340D////+WdN8lAAAA3nRSTlMAAAAAAAAAAAAAAAAAAAAAAAAAAgMCBAcJDAkDCA0SFRsbGxMDBQscJSwwMS0SDAUFFyExQExUVyIYDQULJzlOZHeDhDonFwoDASE5VXGNpbO4tFM5BwEcMJa3zdjb2Mu2cBwDESM+Y7bU4ebo4bUUK3bL6vDy7+rKogIZgPb49ebXsBu02+jx9/jw6Nu0VRsBGbDX5q9/UhkCCRUqS+HqoHMqESI9i9Thi2E9IhEvTG+V1tq0kxsDAQchN1Ggr7SvoDghChUjYXJ/cjgnIUlSVEkFGi8qIhsFFAcICAaJi/ApAAAAAWJLR0Te6W7imwAAAAd0SU1FB+YMHBEUINvSacMAAAIKSURBVCjPY2AgBBgZmZiFRYQZgQBVnEVUTFxCUlJSSlxMlAVJjplVWkZWTl5BUUleWVZGhZkZYZKqmpy6hqaWtpaOhrqunj7MREZGA1lDI2MTUzNzM1MTYwtLK2uIFCOjiI2hrZ29g6OTs5Ojg72Lq5u7Bxs7SMZTXNfL28fXzz8gMMjfzzc4xEI3NIwVrEUyPMLeNzIqOiY2Lj4hMtE+Ikk2mYkRKCOekpqW7peRmZWdk52bmeeXnqYhJ84BkpHKLzAt9C/KKi4pLSvPragsNNXMl/JkZGCqUqvWMqsJiMkuqa2rL2tobKox06qWTOZg4EiWbNY2d25pbWvv6Ozo6u7pde7T6pf04GTgmGAzEahn0uSGsvqO+rIpjVOnTdeaoTaTmYGLfdbsOXMLKyvmzS/rKps/r2jBwrmL5KWAfmViEl+8ZGn6srzlK6Z0T1mxPG/lqtVr1oLdxp0sqbRu/YaNeUWbNm8q2rJ1w/p12yS38wDDh3PHTrldu/dsWLZ33/4DB5dt2HPosO7OMFBwM/KKHjl6bPf64yemOZ88dXz96TPyR6T5+EFByi6ganP07LrV585fmH5x6bqzs21UmZhg0XDJXe7ykjnrtK5cvXZdzv0GMycs6jiZpXdKLs532+Z2M0VSXAQ5KTAKeorcuu1uc+TO3e07hNDSCCMjNyczKz8nN8FkxgAAgH2hXtQzzA4AAAAldEVYdGRhdGU6Y3JlYXRlADIwMjItMTItMjhUMTc6MjA6MzIrMDA6MDA1MNVoAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDIyLTEyLTI4VDE3OjIwOjMyKzAwOjAwRG1t1AAAAABJRU5ErkJggg=="> <script src="https://cpwebassets.codepen.io/assets/common/stopExecutionOnTimeout-2c7831bb44f98c1391d6a4ffda0e1fd302503391ca806e7fcc7b9b87197aec26.js"></script> <script > class Mouse { constructor(canvas) { this.pos = new Vector(-1000, -1000) this.radius = 40 canvas.onmousemove = e => this.pos.setXY(e.clientX, e.clientY) canvas.ontouchmove = e => this.pos.setXY(e.touches[0].clientX, e.touches[0].clientY) canvas.ontouchcancel = () => this.pos.setXY(-1000, -1000) canvas.ontouchend = () => this.pos.setXY(-1000, -1000) } } class Dot { constructor(x, y) { this.id = Math.random() this.pos = new Vector(x, y) this.oldPos = new Vector(x, y) this.radius = 1 this.friction = 0.97 this.gravity = new Vector(0, 0.6) this.mass = 1 this.pinned = false this.distMouse = 1000 this.lightImg = document.querySelector('#light-img') this.lightWidth = 15 this.lightHeight = 15 } update(mouse) { if (this.pinned) return let vel = Vector.sub(this.pos, this.oldPos) vel.mult(this.friction) this.oldPos.setXY(this.pos.x, this.pos.y) vel.add(this.gravity) this.pos.add(vel) let { x: dx, y: dy } = Vector.sub(this.pos, mouse.pos) this.distMouse = Math.sqrt(dx * dx + dy * dy) if (this.distMouse > mouse.radius + this.radius) return const direction = new Vector(dx / this.distMouse, dy / this.distMouse) let force = (mouse.radius - this.distMouse) / mouse.radius if (force < 0) force = 0 if (force < 0.6) { this.pos.sub(direction.mult(force).mult(0.0001)) } else { this.pos.setXY(mouse.pos.x, mouse.pos.y) } } drawLight(ctx) { ctx.drawImage( this.lightImg, this.pos.x - this.lightWidth / 2, this.pos.y - this.lightHeight / 2, this.lightWidth, this.lightHeight ) } draw(ctx) { ctx.fillStyle = '#aaa' ctx.fillRect(this.pos.x - this.radius, this.pos.y - this.radius, this.radius * 2, this.radius * 2) } } class Stick { constructor(p1, p2) { this.startPoint = p1 this.endPoint = p2 this.tension = 1 this.color = '#999' this.length = this.startPoint.pos.dist(this.endPoint.pos) } update() { const dx = this.endPoint.pos.x - this.startPoint.pos.x const dy = this.endPoint.pos.y - this.startPoint.pos.y const dist = Math.sqrt(dx*dx + dy*dy) const diff = (this.length - dist) / dist * this.tension const offsetX = dx * diff * 0.5 const offsetY = dy * diff * 0.5 const m = this.endPoint.mass + this.startPoint.mass const m1 = this.endPoint.mass / m const m2 = this.startPoint.mass / m if (!this.startPoint.pinned) { this.startPoint.pos.x -= offsetX * m1 this.startPoint.pos.y -= offsetY * m1 } if (!this.endPoint.pinned) { this.endPoint.pos.x += offsetX * m2 this.endPoint.pos.y += offsetY * m2 } } draw(ctx) { ctx.beginPath() ctx.strokeStyle = this.color ctx.moveTo(this.startPoint.pos.x, this.startPoint.pos.y) ctx.lineTo(this.endPoint.pos.x, this.endPoint.pos.y) ctx.stroke() ctx.closePath() } } clas.........完整代码请登录后点击上方下载按钮下载查看
网友评论0