每次碰到墙壁时,将球的颜色改为随机颜色

时间:2016-09-23 12:17:21

标签: javascript function canvas html5-canvas

我想每次碰到墙壁时改变点的颜色。我看到了一些解决方案,但我不知道为什么我的工作不起作用。

这是负责改变颜色的部分:

function chColor() {
    hex = Math.floor(Math.random() * 100000 + 1);
    color = '"' + "#" + hex + '"';
    color.toString();
    return color;
}

这里没有工作小提琴:

https://jsfiddle.net/vpzd7ye6/

4 个答案:

答案 0 :(得分:1)

问题在于将数字转换为十六进制颜色字符串。 因此,您可以编写一个将随机数转换为有效十六进制颜色的函数(请参阅what this function does):

function convertToColor(num){
    return '#' + ('00000' + (num | 0).toString(16)).substr(-6);
}

然后只需在chColor函数中使用它:

function chColor() {
    number = Math.floor(Math.random() * 100000 + 1);
    color = convertToColor(number);
    return color;
}

以下是与工作示例的链接:jsfiddle

将函数重命名为getRandomColor

也是有意义的
function getRandomColor(){
    number = Math.floor(Math.random() * 100000 + 1);
    return convertToColor(number);
}

答案 1 :(得分:1)

请查看更新的fiddle

我刚刚更改了@Autowired private DataTemplatesave dataTemplatesave; 功能:

chColor

答案 2 :(得分:1)

颜色过度

这个答案是方式矫枉过正,我即将丢弃它,但是,为什么不为那些可能需要它的人提供更好的随机颜色...... (|: d

当随机接缝较少随机

为我们人类选择一种随机的完全随机的颜色,如果你希望有一个明显的明显变化,吸引眼睛从一种颜色到另一种颜色,那就不会有效。

问题在于,许多可用的颜色值非常接近白色或黑色,并且完全随机的颜色可能非常接近上一次,使得无法注意到更改。

简单的随机颜色

首先,简单的随机颜色从所有16,777,216种颜色中选择一种完全随机的颜色。

function randColor(){
    return "#" + 
           (Math.floor(Math.random() * 0x1000000) + 0x1000000)
              .toString(16)
              .substr(1);
}

该功能通过查找随机24位数(0 - 0xFFFFFF与0 - 16777216相同)来工作。因为数字没有添加前导零,所以0x100000以下的所有随机值都会在转换为十六进制时少于6位(CSS颜色值需要3或6位十六进制数值),所以我添加了0x1000000确保该数字> 0x100000并且始终有7位数字。由于不需要第一个(最左侧)数字,我使用substr将其删除。然后添加了"#"并返回。

函数Number.toString(radix)接受一个名为radix的参数,该参数指定数字转换为的基数。默认情况下,如果没有提供给10(基数十是我们人类使用的)。十六进制颜色为16,因此必须指定。 toString基数参数可以是从2(二进制)到36(使用字符0-9然后是A-Z)的任何值。

少即是随机

具有讽刺意味的是,人类倾向于发现比真正的随机序列更随机的随机序列。许多音乐播放器在将播放设置为随机播放时使用这种类型的随机序列,以确保曲目不会连续播放两次,或者通过随机机会播放重复的曲目序列。

要使随机颜色看起来更随机且更清晰,您应该跟踪最后一个颜色返回,以便确保您不接近该颜色。你还应该使用一种远离白人和黑人的随机颜色。

var randColour = (function(){ // as singleton so closure can track last colour
    var lastHue = 0;
    const minChange = 360 / 3; // Hue distance from last random colour
    var lastVal = false; // for low high saturation and luminance
    const randomAmount = 360 / 3; // random hue range
    const minVal = 20; // how far from full black white to stay (percent)
    const minSat = 80; // how far from grey to stay (percent)
    return function(){
         var hueChange = Math.random() * randomAmount ;
         hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
         lastHue += 360 + hueChange + minChange;  // move away from last colour
         lastHue %= 360;  // ensure colour is in valid range
         var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
         var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
         // switch between high and low and luminance
         lastVal = ! lastVal;
         if(lastVal){        
             val = minVal + val;
         } else {
             val = 100 - minVal - val;
         }


         return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
     }
})(); // call singleton

此函数返回一个随机颜色,但确保饱和度和值保持在特定范围内,并且色调至少是最后一个值的色轮周围的1/3。它在低亮度值和低亮度值之间循环,以使颜色变化尽可能清晰。闭包用于跟踪返回的最后一种颜色。该函数将随机颜色作为CSS hsl(hue, saturation, luminance)颜色字符串返回。

有两个常数控制颜色序列。设置为20的minVal是远离全黑或全白的百分比。有效范围是0到50,minSat设置为80是远离灰色的百分比。         const minSat = 80; //离灰色多远(百分比)

比较更改

为了比较这两种方法,下面的演示使用两种方法并排显示一组随机颜色,然后每秒闪烁4次新的随机颜色。简单的随机颜色会不时出现以错过更改。我把它留给你挑选哪一方。

var canvas = document.createElement("canvas");
canvas.width = 620;
canvas.height = 200;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

var randColour = (function(){ // as singleton so closure can track last colour
    var lastHue = 0;
    const minChange = 360 / 3; // min hue change
    var lastVal = false; // for low high saturation and luminance
    const randomAmount = 360 / 3; // amount of randomness
    const minVal = 20; // how far from full black white to stay (percent)
    const minSat = 80; // how far from grey to stay (percent)
    return function(){
         var hueChange = Math.random() * randomAmount ;
         hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
         lastHue += 360 + hueChange + minChange;  // move away from last colour
         lastHue %= 360;  // ensure colour is in valid range
         var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
         var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
         // switch between high and low and luminance
         lastVal = ! lastVal;
         if(lastVal){        
             val = minVal + val;
         } else {
             val = 100 - minVal - val;
         }
            

         return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
     }
})(); // call singleton

function randColor(){
    return "#" + 
           (Math.floor(Math.random() * 0x1000000) + 0x1000000)
              .toString(16)
              .substr(1);
}

const grid = 16; 
var gridX = 0;
var gridY = 0;
var bigSize = grid - (grid / 3 ) * 2;
const xStep = Math.floor((canvas.width - 12) / (grid * 2));
const yStep = Math.floor(canvas.height / grid);
var count = 0;
function drawRandomColour(){
     ctx.fillStyle = randColor(); // simple random colour
     ctx.fillRect(gridX * xStep, gridY * yStep, xStep, yStep);
     ctx.fillStyle = randColour(); // smart random colour
     ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep, yStep);

     if(count < grid * grid - 1){  // fill the grid
         gridX += 1;  // move to next grid
         if(gridX > grid-1){
             gridX = 0;
             gridY += 1;
             gridY %= grid;
         }
         count += 1;
         setTimeout(drawRandomColour,1); // quickly fill grid
         return; // done for now
     }
     // if grid is full pick a random grid loc and request the next random colour
     gridY = gridX = (grid / 3);
     setTimeout(centerChange,250); // every quarter second
     
 }
 function centerChange(){
     ctx.fillStyle = randColor(); // simple random colour
     ctx.fillRect(gridX * xStep, gridY * yStep, xStep * bigSize, yStep * bigSize);
     ctx.fillStyle = randColour(); // smart random colour
     ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep * bigSize, yStep * bigSize);
     setTimeout(centerChange,250); // every quarter second
 }

 drawRandomColour(); // start it up.

