我在HTML5画布上绘制一条曲线并使用Alpha透明度创建一个发光效果,方法是在下面绘制一个较小版本的曲线,其alpha值小于1,然后绘制一个更薄的曲线版本顶部(我正在使用几个递归级别执行此操作)。
好的,这是问题所在。它的工作方式与我想要的方式完全一致,给人一种美丽的发光效果。但是在Firefox中,如果我的浏览器尺寸大于300px的高度,那么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中工作的屏幕截图:http://i.imgur.com/brVT2i6.png
它在Firefox中不起作用的屏幕截图:http://i.imgur.com/63Z4PJY.png
在我将窗口调整为非常小的窗口之后,在Firefox中工作的屏幕截图:http://i.imgur.com/d9AihEu.png
首个工作解决方案获得一个upvote和一个绿色复选标记!耶!
答案 0 :(得分:1)
这实际上是一个评论,但它不适合分配给评论的空间。 : - )
我已经咨询了Html5 Canvas的全知 - Oracle - w3.org。
如果您指定零shadowBlur(正如您所做),则规格应该不应用阴影。
这意味着具有较大画布尺寸的FF正确应用w3标准(不绘制任何阴影)以及Chrome和&amp ;; FF(较小版本)不应该应用阴影。
http://www.w3.org/TR/2dcontext/
仅在alpha组件的不透明度组件中绘制阴影 shadowColor的颜色是非零,shadowBlur是 非零,或者shadowOffsetX为非零,或者shadowOffsetY为 非零的。
因此,为了实现跨浏览器兼容性,在shadowBlur=0
时,您不能依赖渲染中的怪癖。你必须在“规则”中以另一种方式创造你的光芒。
答案 1 :(得分:1)
这是一条由小的单独线段组成的发光二次曲线 - 每个线段都是不同的颜色。 shadowColor等于分段颜色会导致发光。渲染在浏览器(包括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>