创建一个带阴影的圆锥体
Create a cone with shadows
我想创建一个具有特殊 阴影 效果的 圆。
喜欢这个:
.
它应该看起来像木头或金属制成的锥体。
我试图用 canvas 中的径向渐变做一些事情,但我无法创建那种特殊的效果。
我不知道如何创建这种阴影效果。
有人可以给我提示或帮助我吗?
这是我试过的: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();
来自德国的问候
马祖曼
尝试使用
ctx.shadowBlur = 40;
ctx.shadowColor = "#FF9900";
画圆之前。
shadowBlur
设置阴影的大小,如果你想禁用它可以设置为0。
shadowColor
不言自明。
不幸的是 canvas 中没有渐变类型允许您指定辐射渐变。您必须提供一种机制来手动执行此操作。
您可以使用阴影方法在屏幕外绘制对象,同时偏移阴影,使其与圆锥体底部重叠。一个是亮的,一个是暗的。
通过绘制一个“light/dark 条纹”,根据角度以不同的不透明度级别围绕中心旋转,可以获得更好的效果。
“渲染”圆锥体的示例
此示例允许您调整参数,例如反射的可见度、颜色、锥体大小等。试验这些值以找到您想要的。
要偏移“光源”,只需在渲染重叠条纹之前以您需要的角度旋转一次。
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>
我想创建一个具有特殊 阴影 效果的 圆。 喜欢这个:
它应该看起来像木头或金属制成的锥体。
我试图用 canvas 中的径向渐变做一些事情,但我无法创建那种特殊的效果。 我不知道如何创建这种阴影效果。
有人可以给我提示或帮助我吗?
这是我试过的: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();
来自德国的问候 马祖曼
尝试使用
ctx.shadowBlur = 40;
ctx.shadowColor = "#FF9900";
画圆之前。
shadowBlur
设置阴影的大小,如果你想禁用它可以设置为0。
shadowColor
不言自明。
不幸的是 canvas 中没有渐变类型允许您指定辐射渐变。您必须提供一种机制来手动执行此操作。
您可以使用阴影方法在屏幕外绘制对象,同时偏移阴影,使其与圆锥体底部重叠。一个是亮的,一个是暗的。
通过绘制一个“light/dark 条纹”,根据角度以不同的不透明度级别围绕中心旋转,可以获得更好的效果。
“渲染”圆锥体的示例
此示例允许您调整参数,例如反射的可见度、颜色、锥体大小等。试验这些值以找到您想要的。
要偏移“光源”,只需在渲染重叠条纹之前以您需要的角度旋转一次。
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>