是否可以在canvas标签中创建下拉菜单

问题描述 投票:0回答:2

我正在使用HTML5 <canvas></canvas>标签,我一直试图找到有关是否可以在画布中包含下拉菜单的信息?

据我所知,这是不可能的。

html5 canvas drop-down-menu html5-canvas
2个回答
0
投票

不...

画布不是容器元素,因此您不能在画布中包含下拉菜单。

如果需要,您可以使用CSS在画布上定位下拉窗口小部件。


1
投票

看完这个问题后。我试图在画布上下拉。这是经过大量努力的结果:

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>
© www.soinside.com 2019 - 2024. All rights reserved.