Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/453.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何使画布中的对象被其他对象吸引_Javascript_Canvas_Html5 Canvas_Vector Graphics - Fatal编程技术网

Javascript 如何使画布中的对象被其他对象吸引

Javascript 如何使画布中的对象被其他对象吸引,javascript,canvas,html5-canvas,vector-graphics,Javascript,Canvas,Html5 Canvas,Vector Graphics,我在画布上画了一些字。它们有随机位置。我希望他们根据一套规则慢慢地相互吸引 规则是有些单词必须在其他单词的上面、左边、右边 var rules = { "id": { leftOf: ["title"], }, "title": { above: ["userId"], }, "completed": { "rightOf": ["title"] } } 如何从数学上在多个物体之间添加独立的引力吸引 在中,

我在画布上画了一些字。它们有随机位置。我希望他们根据一套规则慢慢地相互吸引

规则是有些单词必须在其他单词的上面、左边、右边

var rules = {
    "id": {
      leftOf: ["title"],
    },
    "title": {
      above: ["userId"],
    },
    "completed": {
      "rightOf": ["title"]
    }
  }
如何从数学上在多个物体之间添加独立的引力吸引

在中,我刚刚将x和y装配到位置规则

完整代码:

<canvas id="canvas" width="1000" height="300"></canvas>

<script type="text/javascript">
// vector code from https://gist.github.com/winduptoy/a1aa09c3499e09edbd33
function Vector(x, y) {
    this.x = x || 0;
    this.y = y || 0;
}

/* INSTANCE METHODS */

Vector.prototype = {
    negative: function() {
        this.x = -this.x;
        this.y = -this.y;
        return this;
    },
    add: function(v) {
        if (v instanceof Vector) {
            this.x += v.x;
            this.y += v.y;
        } else {
            this.x += v;
            this.y += v;
        }
        return this;
    },
    subtract: function(v) {
        if (v instanceof Vector) {
            this.x -= v.x;
            this.y -= v.y;
        } else {
            this.x -= v;
            this.y -= v;
        }
        return this;
    },
    multiply: function(v) {
        if (v instanceof Vector) {
            this.x *= v.x;
            this.y *= v.y;
        } else {
            this.x *= v;
            this.y *= v;
        }
        return this;
    },
    divide: function(v) {
        if (v instanceof Vector) {
            if(v.x != 0) this.x /= v.x;
            if(v.y != 0) this.y /= v.y;
        } else {
            if(v != 0) {
                this.x /= v;
                this.y /= v;
            }
        }
        return this;
    },
    equals: function(v) {
        return this.x == v.x && this.y == v.y;
    },
    dot: function(v) {
        return this.x * v.x + this.y * v.y;
    },
    cross: function(v) {
        return this.x * v.y - this.y * v.x
    },
    length: function() {
        return Math.sqrt(this.dot(this));
    },
    normalize: function() {
        return this.divide(this.length());
    },
    min: function() {
        return Math.min(this.x, this.y);
    },
    max: function() {
        return Math.max(this.x, this.y);
    },
    toAngles: function() {
        return -Math.atan2(-this.y, this.x);
    },
    angleTo: function(a) {
        return Math.acos(this.dot(a) / (this.length() * a.length()));
    },
    toArray: function(n) {
        return [this.x, this.y].slice(0, n || 2);
    },
    clone: function() {
        return new Vector(this.x, this.y);
    },
    set: function(x, y) {
        this.x = x; this.y = y;
        return this;
    }
};

