2015-06-18 181 views
1

我想创建一个用特殊的影子的效果。 像这样:创建一个带阴影的圆锥

Circle with shadow

它应该看起来像木材或金属的锥体。

我试图用画布上的放射状渐变做某件事,但我无法制作那种特殊的效果器。 我不知道如何创建这种阴影效果。

有人可以给我一个小费或帮助我吗?

这是我已经试过:JSFiddle

var canvas = document.getElementById('canvas'); 
var ctx = canvas.getContext('2d'); 

var x = 100, 
y = 75, 
innerRadius = 1, 
outerRadius = 70, 
radius = 60; 

ctx.arc(x, y, radius, 0, 2 * Math.PI); 

var gradient = ctx.createRadialGradient(x, y, innerRadius, x, y, outerRadius); 
gradient.addColorStop(0, '#FF9900'); 
gradient.addColorStop(1, '#FFFFFF'); 

ctx.fillStyle = gradient; 
ctx.fill(); 

来自德国 Matzuman

+1

您可能需要一个圆锥形与'RGBA(255,255,255更换'#FFFFFF' ,0)'。到'0'的渐变看起来比渐变到白色更好。 – Cerbrus

+0

好的谢谢,但重要的是阴影效果。有一点点深黄色和一点点淡黄色。对不起,我很难在英文中解释它: -/ – Matzuman

回答

2

不幸的是,在画布中没有渐变类型,可以指定一个辐射渐变。你必须提供一个机制来手动完成。

可能使用阴影方法将对象从屏幕上移开,同时偏移阴影以使其与锥体基部重叠。一个用于光源,另一个用于黑暗的一面。

通过根据角度在不同的不透明度水平下围绕中心旋转绘制“明暗条纹”,您可以获得更好的效果。

snap

示例“渲染”锥

这个例子允许您调整喜欢思考应该怎么可见的参数,找到你什么颜色,锥等与实验值的大小之后。

要抵消“光源”,只需在渲染重叠条纹之前先旋转一次所需的角度。

var ctx = document.querySelector("canvas").getContext("2d"), 
 
    cx = 75, cy = 75, radius = 70,  // for arc/cone 
 
    maxOpacity = 1,     // max opacity (will accumulate) 
 
    angleStep = 0.01,     // "resolution" 
 
    angle = 0, t;      // current angle and opacity 
 

 
// draw base of cone 
 
ctx.fillStyle = "rgb(139, 108, 33)"; 
 
ctx.arc(cx, cy, radius, 0, 2*Math.PI); 
 
ctx.fill(); 
 

 
// now rotate around center drawing a white stripe at varying opacity 
 
// depending on angle 
 
ctx.fillStyle = "rgb(181, 159, 109)"; 
 
ctx.translate(cx, cy);     // pivot for rotation = center of cone 
 

 
// half of the cone is done with white overlay 
 
for(angle = 0; angle < Math.PI; angle += angleStep) { 
 
    // calculate t [0,1] based on angle. Multiply with max opacity 
 
    t = (angle < Math.PI * 0.5 ? angle : Math.PI - angle)/Math.PI * maxOpacity; 
 
    ctx.rotate(angleStep);    // increase angle by step 
 
    ctx.globalAlpha = t;     // set opacity to t 
 
    drawStripe();      // draw a small segment/"stripe" 
 
} 
 

 
// the other half of the cone is done with dark overlay 
 
ctx.fillStyle = "rgb(95, 54, 5)"; 
 
for(angle = 0; angle < Math.PI; angle += angleStep) { 
 
    t = (angle < Math.PI * 0.5 ? angle : Math.PI - angle)/Math.PI * maxOpacity;; 
 
    ctx.rotate(angleStep); 
 
    ctx.globalAlpha = t; 
 
    drawStripe(); 
 
} 
 

 
function drawStripe() { 
 
    ctx.beginPath(); 
 
    ctx.lineTo(0, 0); 
 
    ctx.arc(0, 0, radius, 0, angleStep*5); 
 
    ctx.fill(); 
 
} 
 

 
// top off by drawing a smaller circle on top 
 
ctx.setTransform(1,0,0,1,0,0);   // reset transforms 
 
ctx.globalAlpha = 1;     // reset alpha 
 
ctx.fillStyle = "rgb(130, 97, 32)";  // draw in a topping 
 
ctx.beginPath(); 
 
ctx.arc(cx, cy, radius * 0.25, 0, 2*Math.PI); 
 
ctx.fill();
<canvas></canvas>

例近似与阴影

var ctx = document.querySelector("canvas").getContext("2d"), 
 
    cx = 75, cy = 75, radius = 70, offset = radius * 2; 
 

 
// draw base of cone 
 
ctx.fillStyle = "rgb(139, 108, 33)"; 
 
ctx.arc(cx, cy, radius, 0, 2*Math.PI); 
 
ctx.fill(); 
 

 
// offset next shape, couter-offset its shadow 
 
ctx.translate(cx, offset*2);     // make sure shape is drawn outside 
 
ctx.scale(0.75, 1);        // make shadow more narrow 
 
ctx.globalCompositeOperation = "source-atop"; // comp. on top of existing pixels 
 

 
ctx.shadowOffsetY = -offset * 1.1;    // counter-offset shadow 
 
ctx.shadowBlur = 25;       // some blur 
 
ctx.shadowColor = "rgba(181, 159, 109, 1)"; // highlight color 
 

 
ctx.beginPath();        // draw new shape 
 
ctx.arc(0, 0, radius * 0.6, 0, 2*Math.PI);  // reduce radius ~50% 
 
ctx.fill(); 
 

 
ctx.shadowOffsetY = -offset * 1.8;    // counter-offset shadow 
 
ctx.shadowColor = "rgba(95, 54, 5, 0.7)";  // shadow 
 
ctx.beginPath();        // draw new shape 
 
ctx.arc(0, 0, radius * 0.6, 0, 2*Math.PI);  // reduce radius ~50% 
 
ctx.fill(); 
 

 
// top off by drawing a smaller circle on top 
 
ctx.setTransform(1,0,0,1,0,0);     // reset transforms 
 
ctx.globalCompositeOperation = "source-over"; // reset comp. mode 
 
ctx.fillStyle = "rgb(130, 97, 32)";    // draw in a topping 
 
ctx.beginPath(); 
 
ctx.arc(cx, cy, radius * 0.25, 0, 2*Math.PI); 
 
ctx.fill();
<canvas></canvas>

+1

哇人,第一个例子看起来不错,我希望我可以整合它谢谢很多 – Matzuman

+0

@Matzuman没问题,很高兴我可以帮助! – K3N

0

问候尝试使用

ctx.shadowBlur = 40; 
ctx.shadowColor = "#FF9900"; 

画圆之前。 shadowBlur设置阴影的大小,如果要禁用它,可以将其设置为0。 shadowColor是相当自我解释。

+0

我试图做你说的,但我不能创造这种效果。阴影离开圆圈,圆圈有正常的颜色:-( – Matzuman

+0

你可以尝试做一个非常大的阴影非常小的圆圈 – Vanitas

+0

感谢您的帮助,但它没有工作。以stuid :-P。你有我的例子吗? – Matzuman