Jquery可以在图像映射区域上放置

时间:2012-01-24 17:09:46

标签: jquery

我有一个使用图像地图的图像,我想设置拖动 然后放下以便我知道该项目被丢弃的图像部分 到了。

它有点有效,但是当我将一个项目放到其中一个区域时,就可以了 触发所有区域的功能。有办法得到 那工作?

请帮忙......

2 个答案:

答案 0 :(得分:4)

所以,这是一个老问题,但这是我本周遇到的一个问题,找不到任何有用的答案。上面的答案并没有直接解决从html图像地图上的区域元素制作droppable的问题 - 它提出了一个答案,但该答案实际上并不起作用,因为制作一个'area'可以将整个图像映射到droppable,因此您无法确定删除项目时哪个区域处于活动状态。

这是我最终为我的问题实现的解决方案(使用多边形区域):

<div id="content">
<div id="targetImage"><img src="images/interactive_bg_triColored.png" usemap="#targetOverlay" alt="Strategic Action Chart"/>
    <map id="targetOverlay" name="targetOverlay">
    <area id="slice_0" shape="poly" coords="47, 294, 82, 178, 236, 267, 224, 293" />
    <area id="slice_1"  shape="poly" coords="87, 171, 168, 89, 258, 235, 240, 254" />
    <area id="slice_2"  shape="poly" coords="177, 82, 295, 48, 297, 228, 265, 234" />
    <area id="slice_3"  shape="poly" coords="302, 49, 419, 81, 334, 232, 303, 227" />
    <area id="slice_4" shape="poly" coords="428, 84, 514, 170, 360, 258, 338, 239" />
    <area id="slice_5" shape="poly" coords="364, 266, 516, 186, 546, 292, 373, 294" />
    <area id="slice_6" shape="poly" coords="546, 307, 518, 412, 363, 333, 373, 305" />
    <area id="slice_7" shape="poly" coords="512, 427, 428, 508, 340, 361, 360, 343" />
    <area id="slice_8" shape="poly" coords="421, 515, 304, 549, 302, 375, 334, 365" />
    <area id="slice_9" shape="poly" coords="295, 550, 180, 517, 266, 366, 295, 371" />
    <area id="slice_10" shape="poly" coords="170, 512, 86, 431, 240, 340, 259, 360" />
    <area id="slice_11" shape="poly" coords="80, 422, 51, 304, 228, 305, 235, 332" />
    </map>
</div>
<div id="word_list">
    <div id="instructions">Drag these action words into the appropriate category on the left.</div>
    <div id="word_6" class="draggable_word answer_o">Adjust</div>
    <div id="word_7" class="draggable_word answer_m">Infer</div>
    <div id="word_8" class="draggable_word answer_m">Synthesize</div>
    <div id="word_4" class="draggable_word answer_o">Summarize</div>
    <div id="word_5" class="draggable_word answer_o">Maintain<br /> Fluency</div>
    <div id="word_9" class="draggable_word answer_m">Make<br />Connections</div>
    <div id="word_11" class="draggable_word answer_p">Critique</div>
    <div id="word_10" class="draggable_word answer_m">Predict</div>
    <div id="word_2" class="draggable_word answer_o">Monitor <br />and Correct</div>
    <div id="word_3" class="draggable_word answer_o">Search & Use<br /> Information</div>
    <div id="word_0" class="draggable_word answer_p">Analyze</div>
    <div id="word_1" class="draggable_word answer_o">Solve Words</div>

</div>

CSS:

    .draggable_word 
{
    font-weight: bold;
    padding: 5px;
    width: 100px;
    display: inline-block
}

.draggable_word:hover 
{
    cursor: pointer;
}

注意,你必须在你的.draggable类上设置一个宽度(你可以把它命名为什么,但它需要应用于你要使其可拖动的项目,在我的例子中是一个有少量的div里面的文字)

var x1, y1 = 0;
var area = []; //set of area objects
var myDropTarget = 'invalid';

