创建一个带阴影的圆锥

时间:2015-06-18 08:19:07

标签: javascript canvas html5-canvas

我想创建一个带有特殊阴影效果的。 像这样:

Circle with shadow

它应该看起来像木头或金属的锥形。

我尝试用画布中的径向渐变做一些事情,但我不能创造那种特殊的Effekt。 我不知道如何创建这个阴影效果。

有人可以给我一个提示或帮助我吗?

这是我尝试过的: 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

2 个答案:

答案 0 :(得分:1)

不幸的是,画布中没有渐变类型允许您指定辐射渐变。您必须提供手动执行此操作的机制。

可以使用阴影方法在屏幕外绘制对象,同时偏移阴影,使其与圆锥底座重叠。一个用于光,一个用于暗色。

你可以通过在中心周围以不同的不透明度水平旋转“亮/暗条纹”来获得更好的效果。

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 :(得分:0)

尝试使用

ctx.shadowBlur = 40;
ctx.shadowColor = "#FF9900";
在绘制圆之前

shadowBlur设置阴影的大小,如果要禁用它,可以将其设置为0。 shadowColor非常自我解释。