如何创建一个渐变弯曲?

8

我正在使用Javascript编写贪吃蛇游戏。为了渲染不同身体部位的背景,我使用以下渐变生成方式:

gibGradient: function() {
    var string = "background: linear-gradient(to right, rgba(243,226,199,1) 15%,rgba(193,158,103,1) "+ snake.data.gradientLinks +"%,rgba(182,141,76,1) "+ snake.data.gradientRechts +"%,rgba(233,212,179,1) 90%);";
    if ((snake.data.gradientLinks < 85) && (snake.data.modus == "hochzaehlen")) {
        snake.data.gradientLinks = snake.data.gradientLinks + 5;
        snake.data.gradientRechts = snake.data.gradientRechts + 5;
        if (snake.data.gradientLinks >= 85) {
            snake.data.modus = "runterZaehlen";
        }
    }

    if ((snake.data.gradientLinks > 20) && (snake.data.modus == "runterZaehlen")) {
        snake.data.gradientLinks = snake.data.gradientLinks - 5;
        snake.data.gradientRechts = snake.data.gradientRechts - 5;
        if (snake.data.gradientLinks <= 20) {
            snake.data.modus = "hochzaehlen";
        }
    }
    return string;
},

我的问题是,当蛇移动并改变方向时,渐变需要弯曲以适应角落结束前的最后一个身体部位和跟随蛇身直线的最后一个身体部位。
例如:
我正在使用10x10像素的div元素。
现在我需要在蛇拐角移动时进行过渡。
有人有想法吗?

梯度的方向是垂直于蛇的纵轴还是平行于它?一张图片可能会有所帮助。也许一个简单的“径向渐变”可以解决你的问题。 - Bergi
你能提供一张你所说的内容的图片吗? - chiliNUT
你是在使用画布(Canvas)还是其他元素? - Logan Murphy
您可以使用径向渐变来制作角落 https://developer.mozilla.org/zh-CN/docs/Web/CSS/radial-gradient 您可以根据需要设置大小和偏移量。 - Logan Murphy
使用 border-radius 可以实现圆角效果。 - rafaelcastrocouto
1
你可以通过包含一个角度来旋转渐变:linear-gradient(45deg, 红色, 蓝色); - Logan Murphy
1个回答

6
我花了些时间编写了一些实用的 JavaScript 函数,您可能会发现它们很有用。但是,它们需要使用 jQuery 库。创建弯曲渐变的最佳方法是使用偏移径向渐变。结合边框半径可以产生非常好的效果。
现在,由您来:
  • 在正确的时间使用正确的函数(函数的命名约定是sideA_To_sideB,因此rightToUp意味着向右移动最终会找到 sideA,向上移动最终会找到 sideB - 两侧相当于头部或尾部)
  • 使其兼容所有浏览器 (如果您需要)
  • 将头部和尾部圆角化会是不错的选择(理想情况下,此圆角只会出现在垂直和水平部分)
随意更改变量大小以适应您的需求。 编辑——基于您刚才添加的图像,我创建了此代码:jsfiddle http://jsfiddle.net/Lbydhhkh/。使用旋转线性渐变完成这个代码。但我仍然认为使用原始方法会更好,也更有意义。尽管如此,这应该足以让您走向正确的方向。伪代码仍然适用于这个新代码。

var size = 40;

function aToB(gradient) {
    return $("<div>").css({
        width: size,
        height: size,
        background: gradient,
        position: "absolute"
    });
}

function radialOut(x, y, corner) {
    var css = {};
    css["border-" + corner + "-radius"] = size / 2;
    return aToB([
        "radial-gradient(",
    size,
        "px at ",
    x,
        "px ",
    y,
        "px, red, blue)"].join("")).css(css);
}

function radialIn(x, y, corner) {
    var css = {};
    css["border-" + corner + "-radius"] = size / 2;
    return aToB([
        "radial-gradient(",
    size,
        "px at ",
    x,
        "px ",
    y,
        "px, blue, red)"].join("")).css(css);
}

