gpt4 book ai didi

javascript - 如何在 kineticjs 中向贝塞尔曲线添加运动?

转载 作者:行者123 更新时间:2023-11-29 14:56:29 25 4
gpt4 key购买 nike

我是在没有 kinetic 的情况下完成的。这段代码工作得很好,正如我想要的那样。 --fiddle without kineticjs. Take a look

现在我想用 kineticjs 做同样的代码。这是我到目前为止所做的--fiddle with kineticjs .

线根本不动?我哪里错了?我花了一整天,但无法找出问题所在。

这是我的带有 kinetic 的 javascript。在 fiddle 中看不到结果,因为没有包含 kineticjs 的选项。虽然我已经把我的代码放在那里了。欢迎任何帮助。

var stage=new Kinetic.Stage({
container:'container',
width:500,
height:500
});

var layer=new Kinetic.Layer();

var bg=new Kinetic.Rect({
x:0,
y:0,
width:stage.getWidth(),
height:stage.getHeight(),
fill: 'antiquewhite'
});
layer.add(bg);

var drawHair = function(canvas) {
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.sx, this.attrs.sy);
context.bezierCurveTo(this.attrs.cp1x, this.attrs.cp1y, this.attrs.cp2x, this.attrs.cp2y, this.attrs.endx, this.attrs.endy);
context.closePath();
canvas.fillStroke(this);
};

function Hair(a, b, c, d, e, f, g, h) {
return new Kinetic.Shape({
drawFunc: drawHair,
fill: '#000',
lineJoin: 'round',
stroke: 'grey',
strokeWidth: 8,
sx: 136 + a,//start position of curve.used in moveTo(sx,sy)
sy: 235 + b,
cp1x: 136 + c,//control point 1
cp1y: 222 + d,
cp2x: 136 + e,//control point 2
cp2y: 222 + f,
endx: 136 + g,//end points
endy: 210 + h
});
}

var hd =[];
function init(){//this function draws each hair/curve
hd.push(new Hair(0, 0, 0, 0, 0, 0, 0, 0));
layer.add(hd[0]);
hd.push(new Hair(15, 0, 15, 0, 15, 0, 15, 0));
layer.add(hd[1]);
hd.push(new Hair(30, 0, 30, 0, 30, 0, 30, 0));
layer.add(hd[2]);
hd.push(new Hair(45, 0, 45, 0, 45, 0, 45, 0));
layer.add(hd[3]);
hd.push(new Hair(60, 0, 60, 0, 60, 0, 60, 0));
layer.add(hd[4]);
hd.push(new Hair(75, 0, 75, 0, 75, 0, 75, 0));
layer.add(hd[5]);
hd.push(new Hair(90, 0, 90, 0, 90, 0, 90, 0));
layer.add(hd[6]);
hd.push(new Hair(105, 0, 105, 0, 105, 0, 105, 0));
layer.add(hd[7]);
hd.push(new Hair(120, 0, 120, 0, 120, 0, 120, 0));
layer.add(hd[8]);

stage.add(layer);
}

var bend1=0;
var bend2=0;
var bend3=0;
var bend4=0;
var bend5=0;
var bend6=0;
var bend7=0;
var bend8=0;
var bend9=0;

