如何在DIV中创建一个洞?

时间:2015-05-14 16:40:15

标签: html css html5 css3 html5-canvas

所以说我有以下HTML结构:

<canvas></canvas>
<div class="overLay">
    <button>Click me!</button>
</div>

画布绝对定位为负z索引,因此叠加层位于其上方(我有那么多工作)。问题是我希望叠加div具有白色背景,但是按钮具有透明背景并显示到画布/主体背景颜色。

background-color:rgba(0,0,0,0); 

不起作用,因为它只显示背后的白色背景。关于如何实现这种效果的任何想法?

这可能被标记为潜在重复的问题未能说明按钮可能具有border-radius等属性并且没有提供合适的解决方案。

4 个答案:

答案 0 :(得分:0)

无法在HTML元素中创建一个洞。透明背景只能应用于不会从具有非透明背景的父级下降的元素。

你能做什么,认为它有点复杂,就是在你的按钮周围创建div,与兄弟姐妹一样。给这些div一个白色背景,然后你的透明按钮应该工作。

我使用表格布局创建了一个示例,其中按钮保留在中间单元格的中间行。看到按钮显示画布背景颜色:

&#13;
&#13;
canvas {
    width: 200px;
    height: 200px;
    background: purple;
    position: absolute;
    z-index: -1;
}

.overLay {
    width: 200px;
    height: 200px;
    display: table;
}

.overLay button {
    background-color: Transparent;
    white-space: nowrap;
}

.overLay > div {
    display: table-row;
}

.overLay > .middle {
    height: 1px;
}

.overLay > div > div {
    display: table-cell;
    text-align: center;
}

.overLay > .middle > div:nth-child(2) {
    width: 1px;
}

/* Now, set the background on the divs around the button */
.top, .left, .right, .bottom {
    background: white;
}
&#13;
<canvas></canvas>
<div class="overLay">
    <div class="top">
        <div></div>
        <div></div>
        <div></div>
    </div>
    <div class="middle">
        <div class="left"></div>
        <div>
            <button>Click me!</button>
        </div>
        <div class="right"></div>
    </div>
    <div class="bottom">
        <div></div>
        <div></div>
        <div></div>
    </div>
</div>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

因为在我的原始答案中,您指出了使用边界半径的意图。因此,还有另一种方法可以实现这一目标。

基于this asnwer

使用渐变半径背景制作叠加层,在按钮的大小下,在您想要按钮的位置创建渐变色中心。将外部颜色设为white,将内部颜色设为Transparent;

然后,设置按钮的位置。 (我通过将它放在表格布局中来实现这一点):

&#13;
&#13;
canvas {
    width: 200px;
    height: 200px;
    background: purple;
    position: absolute;
    z-index: -1;
}

.overLay {
    width: 200px;
    height: 200px;
    display: table;
    background-color: white;
    background: -webkit-radial-gradient(50% 50%, circle, transparent 25px, white 0px);
    background: radial-gradient(50% 50%, circle, transparent 25px, white 0px);
}

.overLay > div {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}

button {
    background-color: transparent;
    border-radius: 50%;
    width: 50px;
    height: 50px;
    position: relative;
}
&#13;
<canvas></canvas>
<div class="overLay">
    <div>
        <button>Click me!</button>
    </div>
</div>
&#13;
&#13;
&#13;

答案 2 :(得分:0)

嗯......,你有没有考虑过使用带掩码的SVG元素?这应该够了吧。看一下片段。

body {
  padding: 0;
  margin: 0;
}
.your-canvas {
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
}
button {
  width: 150px;
  height: 100px;
  background-color: transparent;
  color: white;
  cursor: pointer;
}
<div class="your-canvas">
  <img width="512" alt="Weingarten Kuppel 8" src="//upload.wikimedia.org/wikipedia/commons/thumb/d/dd/Weingarten_Kuppel_8.jpg/512px-Weingarten_Kuppel_8.jpg"/>
</div>
<svg height="324" width="512">
  <defs>
    <mask id="mask">
      <rect width="512" height="324" fill="white"/>
      <rect x="181" y="112" width="150" height="100" fill="black"/>
    </mask>
  </defs>
  <rect width="512" height="324" style="fill:rgba(255,0,0,.6);" mask="url(#mask)"/>
  <foreignObject class="node" x="181" y="112" width="150" height="100">
    <body xmlns="http://www.w3.org/1999/xhtml">
      <button>Click Me</button>
    </body>
  </foreignObject>
</svg>

据我所知,甚至可以在纯css中使用屏蔽,但没有时间查找它。以下是有关使用带有svg Clipping and masking的掩码的一些信息。

玩得开心。