/* STATIC METHODS */
Vector.negative = function(v) {
    return new Vector(-v.x, -v.y);
};
Vector.add = function(a, b) {
    if (b instanceof Vector) return new Vector(a.x + b.x, a.y + b.y);
    else return new Vector(a.x + b, a.y + b);
};
Vector.subtract = function(a, b) {
    if (b instanceof Vector) return new Vector(a.x - b.x, a.y - b.y);
    else return new Vector(a.x - b, a.y - b);
};
Vector.multiply = function(a, b) {
    if (b instanceof Vector) return new Vector(a.x * b.x, a.y * b.y);
    else return new Vector(a.x * b, a.y * b);
};
Vector.divide = function(a, b) {
    if (b instanceof Vector) return new Vector(a.x / b.x, a.y / b.y);
    else return new Vector(a.x / b, a.y / b);
};
Vector.equals = function(a, b) {
    return a.x == b.x && a.y == b.y;
};
Vector.dot = function(a, b) {
    return a.x * b.x + a.y * b.y;
};
Vector.cross = function(a, b) {
    return a.x * b.y - a.y * b.x;
};

var texts = ["userId", "id", "title", "completed"];

var rules = {
    "id": {
      leftOf: ["title"],
    },
    "title": {
      above: ["userId"],
    },
    "completed": {
      "rightOf": ["title"]
    }
  }

var vectors = [];
function getRandomArbitrary(min, max) {
  return Math.random() * (max - min) + min;
}

function Thing(text, x, y) {
  this.text = text;
  this.pos = new Vector(x, y);
  this.velocity = new Vector(getRandomArbitrary(-1, 1), getRandomArbitrary(-1, 1));
  this.thrust = 0.1;
}
var things = texts.map(function (item) {
  return new Thing(item, getRandomArbitrary(0, 900), getRandomArbitrary(0, 300));
}
);

var lookup = {};
for (var i=0; i<texts.length; i++) {
    lookup[texts[i]] = things[i];
}

var ctx = document.getElementById('canvas').getContext('2d');
  ctx.font = '18px serif';

function tick() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);

 for (var i=0; i < things.length; i ++) {

   var thing = things[i];
   thing.velocity.add(thing.thrust);

   for (var j=0; j < things.length; j++) {
     if (things[j].text == thing.text) { continue }
     if (!rules.hasOwnProperty(thing.text)) { continue }
     var rule = rules[thing.text];

     if (rule.hasOwnProperty( "leftOf")) {
        console.log(thing.text, "must be left of", rule["leftOf"]);
         for (var k=0; k < rule["leftOf"].length; k++ ) {
            if (rule["leftOf"] == things[j].text) {
              console.log("Changing velocity of", thing.text, "to cause it to be left of", things[j].text);
              thing.pos.x = things[j].pos.x - 20;
              thing.pos.y = things[j].pos.y;
            }
         }
     }

        if (rule.hasOwnProperty( "above")) {
        console.log(thing.text, "must be above", rule["above"]);
         for (var k=0; k < rule["above"].length; k++ ) {
            if (rule["above"] == things[j].text) {
              console.log("Changing velocity of", thing.text, "to cause it to be above", things[j].text);
              thing.pos.x = things[j].pos.x;
              thing.pos.y = things[j].pos.y - 30;
            }
         }
        }

        if (rule.hasOwnProperty( "rightOf")) {
        console.log(thing.text, "must be right of", rule["rightOf"]);
         for (var k=0; k < rule["rightOf"].length; k++ ) {
            if (rule["rightOf"] == things[j].text) {
              console.log("Changing velocity of", thing.text, "to cause it to be right of", things[j].text);
              thing.pos.x = things[j].pos.x + 60;
              thing.pos.y = things[j].pos.y;
            }

        }



     }


   }

     thing.pos.add(thing.velocity);
    ctx.fillText(thing.text, thing.pos.x, thing.pos.y);

 }
}
setInterval(tick, 1000);
</script>