function downToUp() {
    return aToB("linear-gradient(to left, red, blue)");
}

function rightToLeft() {
    return aToB("linear-gradient(to bottom, red, blue)");
}

function upToDown() {
    return aToB("linear-gradient(to right, red, blue)");
}

function leftToRight() {
    return aToB("linear-gradient(to top, red, blue)");
}

function upToRight() {
    return radialIn(size, 0, "bottom-left");
}

function leftToUp() {
    return radialIn(0, 0, "bottom-right");
}

function downToLeft() {
    return radialIn(0, size, "top-right");
}

function rightToDown() {
    return radialIn(size, size, "top-left");
}

function rightToUp() {
    return radialOut(size, 0, "bottom-left");
}

function upToLeft() {
    return radialOut(0, 0, "bottom-right");
}

function leftToDown() {
    return radialOut(0, size, "top-right");
}

function downToRight() {
    return radialOut(size, size, "top-left");
}

$(function () {
    //inner
    $("body").append(upToDown().css({
        top: size,
        left: 0
    })).append(upToRight().css({
        top: size * 2,
        left: 0
    })).append(leftToRight().css({
        top: size * 2,
        left: size
    })).append(leftToUp().css({
        top: size * 2,
        left: size * 2
    })).append(downToUp().css({
        top: size,
        left: size * 2
    })).append(downToLeft().css({
        top: 0,
        left: size * 2
    })).append(rightToLeft().css({
        top: 0,
        left: size
    })).append(rightToDown().css({
        top: 0,
        left: 0
    }));

    //outer
    $("body").append(leftToDown().css({
        top: 0,
        left: size * 5
    })).append(upToDown().css({
        top: size,
        left: size * 5
    })).append(upToLeft().css({
        top: size * 2,
        left: size * 5
    })).append(rightToLeft().css({
        top: size * 2,
        left: size * 4
    })).append(rightToUp().css({
        top: size * 2,
        left: size * 3
    })).append(downToUp().css({
        top: size * 1,
        left: size * 3
    })).append(downToRight().css({
        top: 0,
        left: size * 3
    })).append(leftToRight().css({
        top: 0,
        left: size * 4
    }));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

以下是一些伪代码,可帮助你调用相应的函数

while(nextPart()) { //while there are more parts to process
    var prev = getPrev(), //returns null or previous part
        curr = getCurrent(), //returns current part
        next = getNext(), //returns null or next part
        a, b, part = [];

    //get the direction towards the tail
    if(prev) a = curr.getDirectionTo(prev); //returns "up", "right", "down", or "left"
    else a = tail.getOppositeDirection(); //returns "up", "right", "down", or "left"

    //get the direction towards the head
    if(next) b = curr.getDirectionTo(next);
    else b = head.getDirection(); //returns "up", "right", "down", or "left"

    b = upperCaseFirstLetter(b);

    if(!prev) part.push("tail"); //is this a tail?
    if(!next) part.push("head"); //is this a head?

    //the following line of code calls a function with the form "aToB"
    //the variable part does not do anything yet but it can help the called  
    //function determine if this part is a head, tail, or both for rounding
    var domElement = window[a + "To" + b](part); 
    domElement.css(curr.position()); //properly position the element
    $("#container").append(domElement); //add the element to the container
}

当你说它“不起作用”时,你是指它不能满足你的要求吗?因为这段代码将在任何支持CSS3渐变的现代浏览器中运行。 - Logan Murphy
是的,抱歉那就是我想说的,这段代码本身工作得非常好,但我不能在不构建全新的 Sneak 逻辑的情况下使用它。 - Snackaholic
我刚刚看到你附加的图片并更新了我的答案...虽然“如何创建弯曲的渐变?”是主要问题,但我相信我已经回答了它。 - Logan Murphy
在制作游戏时,你应该至少有两个循环运行,逻辑循环和渲染循环...使用我提供的代码,你不需要新的蛇逻辑,你需要新的蛇渲染...如果你至少将这两个流程分开,你会发现游戏开发更容易、更愉快。 - Logan Murphy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接