stage.on('mousemove', function() {
var ref1=135;//this is ref point for hair or curve no 1
var ref2=150;//hair no 2 and so on
var ref3=165;
var ref4=180;
var ref5=195;
var ref6=210;
var ref7=225;
var ref8=240;
var ref9=255;
var pos = stage.getMousePosition();
console.log("x="+pos.x+"&&"+"y="+pos.y)
if(between(pos.x,115,270) && between(pos.y,205,236))
{
if(pos.x>=ref1 && pos.x<=145){bend1=(pos.x-ref1)*(2.2);}
if(pos.x<=ref1 && pos.x>=125){bend1=(pos.x-ref1)*(2.2);}

if(pos.x>=ref2 && pos.x<=160){bend2=(pos.x-ref2)*(2.2);}
if(pos.x<=ref2 && pos.x>=140){bend2=(pos.x-ref2)*(2.2);}

if(pos.x>=ref3 && pos.x<=175){bend3=(pos.x-ref3)*(2.2);}
if(pos.x<=ref3 && pos.x>=155){bend3=(pos.x-ref3)*(2.2);}

if(pos.x>=ref4 && pos.x<=190){bend4=(pos.x-ref4)*(2.2);}
if(pos.x<=ref4 && pos.x>=170){bend4=(pos.x-ref4)*(2.2);}

if(pos.x>=ref5 && pos.x<=205){bend5=(pos.x-ref5)*(2.2);}
if(pos.x<=ref5 && pos.x>=185){bend5=(pos.x-ref5)*(2.2);}

if(pos.x>=ref6 && pos.x<=220){bend6=(pos.x-ref6)*(2.2);}
if(pos.x<=ref6 && pos.x>=200){bend6=(pos.x-ref6)*(2.2);}

if(pos.x>=ref7 && pos.x<=235){bend7=(pos.x-ref7)*(2.2);}
if(pos.x<=ref7 && pos.x>=215){bend7=(pos.x-ref7)*(2.2);}

if(pos.x>=ref8 && pos.x<=250){bend8=(pos.x-ref8)*(2.2);}
if(pos.x<=ref8 && pos.x>=230){bend8=(pos.x-ref8)*(2.2);}

if(pos.x>=ref9 && pos.x<=265){bend9=(pos.x-ref9)*(2.2);}
if(pos.x<=ref9 && pos.x>=245){bend9=(pos.x-ref9)*(2.2);}
}
hd.push(new Hair(0, 0, 0, 0, 0, 0, 0+bend1, 0));
layer.add(hd[0]);
hd.push(new Hair(15, 0, 15, 0, 15, 0, 15+bend2, 0));
layer.add(hd[1]);
hd.push(new Hair(30, 0, 30, 0, 30, 0, 30+bend3, 0));
layer.add(hd[2]);
hd.push(new Hair(45, 0, 45, 0, 45, 0, 45+bend4, 0));
layer.add(hd[3]);
hd.push(new Hair(60, 0, 60, 0, 60, 0, 60+bend5, 0));
layer.add(hd[4]);
hd.push(new Hair(75, 0, 75, 0, 75, 0, 75+bend6, 0));
layer.add(hd[5]);
hd.push(new Hair(90, 0, 90, 0, 90, 0, 90+bend7, 0));
layer.add(hd[6]);
hd.push(new Hair(105, 0, 105, 0, 105, 0, 105+bend8, 0));
layer.add(hd[7]);
hd.push(new Hair(120, 0, 120, 0, 120, 0, 120+bend9, 0));
layer.add(hd[8]);
stage.add(layer);
console.log("bend1="+bend1);

});

function between(val, min, max) {
return val >= min && val <= max;
}

window.onload = function() {
init();
};

最佳答案

问题:

您正在为每个阶段的鼠标移动事件添加 9 个额外的 Shape 对象。

这意味着您可以快速创建数百(数千)根头发。

从只有 9 根头发的重新设计开始。

在 mousemove 事件期间,您将通过在它们的 drawFunc 中更改每根头发的弯曲来响应。

[编辑以包含示例代码]

您可以创建一个“智能”毛发,如果鼠标悬停在它上面,它就会倾听并相应地弯曲自己。

然后您可以根据需要添加任意数量的智能毛发。

你不需要跟踪他们在做什么,因为每个人都包含足够的信息+代码来正确地弯曲自己。

由于这只是一个教学示例,我已将您的曲线简化为由两部分组成的线,底部垂直,顶部“弯曲”。

enter image description here

这是自定义头发形状的绘制函数。线的顶部向鼠标位置“弯曲”。如果鼠标已在毛发响应区域内移动,则毛发的 endX 属性将设置为 mouseX 位置。这会导致头发向 mouseX 弯曲。