答案 3 :(得分:0)

你可以......

  • 将画布元素缩小为按钮大小(==按钮画布!),
  • 使用CSS根据需要定位按钮画布在div上
  • 在画布上添加单击事件侦听器
  • 在按钮画布上绘制所需的任何设计。

通过这种方式,您可以使用canvas元素提供的令人惊叹的绘图工具完全灵活。

这是示例代码和(幻想的)演示。

虽然这个演示只是为了好玩,但您可以轻松地重新设计此示例&amp;把它变成一个可重复使用的小部件:

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var width=80;
var height=40;
var borderwidth=4;
var x=0;
var y=0;
x+=borderwidth;
y+=borderwidth/2;
var w=width-borderwidth-borderwidth;
var h=height-borderwidth;
var depth=5;
//
var stopCount=8;
var angle=0;
var angleDelta=360;
//
var labelColor='black';

canvas.width=width;
canvas.height=height;

requestAnimationFrame(animate);

$("#canvas").mousedown(function(e){handleMouseDown(e);});
$("#canvas").mouseup(function(e){handleMouseUp(e);});
$("#canvas").mouseout(function(e){handleMouseUp(e);});


function makeGradient(){
  var g=ctx.createLinearGradient(0,0,cw,0);
  for(var i=0;i<stopCount;i++){
    var stop=i/stopCount;
    var hslDegrees=(angle+angleDelta*stop)%360;
    var hsl="hsl(" + hslDegrees + ",100%, 50%)"
    g.addColorStop(stop,hsl);
  }
  return(g);
}

function animate(){
  ctx.clearRect(0,0,cw,ch);
  gradientBorder();
  ctx.font='12px verdana';
  ctx.fillStyle=labelColor;
  ctx.fillText('Click Me',x+10,y+25);
  angle++;
  requestAnimationFrame(animate);
}

//
function gradientBorder(){
  var lw=ctx.lineWidth
  var ss=ctx.strokeStyle;
  ctx.lineWidth=borderwidth;
  ctx.strokeStyle=makeGradient();
  //
  ctx.beginPath();
  ctx.moveTo(x+w-depth,y);
  ctx.lineTo(x+depth,y);
  ctx.bezierCurveTo(  x-depth/2,y+h*1/6,  x+depth*2,y+h*2/6, x,y+h/2);
  ctx.bezierCurveTo(  x+depth*2,y+h*4/6,  x-depth/2,y+h*5/6, x+depth,y+h);
  ctx.lineTo(x+w-depth,y+h);
  ctx.bezierCurveTo(  x+w+depth/2,y+h*5/6, x+w-depth*2,y+h*4/6, x+w,y+h/2);
  ctx.bezierCurveTo(  x+w-depth*2,y+h*2/6, x+w+depth/2,y+h*1/6, x+w-depth,y);
  ctx.closePath();
  ctx.stroke();
  //
  var b2=borderwidth/2;
  ctx.beginPath();
  ctx.moveTo(x+w-depth-1,y+b2);
  ctx.lineTo(x+depth+2,y+b2);
  ctx.bezierCurveTo(  x-depth/2+b2+2,y+h*1/6+1,  x+depth*2+b2,y+h*2/6, x+b2+1,y+h/2);
  ctx.bezierCurveTo(  x+depth*2+b2,y+h*4/6+1,  x-depth/2+b2+1,y+h*5/6, x+depth+b2-2,y+h-b2);
  ctx.strokeStyle='#666';
  ctx.lineWidth=0.50;

  ctx.moveTo(x+depth+b2-2,y+h-b2);
  ctx.lineTo(x+w-depth-2,y+h-b2);
  ctx.bezierCurveTo(  x+w+depth/2-b2-2,y+h*5/6, x+w-depth*2-b2+1,y+h*4/6, x+w-b2-2,y+h/2);
  ctx.bezierCurveTo(  x+w-depth*2-b2+1,y+h*2/6, x+w+depth/2-b2-2,y+h*1/6, x+w-depth-b2+3,y+b2);
  ctx.strokeStyle='#666';
  ctx.lineWidth=0.50;
  ctx.stroke();
  //
  ctx.strokeStyle=ss;
  ctx.lineWidth=lw;

  ctx.fillStyle='gainsboro';
  ctx.fill();
}

function handleMouseDown(e){ labelColor='red'; }

function handleMouseUp(e){ labelColor='black'; }
body{ background-color:white; }
.demo{
  width:200px;
  height:100px;
  border:1px solid red;
  position:relative;
}
#canvas{
  position:absolute;
  left:10px;
  top:10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div class='demo'>
  <canvas id="canvas"></canvas>
</div>