需求:导入CAD户型图,作为场景的背景图,可跟随场景缩放,但位置固定不变(在图上拖动改变场景的位置而不是改变户型图的位置)。
思考一:简单点,直接把户型图作为jtopo场景的背景图片
var canvas = document.getElementById('canvas');
var stage = new JTopo.Stage(canvas);
var scene = new JTopo.Scene(stage);
scene.background = './img/House.jpg';
然而,这样背景图就固定在那儿了,不能跟随场景缩放。。。
思考二:直接把户型图作为jtopo节点
首先把图片装进node中,并把节点大小设置成图片大小,节点位置居中
var houseImg = new Image();
houseImg .src = './img/House.jpg';
houseImg .onload = function () {
var node = new JTopo.Node();
node.setImage('./img/House.jpg', true); // 设置图片为CAD户型图
node.setSize(houseImg .width,houseImg .height); // 把节点大小设置成图片大小
node.setCenterLocation(canvasW/2, canvasH/2); // 节点位置居中
scene.add(node);
};
嗯…… 图片可以随着场景的缩放而缩放了
那进行下一步(在图上拖动改变场景的位置而不是改变户型图的位置 )
首先就想到了,拖动时记录鼠标按下时图片的原位置,拖拽时把图片的位置改成记录的图片的原位置,同时改变场景的位置。这样貌似就是我们需要的样子。。。
var selfX,selfY;
var mapStartX,mapStartY; // 地图上拖动事件记录起点
node.addEventListener("mousedown",function(event){
selfX = event.target.x; // 记录节点自身位置
selfY = event.target.y;
mapStartX = event.offsetX - _self.scene.translateX;
mapStartY = event.offsetY - _self.scene.translateY;
});
node.addEventListener("mousedrag",function(event){
stage.cursor = "url(./img/cur/closedhand.cur) 8 8, default";
event.target.x = selfX; // 使节点自身位置保持不变
event.target.y = selfY;
// 改变场景位置
scene.translateX += ((event.offsetX - _self.scene.translateX) - mapStartX);
scene.translateY += ((event.offsetY - _self.scene.translateY) - mapStartY);
});
node.addEventListener("mouseup",function(event){
selfX= ""; // 清空节点位置信息
selfY = "";
});
敲完一拖,哎。。看起来没毛病
滑动滚轮,图片缩放,,,嗯,没毛病
滑动拖动,图片不动,场景移动,,,嗯,没。。。。等等,拖动距离怎么不对。。
想想。。缩放后的拖动,改变的距离应该也要缩放一下
// 改变场景位置
scene.translateX += ((event.offsetX - _self.scene.translateX) - mapStartX)*scene.scaleX;
scene.translateY += ((event.offsetY - _self.scene.translateY) - mapStartY)*scene.scaleY;
刷新,再拖。。。嗯。。图呢?
好吧。。。看来是不行了。。。。为什么不行呢???想不通╮(╯▽╰)╭
。。。
哎,算啦先不想了这个了。。
再想个方法呢。。。
拖动图片节点时,我们去触发场景的拖动事件,而不触发节点自己的拖拽事件。
于是翻源码中。。
ctrl+f 搜索 onmousedrag 。。嗯?没有。。。那 mousedrag 嗯。。有了
终于找到下面这段代码:
/**
* scene场景拖拽的是节点时的处理(会将所有被选中的元素进行同样拖拽处理)
* 参数b为子元素
*/
this.dragElements = function (b) {
if (null != this.currentElement && 1 == this.currentElement.dragable)
for (var c = 0; c < this.selectedElements.length; c++) {
var d = this.selectedElements[c];
if (0 != d.dragable) {
var e = a.util.clone(b);
e.target = d, d.mousedragHandler(e)
}
}
},
/**
* scene场景拖拽处理
* 参数b为子元素
*/
this.mousedragHandler = function (b) {
var c = this.toSceneEvent(b);
this.mode == a.SceneMode.normal ?
null == this.currentElement || this.currentElement instanceof a.Link ? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) : this.dragElements(c) : this.mode == a.SceneMode.drag ? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) : this.mode == a.SceneMode.select ? null != this.currentElement ? 1 == this.currentElement.dragable && this.dragElements(c) : 1 == this.areaSelect && this.areaSelectHandle(c) : this.mode == a.SceneMode.edit && (null == this.currentElement || this.currentElement instanceof a.Link ? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) : this.dragElements(c)),
this.dispatchEvent("mousedrag", c)
},
好长的三元运算符。。。
this.dragElements = function(b) {
if (null != this.currentElement && 1 == this.currentElement.dragable)
for (var c = 0; c < this.selectedElements.length; c++) {
var d = this.selectedElements[c];
if (0 != d.dragable) {
var e = a.util.clone(b);
e.target = d,
d.mousedragHandler(e)
}
}
},
this.mousedragHandler = function(b) { //修改 myType 为 map 的拖拽方式
var c = this.toSceneEvent(b);;
this.mode == a.SceneMode.normal ? (null == this.currentElement || this.currentElement instanceof a.Link ? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) : this.dragElements(c) )
: this.mode == a.SceneMode.drag ? ( 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) )
: this.mode == a.SceneMode.select ? (null != this.currentElement ? 1 == this.currentElement.dragable && this.dragElements(c) : 1 == this.areaSelect && this.areaSelectHandle(c))
: this.mode == a.SceneMode.edit && (null == this.currentElement || this.currentElement instanceof a.Link ||(c.target&& c.target.myType == "map") ? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy) : this.dragElements(c)), this.dispatchEvent("mousedrag", c)
},
终于容易看懂了。。。
舞台模式是 normal 吗?
必须是哇。。
没有拖拽节点(拖拽的是场景),或者拖拽的是线(Link)吗?
诶。。就是你了!再看后面的处理,正是需要的:
null == this.currentElement || this.currentElement instanceof a.Link
? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy)
: this.dragElements(c)
嗯,给我们的图片设置一个属性,用以区分和其他节点的不同:
node.myType = "map";
其他节点设置成:
node.myType = "normal";
再修改上面的代码为:
null == this.currentElement || this.currentElement instanceof a.Link ||(c.target&& c.target.myType == "map")
? 1 == this.translate && (this.stage.cursor = a.MouseCursor.closed_hand, this.translateX = this.lastTranslateX + c.dx, this.translateY = this.lastTranslateY + c.dy)
: this.dragElements(c)
嗯。。刷新。。缩放。。拖动。。哈哈没毛病。。
咦。。再拖。。怎么是起点瞬间回到最开始的位置后在移动。。。
看来光改这一段源代码还不行啊,于是继续 ctrl+F
搜索 this.currentElement || this.currentElement instanceof a.Link
,在后面都加上
||(c.target&& c.target.myType == "map")
再刷新。。拖动。。。嗯。。没毛病
缩放。。拖动。。没毛病
O(∩_∩)O哈哈~