//矢量码https://gist.github.com/winduptoy/a1aa09c3499e09edbd33
函数向量(x,y){
这个.x=x | | 0;
这个.y=y | | 0;
}
/*实例方法*/
Vector.prototype={
否定:函数(){
this.x=-this.x;
this.y=-this.y;
归还这个;
},
加:功能(五){
if(v instanceof向量){
这个.x+=v.x;
这个.y+=v.y;
}否则{
这个.x+=v;
这是y+=v;
}
归还这个;
},
减:函数(v){
if(v instanceof向量){
这个.x-=v.x;
这个.y-=v.y;
}否则{
这个.x-=v;
这个.y-=v;
}
归还这个;
},
乘法:函数(v){
if(v instanceof向量){
这个.x*=v.x;
这个.y*=v.y;
}否则{
这个.x*=v;
这个.y*=v;
}
归还这个;
},
划分:功能(五){
if(v instanceof向量){
如果(v.x!=0)这个.x/=v.x;
如果(v.y!=0)这个.y/=v.y;
}否则{
如果(v!=0){
这个.x/=v;
这个.y/=v;
}
}
归还这个;
},
等于:函数(v){
返回this.x==v.x&&this.y==v.y;
},
dot:功能(v){
返回此.x*v.x+此.y*v.y;
},
交叉:功能(v){
返回此.x*v.y-此.y*v.x
},
长度:函数(){
返回Math.sqrt(this.dot(this));
},
规范化:函数(){
返回this.divide(this.length());
},
min:函数(){
返回Math.min(this.x,this.y);
},
max:function(){
返回Math.max(this.x,this.y);
},
toAngles:function(){
return-Math.atan2(-this.y,this.x);
},
角度:功能(a){
返回Math.acos(this.dot(a)/(this.length()*a.length());
},
toArray:函数(n){
返回[this.x,this.y].slice(0,n | | 2);
},
克隆:函数(){
返回新向量(this.x,this.y);
},
设置:功能(x,y){
这个.x=x;这个.y=y;
归还这个;
}
};
/*静态方法*/
向量负=函数(v){
返回新向量(-v.x,-v.y);
};
Vector.add=函数(a,b){
if(b instanceof Vector)返回新向量(a.x+b.x,a.y+b.y);
否则返回新向量(a.x+b,a.y+b);
};
Vector.subtract=函数(a,b){
if(b instanceof Vector)返回新向量(a.x-b.x,a.y-b.y);
否则返回新向量(a.x-b,a.y-b);
};
向量乘=函数(a,b){
if(b instanceof Vector)返回新向量(a.x*b.x,a.y*b.y);
否则返回新向量(a.x*b,a.y*b);
};
Vector.divide=函数(a,b){
if(b instanceof Vector)返回新向量(a.x/b.x,a.y/b.y);
否则返回新向量(a.x/b,a.y/b);
};
Vector.equals=函数(a,b){
返回a.x==b.x&&a.y==b.y;
};
Vector.dot=函数(a,b){
返回a.x*b.x+a.y*b.y;
};
Vector.cross=函数(a,b){
返回a.x*b.y-a.y*b.x;
};
var text=[“userId”、“id”、“title”、“completed”];
风险值规则={
“id”:{
左撇子:[“标题”],
},
“标题”:{
上面:[“userId”],
},
“已完成”:{
“所有权”:[“所有权”]
}
}
var向量=[];
函数GetRandomArbital(最小值、最大值){
返回Math.random()*(max-min)+min;
}
函数对象(文本,x,y){
this.text=文本;
this.pos=新向量(x,y);
this.velocity=新向量(GetRandomArbital(-1,1),GetRandomArbital(-1,1));
这个推力=0.1;
}
var things=text.map(函数(项){
返回新事物(item,getrandomArbital(0900),getrandomArbital(0300));
}
);
var查找={};

对于(var i=0;iHi,您希望显示几个需要精确定位在彼此之间的单词。但是,它们最初是以随机位置显示的。它们必须缓慢地向应该位于的一侧移动,好像它们被吸引了一样。这是您想要的吗?还是我弄错了?只是几件事:
GetRandomArbitral(a,b)
=>随机和任意在这里的意思几乎相同,您可以将其更改为更有意义的内容,如
getRandomInRange(a,b)
getRandomBetween(a,b)
函数对象
:这是……嗯:)您可以使用
window.requestAnimationFrame()
而不是
setInterval()
:,您应该将
tick()
函数分解为几个较小的函数:)