canvas实现鼠标悬浮拖动铅球重力感应效果代码
代码语言:html
所属分类:动画
代码描述:canvas实现鼠标悬浮拖动铅球重力感应效果代码
代码标签: canvas 鼠标 悬浮 拖动 铅球 重力 感应 代码
下面为部分代码预览,完整代码请点击下载或在bfwstudio webide中打开
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<style>
body, html {
position: absolute;
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
canvas {
position: absolute;
width: 100%;
height: 100%;
cursor: none;
}
</style>
</head>
<body>
<script >
{
// Code never lies, comments sometimes do.
const Human = class {
constructor(size, gravity, x, y, struct) {
this.x = x;
this.y = y;
this.points = [];
this.constraints = [];
this.angles = [];
this.shapes = [];
// Points
for (const point of struct.points) {
this.points.push(
new Human.Point(canvas.width * x, canvas.height * y, point, size, gravity)
);
}
// constraints and shapes
for (const constraint of struct.constraints) {
const p0 = this.points[constraint.p0];
const p1 = this.points[constraint.p1];
this.constraints.push(new Human.Constraint(p0, p1, constraint));
if (constraint.svg) {
this.shapes.push(
new Human.Shape(p0, p1, constraint, struct.svg[constraint.svg], size)
);
}
}
// angle constraints
for (const angle of struct.angles) {
this.angles.push(
new Human.Angle(
this.points[angle.p0],
this.points[angle.p1],
this.points[angle.p2],
angle
)
);
}
}
anim() {
for (const point of this.points) point.integrate();
for (let i = 0; i < 5; ++i) {
for (const angle of this.angles) angle.update();
for (const constraint of this.constraints) constraint.update();
}
for (const point of this.points) point.collide(ball);
}
draw() {
for (const shape of this.shapes) shape.draw();
}
};
// Points
Human.Point = class {
constructor(x, y, p, s, g) {
this.x = x + p.x * s;
this.y = y + p.y * s;
this.px = this.x;
this.py = this.y;
this.vx = 0.0;
this.vy = 0.0;
this.m = p.m || 1.0;
this.g = g;
}
join(p1, distance, force) {
const dx = p1.x - this.x;
const dy = p1.y - this.y;
const dist = Math.sqrt(dx * dx + dy * dy);
const tw = this.m + p1.m;
const r1 = p1.m / tw;
const r0 = this.m / tw;
const dz = (distance - dist) * force;
const sx = dx / dist * dz;
const sy = dy / dist * dz;
p1.x += sx * r0;
p1.y += sy * r0;
this.x -= sx * r1;
this.y -= sy * r1;
}
dist(p1) {
const dx = this.x - p1.x;
const dy = this.y - p1.y;
return Math.sqrt(dx * dx + dy * dy);
}
integrate() {
// verlet integration
this.vx = this.x - this.px;
this.vy = this.y - this.py;
this.px = this.x;
this.py = this.y;
this.x += this.vx;
this.y += this.vy + this.g;
}
collide(ball) {
// collision with ball
const dx = this.x - ball.x;
const dy = this.y - ball.y;
const sd = dx * dx + dy * dy;
if (sd < ball.radius * ball.radius) {
const d = Math.sqrt(sd);
const dz = (ball.radius - d) * 0.5;
this.x += dx / d * dz;
this.y += dy / d * dz;
}
}
};
// Shapes
Human.Shape = class {
constructor(p0, p1, shape, src, size) {
this.p0 = p0;
this.p1 = p1;
this.width = shape.w * size;
this.height = shape.h * size;
this.shape = canvas.createImage(
shape.svg,
"data:image/svg+xml;base64," + window.btoa(src)
);
this.offset = shape.offset;
}
draw() {
canvas.drawImage(
this.shape,
this.p0.x,
this.p0.y,
this.height + this.width * this.offset,
this.width,
-this.height * this.offset,
-this.width * 0.5,
Math.atan2(this.p1.y - this.p0.y.........完整代码请登录后点击上方下载按钮下载查看
















网友评论0