我正在使用HTML5 <canvas></canvas>
标签,我一直试图找到有关是否可以在画布中包含下拉菜单的信息?
据我所知,这是不可能的。
不...
画布不是容器元素,因此您不能在画布中包含下拉菜单。
如果需要,您可以使用CSS在画布上定位下拉窗口小部件。
看完这个问题后。我试图在画布上下拉。这是经过大量努力的结果:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
var selected = "Selected item";
var labels = ["1","2","3"];
var mainDrop = {
x: 50,
y: 50,
width: 100,
height: 20
};
var itemDrop = {
x: mainDrop.x,
width: 100,
height: 20
};
var visible = false;
function getMousePos(canvas, event)
{
var rect = canvas.getBoundingClientRect();
return {
x: event.clientX - rect.left,
y: event.clientY - rect.top
};
}
function isInside(pos, rect)
{
return pos.x > (rect.x-(rect.x/100*10)) && pos.x < rect.x+rect.width && pos.y < rect.y+(rect.height/2) && pos.y > (rect.y-(rect.y/100*50));
}
function drawDropdown(selected, items, x, y, w, h){
ctx.strokeStyle = "black";
ctx.strokeRect(x,y, w,h);
ctx.fillText(selected, x+(x/10), y+(y/4));
}
function drawItems(labels, x,y, w,h)
{
for(var i=0; i < labels.length; i++)
{
if(i==0)
{
ctx.strokeRect(x, y+h, w,h);
ctx.fillText(labels[i], x+(x/10), y+h+(h/2));
}
else{
ctx.strokeRect(x, y+(h*(i+1)), w, h);
ctx.fillText(labels[i], x+(x/10), y+(h*(i+1))+(h/2));
}
}
}
function onItemClick(mousePos, labels)
{
if(isInside(mousePos, {x:itemDrop.x, y: mainDrop.y+(mainDrop.height*(labels.length)), width: mainDrop.width, height: mainDrop.height}))
{
var item = insideItem(mousePos);
var oldItem = selected;
if(item != selected)
newLabel(item, oldItem);
}
}
function insideItem(mousePos){
var mouseY = mousePos.y;
var startPos;
var nextPos;
for(var i=0; i < labels.length; i++)
{
startPos = mainDrop.y + (mainDrop.height*(i+1));
nextPos = startPos + mainDrop.height;
if(mouseY < nextPos && mouseY > startPos)
{
return labels[i];
}
}
return selected;
}
function newLabel(newLabel, removedLabel){
ctx.clearRect(mainDrop.x, mainDrop.y, canvas.width, canvas.height);
selected = newLabel;
labels[labels.indexOf(selected)] = removedLabel;
ctx.clearRect(0,0, canvas.width, canvas.height);
drawDropdown(selected, labels, mainDrop.x, mainDrop.y, mainDrop.width, mainDrop.height);
visible = false;
}
$('#canvas').on('mousemove', function(e){
var labelsHeight = mainDrop.y + mainDrop.height + (mainDrop.height * (labels.length+1));
var mousePos = getMousePos(canvas, e);
if(isInside(mousePos, mainDrop))
{
drawItems(labels, mainDrop.x, mainDrop.y, mainDrop.width, mainDrop.height);
visible = true;
}
else if(!isInside(mousePos, {x:mainDrop.x,y:mainDrop.x,width:mainDrop.width, height:labelsHeight}))
{
ctx.clearRect(0,0, canvas.width, canvas.height);
drawDropdown(selected, labels, mainDrop.x, mainDrop.y, mainDrop.width, mainDrop.height);
visible = false;
}
});
$('#canvas').click(function(e){
var labelsHeight = mainDrop.y + mainDrop.height*labels.length;
var mousePos = getMousePos(canvas, e);
if(visible)
onItemClick(mousePos, labels);
});
drawDropdown(selected, labels, mainDrop.x, mainDrop.y, mainDrop.width, mainDrop.height);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<canvas id="canvas"></canvas>