$(document).ready(function () {
for (i = 0; i < 12; i++) {
    $('#word_' + i).draggable({
        cursor: "move",
        revert: function (socketObj) {
            //if false then no droppable target was found
            if (socketObj === false) {
                //revert the draggable by returning true
                return true;
            }
            else { //the drop location was a droppable zone, now test it for answer validity

                var offset = $(this).offset(); //gets the x,y position of the dragged object when it stops
                x1 = offset.left + ($(this).width() / 2); //establishes the center of the object to use for testing x,y
                y1 = offset.top + ($(this).height() / 2);

                var result = dropTarget(x1, y1); //returns id of area or 'invalid'
                //logic to validate answers
                if (result === 'invalid') {
                    return true;
                } else { //evaluate for answer correctness
                    var testSlice = result.split('_');

                    if ((testSlice[1] > -1) && testSlice[1] < 6) { //first 6 slices are 'orange'
                        if ($(this).hasClass('answer_o')) { //correct answer
                            return false; //slice matches word answer class so do NOT revert
                        }
                    } else if ((testSlice[1] > 5) && testSlice[1] < 10) { //next 4 slices are 'maroon'
                        if ($(this).hasClass('answer_m')) { //correct answer
                            return false; //slice matches word answer class so do NOT revert
                        }
                    } else if ((testSlice[1] > 9 ) && testSlice[1] < 12) { //last 2 slices are 'purple'
                        if ($(this).hasClass('answer_p')) { //correct answer
                            return false; //slice matches word answer class so do NOT revert
                        }
                    }  else return true;


                }

                console.log('drop ' + x1 + ', ' + y1);
                console.log(result);

                //if no correct answer was found then it will still need to revert;
                return true;
            }
        }
    });
}

$('map area').each(function (i) {
    //this creates an array of area polygon objects so that we can test when an item has been dropped inside of one
    area[i] = {}; // creates a new object which will have properties for id, x coordinates, and y coordinates
    area[i].id = $(this).attr("id");
    area[i].x = [];
    area[i].y = [];
    var coords = JSON.parse('[' + $(this).attr("coords") + ']');
    var totalPairs = coords.length / 2;
    var coordCounter = 0; //variable to double iterate
    for (ix = 0; ix < totalPairs; ix++) { //fill arrays of x/y coordinates for pnpoly
        area[i].x[ix] = coords[coordCounter];
        area[i].y[ix] = coords[coordCounter + 1];
        coordCounter += 2;
    }
});

$('#targetImage').droppable({
    // maps or areas don't work well as droppable targets so we make image's container div into the droppable 
    tolerance: 'pointer'
});
});


function dropTarget(dropX, dropY) {
var target = 'invalid';

for (i = 0; i < area.length; i++) { //iterate through all of our area objects
    if (pnpoly(area[i].x.length, area[i].x, area[i].y, dropX, dropY)) {
        for (ix = 0; ix < area[i].x.length; ix++) {
            console.log(area[i].x[ix] + ', ' + area[i].y[ix]);
        }
        target = area[i].id;
        break;
     }
}
return target;
}

function pnpoly(nvert, vertx, verty, testx, testy) { //Point in Poly Test http://www.ecse.rpi.edu/~wrf/Research/Short_Notes/pnpoly.html
var i, j, c = false;
for (i = 0, j = nvert - 1; i < nvert; j = i++) {
    if (((verty[i] > testy) != (verty[j] > testy)) &&
        (testx < (vertx[j] - vertx[i]) * (testy - verty[i]) / (verty[j] - verty[i]) + vertx[i])) {
        c = !c;
    }
}
return c;
}

它的基本功能是生成一个对象数组来表示每个'area'元素。这些对象具有ID属性,X点数组和Y点数组。可拖动的项目报告它们的中心点,然后测试它是否落入具有聚合点函数(pnpoly)的某个多边形内。如果找到匹配,则返回该区域的ID,允许我们在draggable的revert函数定义中应用逻辑。在这种情况下,我应用了一个虚拟类来表示不同的可接受答案类型。

无论如何,希望将来帮助某人......

答案 1 :(得分:2)

我假设你有类似的东西:

<img src="image.gif" width="145" height="126" alt="Elements" usemap="#elementmap" />

<map name="elementmap">
  <area id="element1" shape="rect" coords="0,0,82,126" alt="Element 1"/>
  <area id="element2" shape="circle" coords="90,58,3" alt="Element 2"/>
</map>

我认为你可以在你的jQuery代码中调用$('#element1')来获取对象并做一些事情(我认为可以工作,因为如果你在第一个元素中发出一个click事件触发警报,它有效!)

另一方面,如果您需要删除元素的坐标或者只是希望元素在div上建立,这可能会对您有所帮助。看看这个例子并根据你的需要进行编辑:

首先看一下: http://www.placona.co.uk/166/javascript/a-more-elaborated-jquery-drag-drop-cloning/

实例: http://examples.placona.co.uk/drag_drop

最后,建议不要100%使用coords,因为当用户调整浏览器窗口大小时,coords会更改,如果您将来需要它们来恢复位置并将它们全部收费到浏览器,它将无法正常工作

显然我不知道你是否需要它们但我只是说。

希望这有帮助。