开发者

how to give cone or cylinder a 3d effect using javascript on the canvas? And how to fill the desired color in them?

I am doing a BE final year project so i n开发者_运维百科eed your help. how to give cone or cylinder a 3d effect using javascript on the canvas? And how to fill the desired color in them so that the same 3D effect is maintained even if the object is rotated or displaced or scaled?


The 3D effect for a cylinder can be emulated using a 4 stop gradient.

For example, if you want a red cylinder, you can do something like:

  • Red
  • Lighter Red
  • Red
  • Darker Red
  • Red

People may tweak those ratios somewhat, but what's listed above will give you the desired effect. Obviously, the direction of your gradient is going to have to be perpendicular to the length of your cylinder.

You use something like the xColor JS library to get lighter and darker colours.

So you'd have something like this:

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

  var x1 = 0, x2 = 20, y1 = 0, y2 = 100;

  var lingrad = ctx.createLinearGradient(x1,y1,x2,y1);
  lingrad.addColorStop(0, 'red');
  lingrad.addColorStop(0.25, $.xcolor.lighten('red', 1));
  lingrad.addColorStop(0.5, 'red');
  lingrad.addColorStop(0.75, $.xcolor.darken('red', 1));
  lingrad.addColorStop(1, 'red');

  ctx.fillStyle = lingrad;   
  ctx.fillRect(x1,y1,x2-x1,y2-y1);
}

I'm pretty sure rotation will apply to everything, so you don't have to worry about that except for one caveat. The illusion relies on the idea that we're predisposed to expect objects to be illuminated from above (probably that big fiery ball in the sky). So once you rotate beyond vertical, you may need to reverse the gradient. The effect may be jarring though.

Give it a try.

UPDATE: Did this for a demo - hope it helps

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

var cylinder = {width: 30, height: 100};

var x = -cylinder.width / 2;
var y = -cylinder.height / 2;
var baseColor = "#c00";

var tick = 0;

function draw() {
    context.clearRect(0, 0, context.canvas.width, context.canvas.height);

    context.save();

    context.translate(context.canvas.width / 2, context.canvas.height / 2);

    var gradient = context.createLinearGradient(x, y, x + cylinder.width, y);
    gradient.addColorStop(0, baseColor);
    gradient.addColorStop(0.25, $.xcolor.lighten(baseColor, 1));
    gradient.addColorStop(0.5, baseColor);
    gradient.addColorStop(0.75, $.xcolor.darken(baseColor, 0.5));
    gradient.addColorStop(1, baseColor);

    context.rotate(tick++ / 180 * Math.PI);

    context.fillStyle = gradient;
    context.fillRect(x, y, cylinder.width, cylinder.height);

    context.restore();

    console.log("Tick");
}

setInterval(draw, 1000 / 20);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://rawgithub.com/infusion/jQuery-xcolor/master/jquery.xcolor.min.js"></script>
<!DOCTYPE html>
<html>
<head>
    <title>Cylinder effect</title>
    <script src="/javascripts/jquery-1.5.1.js"></script>
    <script src="/javascripts/jquery.xcolor.js"></script>
</head>
<body>
<div style="margin-left:auto;margin-right:auto;margin-top: 100px;width:640px;height:480px;border:1px solid gray">
    <canvas id="canvas" width="640" height="480"></canvas>
</div>


</body>
</html>

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