比较序列

此演示只是将随机颜色绘制为一系列随机值。检查序列以查看您在一行中看到难以区分的两种或更多种颜色的频率。你会发现左边的序列比右边的序列有更多相似的序列。

将demo扩展到整页视图以查看两个序列。

单击以重绘序列。

var canvas = document.createElement("canvas");
canvas.width = 1240;
canvas.height = 800;
var ctx = canvas.getContext("2d");
document.body.appendChild(canvas);

var randColour = (function(){ // as singleton so closure can track last colour
    var lastHue = 0;
    const minChange = 360 / 3; // min hue change
    var lastVal = false; // for low high saturation and luminance
    const randomAmount = 360 / 3; // amount of randomness
    const minVal = 20; // how far from full black white to stay (percent)
    const minSat = 80; // how far from grey to stay (percent)
    return function(){
         var hueChange = Math.random() * randomAmount ;
         hueChange *= Math.random() < 0.5 ? -1 : 1; // randomly move forward or backward
         lastHue += 360 + hueChange + minChange;  // move away from last colour
         lastHue %= 360;  // ensure colour is in valid range
         var sat = (Math.random() * (100 - minSat)) + minSat; // get saturation (amount of colour)
         var val = (Math.random() * (50 - minVal * 2)) * 1.5; // get value (luminance)
         // switch between high and low and luminance
         lastVal = ! lastVal;
         if(lastVal){        
             val = minVal + val;
         } else {
             val = 100 - minVal - val;
         }
            

         return "hsl(" + lastHue.toFixed(0) + "," + sat.toFixed(0) + "%," + val.toFixed(0) + "%)";
     }
})(); // call singleton

function randColor(){
    return "#" + 
           (Math.floor(Math.random() * 0x1000000) + 0x1000000)
              .toString(16)
              .substr(1);
}

const grid = 32; 
var gridX = 0;
var gridY = 0;
const xStep = Math.floor((canvas.width - 12) / (grid * 2));
const yStep = Math.floor(canvas.height / grid);
var count = 0;
function drawRandomColour(){
     ctx.fillStyle = randColor(); // simple random colour
     ctx.fillRect(gridX * xStep, gridY * yStep, xStep, yStep);
     ctx.fillStyle = randColour(); // smart random colour
     ctx.fillRect(gridX * xStep + canvas.width / 2, gridY * yStep, xStep, yStep);

     if(count < grid * grid - 1){  // fill the grid
         gridX += 1;  // move to next grid
         if(gridX > grid-1){
             gridX = 0;
             gridY += 1;
             gridY %= grid;
         }
         count += 1;
         setTimeout(drawRandomColour,1); // quickly fill grid
         return; // done for now
     }
 }

 drawRandomColour(); // start it up.

 // redraw on click
 canvas.addEventListener("click",function(){
     if(count >= grid * grid - 1){
          gridX = gridY = count = 0;
          drawRandomColour();
     }else { 
          gridX = gridY = count = 0;

     }
 });

<强>摘要

虽然第二个随机函数并不完美,但它可能会不时地获得在上下文中看起来相似的颜色,这种颜色比纯随机函数要少得多。当对于用户注意到视觉变化很重要时,最好的方法是使两个互补色(色调+ 180)循环,其中一个具有高亮度而另一个具有低亮度。 CSS hsl颜色字符串可以轻松选择亮度和色调,当您想要随机颜色时,可以更好地控制。

答案 3 :(得分:0)

我已经更新了小提琴。链接https://jsfiddle.net/vpzd7ye6/2/

我对您的更改颜色功能进行了以下更改;

function chColor() {
        hex = Math.floor(Math.random() * 1000000) + 1;
        color = '' + '#' + hex + '';
        return color;
}