drawFunc: function(canvas){

if(mouseX>=this.attrs.respondLeft && mouseX<=this.attrs.respondRight){
this.attrs.endX=mouseX;
}
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.startX,this.attrs.bottomY);
context.lineTo(this.attrs.startX,this.attrs.midY);
context.lineTo(this.attrs.endX,this.attrs.topY);
canvas.fillStroke(this);
},

由于我们希望头发在鼠标移过它时自行弯曲,因此我们为舞台添加了一个 mousemove 事件处理程序。当鼠标移动时,mouseX 的位置会更新。重绘头发时,会向mouseX弯曲。

stage.on('mousemove', function() {

// set the endX where the hair will bend to
mouseX=stage.getMousePosition().x;

// redraw the layer
layer.draw();

});

下面的工作代码有点复杂,因为每根头发都存储了自己的信息,关于如何绘制自己和它的命中区域。

这是代码和 fiddle :http://jsfiddle.net/m1erickson/ey38w/

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Prototype</title>
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.1.min.js"></script>

<style>
#container{
border:solid 1px #ccc;
margin-top: 10px;
width:300px;
}
</style>
<script>
$(function(){

var stage = new Kinetic.Stage({
container: 'container',
width: 300,
height: 300
});
var layer = new Kinetic.Layer();
stage.add(layer);

var mouseX;

var hair1=addHair(100,200,20,150);
var hair2=addHair(120,200,20,150);
var hair3=addHair(140,200,20,150);
layer.draw();

function addHair(x,y,width,height){
var shape=new Kinetic.Shape({
drawFunc: function(canvas){

if(mouseX>=this.attrs.respondLeft && mouseX<=this.attrs.respondRight){
this.attrs.endX=mouseX;
}
var context = canvas.getContext();
context.beginPath();
context.moveTo(this.attrs.startX,this.attrs.bottomY);
context.lineTo(this.attrs.startX,this.attrs.midY);
context.lineTo(this.attrs.endX,this.attrs.topY);
canvas.fillStroke(this);
},
lineJoin: 'round',
stroke: 'grey',
strokeWidth: 12,
respondWidth:width,
respondLeft:x-width/2,
respondRight:x+width/2,
respondHeight:height,
respondTop:y-100,
topY:y-100,
midY:y-50,
bottomY:y,
startX:x,
endX:x
});
layer.add(shape);
return(shape);
}

// "bend" when mouse is inside any hairs hit boundaries
stage.on('mousemove', function() {
// set the endX where the hair will bend to
mouseX=stage.getMousePosition().x;
layer.draw();
});


}); // end $(function(){});

</script>
</head>

<body>
<div id="container"></div>
</body>
</html>

[额外的鼓励的话]

此模式适合您。

是的......即使是你的贝塞尔曲线。

但这只是一个起点,您必须根据自己的项目进行调整。

例如,在您的原始代码中,您经历了这些步骤

  • 监听 mousemove 事件并处理它们(您的移动函数),
  • 确定鼠标位置是否会影响您的头发,
  • 如果是这样,重新计算控制点+终点(您的初始化函数)。
  • 重新绘制头发(直到现在你才知道只重新绘制现有的头发——而不是创建新的头发),

所以将这些代码片段修改成这个模式!

不,您不能只是剪切和粘贴。你将不得不修改、改进、适应。

首先,让 1 根贝塞尔曲线按照您喜欢的方式工作。

然后——不是之前,请记住这个提示:

与其为每根头发分别创建一个 Kinetic Shape,不如创建一个 Shape 对象并在其 drawFunc 中绘制所有头发。这更高效。此外,然后您可以在那个形状而不是整个 Canvas 上收听 mousemove。同样,性能更高。

最重要的是——学习!:(1)实验(2)测试,(3)适应,(4)不要放弃,(5)重复#1。

关于javascript - 如何在 kineticjs 中向贝塞尔曲线添加运动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17026783/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com