javascript - 当窗口很大时,HTML5 Canvas alpha 透明度在 Firefox 中对曲线不起作用

标签 javascript html firefox canvas transparency

我正在 HTML5 Canvas 上绘制一条曲线,并使用 alpha 透明度来创建发光效果,方法是在下面绘制一条 alpha 小于 1 的较厚版本的曲线,然后在上面绘制较薄的曲线版本顶部(我正在使用多个递归级别来完成此操作)。

好吧,问题就在这里。它的工作方式与我在 Chrome 中想要的完全一样,给出了美丽的发光效果。但在 Firefox 中,如果我的浏览器尺寸大于 300 像素左右,则 alpha 无法正确渲染(是的,这听起来很疯狂,但实际上出于某种原因它正在这样做)。如果我将浏览器的大小调整得非常小,那么 Alpha 会突然起作用并且我会得到令人惊叹的光芒。一旦我将窗口设置为合理的大小,Alpha 就不再起作用,所以我得到的不是一条发光线,而是一条非常粗的线。 :( 代码如下。

HTML:

<body>
    <canvas id="viewport">
    <script type="text/javascript" src="scripts/render.js"></script>
</body>

CSS:

* {
    background-color:#000000;
    padding:0px;
    margin:0px;
    width:100%;
    height:100%;
    overflow:hidden;
}

#viewport {
    border:0px;
}

Javascript:

window.viewport = document.getElementById("viewport");
window.context = viewport.getContext("2d");
window.xFactor = 1;
window.yFactor = 1;

function initializeViewport() {
    maximizeViewport();
    setFactors();
}

function maximizeViewport() {
    viewport.width = window.innerWidth;
    viewport.height = window.innerHeight;
}

function setFactors() {
    xFactor = window.innerWidth / 100;
    yFactor = window.innerHeight / 100;
}

function absX(x) {
    return Math.floor(x * xFactor);
}

function absY(y) {
    return Math.floor(y * yFactor);
}


function drawQuadraticCurve(startX, startY, controlX, controlY, endX, endY, lineWidth, gradient, alpha, glowiness, glowLevel) {
    glowLevel = (typeof glowLevel === 'undefined') ? 0 : glowLevel;

    // Draw the glow first
    if (glowLevel < glowiness) {
        drawQuadraticCurve(startX, startY, controlX, controlY, endX, endY, lineWidth + Math.sqrt(glowLevel), gradient, alpha*0.65, glowiness, glowLevel + 1);
    }

    // Then draw the curve
    context.beginPath();
    context.moveTo(absX(startX), absY(startY));
    context.quadraticCurveTo(absX(controlX), absY(controlY), absX(endX), absY(endY));
    context.lineWidth = lineWidth;
    context.strokeStyle = gradient;
    context.globalAlpha = alpha;
    context.shadowColor = "#FFFFFF";
    context.shadowBlur = 0;
    context.shadowOffsetX = 0;
    context.shadowOffsetY = 0;
    context.stroke();
}

    function createRadialGradient(colors, innerX, innerY, innerR, outerX, outerY, outerR) {
    var gradient = context.createRadialGradient(absX(innerX),absY(innerY),Math.min(absX(innerR/2), absY(innerR/2)),absX(outerX),absY(outerY),Math.min(absX(outerR/2), absY(outerR/2)));
    var gradientLength = colors.length;
    for (i=0; i<gradientLength; i++) {
        gradient.addColorStop(colors[i][0], colors[i][1]);
    }

    return gradient;
}


initializeViewport();
drawQuadraticCurve(80,65,20,70,70,10, 1,createRadialGradient([[0,"#FFFFFF"],[0.7,"#33CCFF"],[1,"#9944FF"]],50,50,1,50,50,90),1,8,0);

它在 Chrome 中运行的屏幕截图:/image/tUagK.png

它在 Firefox 中不起作用的屏幕截图: /image/m0HDU.png

我将窗口大小调整得小得离谱后,它在 Firefox 中工作的屏幕截图:/image/o2uGM.png

