当窗口较大时,HTML5 Canvas Alpha透明度在Firefox的曲线中不起作用 [英] HTML5 Canvas alpha transparency doesn't work in firefox for curves when window is big

查看:75
本文介绍了当窗口较大时,HTML5 Canvas Alpha透明度在Firefox的曲线中不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在HTML5画布上绘制曲线,并使用Alpha透明度创建发光效果,方法是在下面绘制Alpha小于1的较粗曲线,然后在Alpha上绘制较细的曲线顶部(并且我正在使用多个递归级别进行此操作。)



好的,这就是问题所在。它完全按照我希望在Chrome中使用的方式工作,并提供美丽的发光效果。但是在Firefox中,如果我的浏览器尺寸大于300px左右,则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%;
高度:100%;
溢出:隐藏;
}

#viewport {
border:0px;
}

JavaScript:

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

函数initializeViewport(){
maximumViewport();
setFactors();
}

函数maximumViewport(){
视口.width = window.innerWidth;
viewport.height = window.innerHeight;
}

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

函数absX(x){
返回Math.floor(x * xFactor);
}

函数absY(y){
返回Math.floor(y * yFactor);
}


函数drawQuadraticCurve(startX,startY,controlX,controlY,endX,endY,lineWidth,渐变,alpha,辉光度,glowLevel){
glowLevel =( typeof glowLevel ==='未定义')? 0:glowLevel;

//首先绘制辉光
if(glowLevel< glowiness){
drawQuadraticCurve(startX,startY,controlX,controlY,endX,endY,lineWidth + Math.sqrt( glowLevel),渐变,alpha * 0.65,发光度,glowLevel + 1);
}

//然后绘制曲线
context.beginPath();
context.moveTo(absX(startX),absY(startY));
context.quadraticCurveTo(absX(controlX),absY(controlY),absX(endX),absY(endY));
context.lineWidth = lineWidth;
context.strokeStyle =渐变;
context.globalAlpha = alpha;
context.shadowColor = #FFFFFF;
context.shadowBlur = 0;
context.shadowOffsetX = 0;
context.shadowOffsetY = 0;
context.stroke();
}

函数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]);
}

收益梯度;
}


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中工作的屏幕截图: http://i.imgur.com/brVT2i6.png



在Firefox中无法使用的屏幕截图: http://i.imgur.com/63Z4PJY.png



在将窗口的大小调整为可笑后,它在Firefox中工作的屏幕截图: http://i.imgur.com/d9AihEu.png



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

解决方案



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



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



  var canvas = document.getElementById( canvas); var ctx = canvas.getContext( 2d); var cw = canvas .width; var ch = canvas.height; //定义颜色的变量-使用hsl代替rgbvar hue = 10; var hueShift = 4; //定义二次曲线var startPt = {x:350,y:100}; var controlPt = {x:0,y:250}; var endPt = {x:350,y:400}; //定义开始& //当前线段的终点.var newXY = startPt; var oldXY = startPt; //沿二次曲线的当前间隔//(用于计算沿曲线的x,y)//(t是-像沿着曲线的百分比一样-种类不为var t = 0; //无阴影的线宽ctx.lineWidth = 1; //围绕linectx.shadowBlur = 7施加的阴影; //使端盖圆角可见混合线段ctx.lineCap ='round'; //从黑色填充的画布开始ctx.fillStyle ='black'; ctx.fillRect(0,0,cw,ch); //开始animationrequestAnimationFrame(animate);功能animate(time){//沿曲线var T = t / 100计算新的x,y; var newXY = getQuadraticBezierXYatT(startPt,controlPt,endPt,T); //更改此段的颜色hue =(hue + hueShift)%360; //用阴影发光glowLine(oldXY,newXY,hue);绘制此线段//设置old = new为下一个循环做准备oldXY = newXY; //请求另一个动画循环,直到达到100 if(++ t< 100){requestAnimationFrame(animate); }} function glowLine(oldXY,newXY,hue){//根据给定的新色调计算hsl颜色var hsl = hsl( +(hue%360)+,99%,50%); //绘制发光的线段//(==线段的阴影与线段的颜色相同)ctx.beginPath(); ctx.moveTo(oldXY.x,oldXY.y); ctx.lineTo(newXY.x,newXY.y); ctx.fillStyle = hsl ctx.strokeStyle = hsl; ctx.shadowColor = hsl; //覆盖线段,以使其真正脱颖而出(var i = 0; i< 6; i ++){ctx.stroke(); }} //给定间隔T函数,沿二次曲线计算[x,y] 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;内边距:10px; } #canvas {border:1px纯红色;}  

 < ; canvas id = canvas width = 500 height = 500>< / canvas>  


I'm drawing a curve on an HTML5 canvas and am using alpha transparency to create a glow effect, by drawing a thicker version of the curve underneath with an alpha of less than 1, then drawing a thinner version of the curve on top (and I'm doing this with several levels of recursion).

Okay here's the problem. It works exactly the way I want it to in Chrome, giving a beautiful glow effect. But in Firefox, the alpha doesn't render properly if my browser dimensions are bigger than around 300px in height (yes that sounds crazy but it is actually what it is doing for some reason). If I resize my browser to be extremely tiny, then all the sudden the alpha works and I get my awesome glow. Once I make the window a reasonable size, the alpha no longer works so instead of a glowing line I just get a really thick line. :( Code is below.

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);

Screenshot of it working in Chrome: http://i.imgur.com/brVT2i6.png

Screenshot of it NOT working in Firefox: http://i.imgur.com/63Z4PJY.png

Screenshot of it working in Firefox after I've resized the window to be ridiculously small: http://i.imgur.com/d9AihEu.png

First working solution gets an upvote and a green checkmark! Yay!

解决方案

Here is a glowing quadratic curve made up of small, individual line segments--each segment being a different color. A shadowColor equal to the segment color causes the glow. The rendering is compatible across browsers (including FF).

(You can control the linewidth and the glow strength)

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>

这篇关于当窗口较大时,HTML5 Canvas Alpha透明度在Firefox的曲线中不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