代码之家  ›  专栏  ›  技术社区  ›  TomáÅ¡ Zato

使前景透明,但不使背景透明

  •  2
  • TomáÅ¡ Zato  · 技术社区  · 6 年前

    我正在做一些试验,我已经设定了以下挑战,但现在我无法解决。我正在为Flyspray Bug跟踪器编写用户脚本。在问题列表中,有一列指示完成百分比:

    enter image description here

    这个系统相当古老,给它一种简单的美。这是进度的HTML:

    <td class="task_progress">
        <img src="/themes/Bluey/percent-70.png" alt="70%">
    </td>
    

    简洁明了。现在我想做的是将鼠标移动的进度移到 <img> ,不更改HTML。如果我能使前景半透明并设置一个CSS渐变背景,就可以做到这一点。

    我可以通过包装 <IMG & GT; 在里面 <span> 但是很笨拙。

    const wrapped = document.querySelector("#wrapped");
    const img = wrapped.querySelector("img");
    const box = img.getBoundingClientRect();
    //wrapped.style.height = (box.bottom-box.top)+"px";
    
    const bg = "linear-gradient(to right, rgba(0,38,114,1) 0%,rgba(0,38,114,1) 50%,rgba(0,38,114,0) 51%,rgba(0,38,114,0) 100%)";
    console.log(wrapped);
    wrapped.addEventListener("mousemove", (e)=>{
        const box = wrapped.getBoundingClientRect();
        const mousePos = e.clientX - box.left;
        const max = box.right-box.left;
        const perc = 100*(mousePos/max);
        
        const gradient = bg
                   .replace("50%", (perc-0.5)+"%")
                   .replace("51%", (perc+0.5)+"%");
        //console.log(gradient);
        ///console.log(perc);
        wrapped.style.backgroundImage = gradient;
        wrapped.style.color = "red";
    }, {capture: false});
    #wrapped {
       display: inline-block;
       margin: 0px;
       padding: -1px;
       border-width: 1px;
       border-color:transparent;
       border-style: solid;
       
       position: relative;
       
       background-position: center center;
       
       background-repeat: no-repeat;
       
       background-size: 0px 0px;
    }
    #wrapped img {
       margin: 0px;
       padding: 0px;
       
       position: relative;
       
       top:0px;
       left: 0px;
    }
    #wrapped:hover img {
        opacity: 0.3;
    }
    #wrapped:hover {
        /*border-color:#002672;*/
        background-size: 100% 8.82px;
    }
    <span id="wrapped"><img src="https://i.stack.imgur.com/lymku.png" /></span>

    上述解决方案的主要问题是:包装器的高度与 <IMG & GT; 高度,这意味着背景尺寸必须精确设置为像素。

    enter image description here

    有办法吗 没有任何包装元素?

    请注意,这是一个练习/学习类的问题,通过其他方式解决整个问题的解决方案对我来说毫无用处。

    1 回复  |  直到 6 年前
        1
  •  3
  •   Temani Afif    6 年前

    不要使用透明颜色的渐变。只使用纯色并控制 background-size 然后简单地做 img 阻止元素以避免空白问题:

    不确定是否可以不使用包装器,因为您需要一个元素来应用渐变:

    const wrapped = document.querySelector("#wrapped");
    const img = wrapped.querySelector("img");
    const box = img.getBoundingClientRect();
    //wrapped.style.height = (box.bottom-box.top)+"px";
    
    const bg = "linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1))";
    console.log(wrapped);
    wrapped.addEventListener("mousemove", (e)=>{
        const box = wrapped.getBoundingClientRect();
        const mousePos = e.clientX - box.left;
        const max = box.right-box.left;
        const perc = 100*(mousePos/max);
    
        //console.log(gradient);
        ///console.log(perc);
        wrapped.style.backgroundSize =perc+"% 100%";
        wrapped.style.color = "red";
    }, {capture: false});
    #wrapped {
       display: inline-block;
       margin: 0px;
       /*padding: -1px; there is no negative padding */
       border-width: 1px;
       border-color:transparent;
       border-style: solid;
       
       background-position:left;
       background-repeat: no-repeat;
    }
    #wrapped img {
       display:block;
    }
    #wrapped:hover img {
        opacity: 0.3;
    }
    #wrapped:hover {
        /*border-color:#002672;*/
        background-image:linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1));
        background-size: 50% 100%;
    }
    <span id="wrapped"><img src="https://i.stack.imgur.com/lymku.png" /></span>

    但是,您可能会考虑一个具有多个背景的想法,以避免出现图像,并且在结尾处有一个元素将替换图像:

    const wrapped = document.querySelector("#wrapped");
    
    
    wrapped.addEventListener("mousemove", (e)=>{
        const box = wrapped.getBoundingClientRect();
        const mousePos = e.clientX - box.left;
        const max = box.right-box.left;
        const perc = 100*(mousePos/max);
    
        wrapped.style.backgroundSize =perc+"% 100%, 60% 100%";
    }, {capture: false});
    #wrapped {
       display: inline-block;
       border-width: 1px;
       border-style: solid;
       border-color:rgba(0,38,114,1);
       height:10px;
       width:100px;
        background-image:
          linear-gradient(transparent,transparent),
          linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1));
        background-size: 60% 100%;
       background-position:left;
       background-repeat: no-repeat;
    }
    #wrapped:hover {
       border-color:rgba(0,38,114,0.5);
        background-image:
          linear-gradient(rgba(0,38,114,1),rgba(0,38,114,1)),
          linear-gradient(rgba(0,38,114,0.5),rgba(0,38,114,0.5));
    }
    <span id="wrapped"></span>