第一个可行的解决方案获得了赞成票和绿色复选标记!耶!

最佳答案

enter image description here

这是一条发光的二次曲线,由小的、单独的线段组成——每个线段都有不同的颜色。等于段颜色的阴影颜色会导致发光。渲染跨浏览器(包括FF)兼容。

(您可以控制线宽和发光强度)

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

// variables to define colors -- use hsl instead of rgb
var hue=10;
var hueShift=4;

// define the quadratic curve
var startPt={x:350,y:100};
var controlPt={x:0,y:250};
var endPt={x:350,y:400};

// variables defining the starting & ending point of 
// the current line segment.
var newXY=startPt;
var oldXY=startPt;

// the current interval along the quadratic curve
// (used to calc an x,y along the curve)
// (t is kind-of like a percentage along the curve--kind of but not)
var t=0;

// the unshadowed linewidth
ctx.lineWidth=1;

// the shadow to apply around the line
ctx.shadowBlur=7;

// round the endcaps to visually blend the line segments
ctx.lineCap='round';

// start with a black-filled canvas
ctx.fillStyle='black';
ctx.fillRect(0,0,cw,ch);

// start the animation
requestAnimationFrame(animate);


function animate(time){ 

  // calculate a new x,y along the curve
  var T=t/100;
  var newXY=getQuadraticBezierXYatT(startPt,controlPt,endPt,T);

  // change the color for this segment
  hue=(hue+hueShift)%360;

  // draw this line segment with a shadow-glow
  glowLine(oldXY,newXY,hue);

  // set old=new in preparation for the next loop
  oldXY=newXY;

  // request another animation loop intil reaching 100
  if(++t<100){
    requestAnimationFrame(animate);
  }
}

function glowLine(oldXY,newXY,hue){
  // calculate the hsl color given the new hue
  var hsl="hsl(" + (hue % 360) + ",99%,50%)";
  // draw a glowing line segment
  // (==a line segment with a shadow of the same color as the line segment)
  ctx.beginPath();
  ctx.moveTo(oldXY.x,oldXY.y);
  ctx.lineTo(newXY.x,newXY.y);
  ctx.fillStyle= hsl
  ctx.strokeStyle=hsl;
  ctx.shadowColor=hsl;
  // overdraw the line segment so it really stands out
  for(var i=0;i<6;i++){
    ctx.stroke();
  }
}

// calculate an [x,y] along a quadratic curve given an interval T
function getQuadraticBezierXYatT(startPt,controlPt,endPt,T) {
  var x = Math.pow(1-T,2) * startPt.x + 2 * (1-T) * T * controlPt.x + Math.pow(T,2) * endPt.x; 
  var y = Math.pow(1-T,2) * startPt.y + 2 * (1-T) * T * controlPt.y + Math.pow(T,2) * endPt.y; 
  return( {x:x,y:y} );
}
body{ background-color:ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=500 height=500></canvas>

关于javascript - 当窗口很大时,HTML5 Canvas alpha 透明度在 Firefox 中对曲线不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28492042/

相关文章:

javascript - HTML5/JavaScript/jQuery - 使用 jQuery 选择器时输入范围 .value() 变得未定义?

javascript - jquery中if语句中如何选择元素

html - 相同的 CSS 在非 chromium 浏览器上给出不同的结果

firefox - 如何在 Firefox 中获取 DOM 元素 Xpath

Ubuntu 上的 Python Selenium Firefox : New Tabs Not Working

javascript - Vue 2.X - 在组件中等待对比异步数据源的好方法

javascript - jQuery 的 $(this).parent().parent().find ('.active' ) 的 Zepto.js 替代品是什么?

javascript - URL 上的 HTML &lt;script&gt; 片段是否可以用于纯客户端应用程序中的 XSS?

html - 如何将 Internet Explorer 中的数据 URI 用作 URL?

html - 为什么我的 ASP Core MVC Razor 表单显示的输入框没有边距?