javascript - 当用户单击时,如何阻止我的文本在数组中循环?

标签 javascript html canvas

我有当用户单击屏幕时随机生成的文本。一切都与运动、颜色等一起工作,除了它只是不断地在数组中循环改变单词。如何让它在用户每次单击时随机选择一个单词并将该单词保留在屏幕上而不循环遍历数组?代码如下:

<html>
<head>
<script>
var canvas;
var context;
var texts = [];
var timer;

function init() {
    canvas = document.getElementById('canvas');
    context = canvas.getContext("2d");
    resizeCanvas();
    window.addEventListener('resize', resizeCanvas, false);
    window.addEventListener('orientationchange', resizeCanvas, false);

    canvas.onclick = function(event) {
        handleClick(event.clientX, event.clientY);
    }

    var timer = setInterval(resizeCanvas, 30);
}

function Text(x,y,textColor) {
        this.x = x;
        this.y = y;
        this.textColor = textColor;

        this.vx = Math.random() * 30 - 15;
        this.vy = Math.random() * 30 - 15;
        this.time = 300;
}

function handleClick(x,y) {
        var colors = [[255,0,0],[255,255,0],[0,0,255]];
        var textColor = colors[Math.floor(Math.random()*colors.length)];
        texts.push(new Text(x,y,textColor));
        for (var i=0; i<texts.length; i++) {
            drawText(texts[i]);
        }
}

function timeToFade(time) {
    if(time > 100) {
        return 1;
    }
    else {
        return time / 100;
    }
}

function drawText(text) {
     context.font = "bold 60px Verdana";
     var textSayings = ['Cool!', 'Nice!', 'Awesome!', 'Wow!', 'Whoa!', 'Super!', 'Woohoo!', 'Yay!', 'Yeah!']
     var whichText = textSayings[Math.floor(Math.random()*textSayings.length)];

     var c = text.textColor
     context.fillStyle = 'rgba(' + c[0] + ', ' + c[1] + ', ' + c[2] + ', ' + (text.time / 100) + ')';
     context.fillText(whichText,text.x,text.y); 
}

function resizeCanvas() {
    canvas.width = window.innerWidth-20;
    canvas.height = window.innerHeight-20;
    fillBackgroundColor();
    for (var i=0; i<texts.length; i++) {
        var te = texts[i];
        drawText(te);

        if (te.x + te.vx > canvas.width || te.x + te.vx < 0)
            te.vx = -te.vx
        if (te.y + te.vy > canvas.height || te.y + te.vy < 0)
            te.vy = -te.vy
        if (te.time === 0) {
            texts.splice(i,1);
        }

        te.time -= 3;
        te.x += te.vx;
        te.y += te.vy;
    }
}

function fillBackgroundColor() {
    context.globalCompositeOperation = 'source-over';
    context.fillStyle = 'rgba(0, 0, 0, 1)';
    context.fillRect(0,0,canvas.width,canvas.height);
    context.globalCompositeOperation = 'lighter';
}

window.onload = init;
</script>
</head>
<body>
    <canvas id="canvas" width="500" height="500"></canvas>
</body>
</html>

最佳答案

您应该将单词选取逻辑移出绘图函数。只需在进入循环之前选择一个单词,然后将该单词传递给绘图函数,该函数的唯一工作就是实际绘制一些东西。

你可以这样做:

var canvas;
var context;
var texts = [];
var timer;
var textSayings = ['Cool!', 'Nice!', 'Awesome!', 'Wow!', 'Whoa!', 'Super!', 'Woohoo!', 'Yay!', 'Yeah!']

function init() {
  canvas = document.getElementById('canvas');
  context = canvas.getContext("2d");
  resizeCanvas();
  window.addEventListener('resize', resizeCanvas, false);
  window.addEventListener('orientationchange', resizeCanvas, false);

  canvas.onclick = function(event) {
    handleClick(event.clientX, event.clientY);
  }

  var timer = setInterval(resizeCanvas, 30);
}

function Text(x, y, textColor, word) {
  this.x = x;
  this.y = y;
  this.word = word;
  this.textColor = textColor;

  this.vx = Math.random() * 30 - 15;
  this.vy = Math.random() * 30 - 15;
  this.time = 300;
}

function handleClick(x, y) {
  var colors = [
    [255, 0, 0],
    [255, 255, 0],
    [0, 0, 255]
  ];
  var textColor = colors[Math.floor(Math.random() * colors.length)];
  texts.push(new Text(
    x,
    y,
    textColor,
    pickWord()
  ));
  for (var i = 0; i < texts.length; i++) {
    drawText(texts[i]);
  }
}

function timeToFade(time) {
  if (time > 100) {
    return 1;
  } else {
    return time / 100;
  }
}

function pickWord() {
  return textSayings[Math.floor(Math.random() * textSayings.length)];
}

function drawText(text) {
  context.font = "bold 60px Verdana";

  var c = text.textColor
  context.fillStyle = 'rgba(' + c[0] + ', ' + c[1] + ', ' + c[2] + ', ' + (text.time / 100) + ')';
  context.fillText(text.word, text.x, text.y);
}

function resizeCanvas() {
  canvas.width = window.innerWidth - 20;
  canvas.height = window.innerHeight - 20;
  fillBackgroundColor();
  for (var i = 0; i < texts.length; i++) {
    var te = texts[i];
    drawText(te);

    if (te.x + te.vx > canvas.width || te.x + te.vx < 0)
      te.vx = -te.vx
    if (te.y + te.vy > canvas.height || te.y + te.vy < 0)
      te.vy = -te.vy
    if (te.time === 0) {
      texts.splice(i, 1);
    }

    te.time -= 3;
    te.x += te.vx;
    te.y += te.vy;
  }
}

function fillBackgroundColor() {
  context.globalCompositeOperation = 'source-over';
  context.fillStyle = 'rgba(0, 0, 0, 1)';
  context.fillRect(0, 0, canvas.width, canvas.height);
  context.globalCompositeOperation = 'lighter';
}

window.onload = init;
init();
<canvas id="canvas" width="500" height="500"></canvas>

请注意,我向 Text 类添加了一个 word 属性,以及一个从全局列表中选择单词的 pickWord 函数。

关于javascript - 当用户单击时,如何阻止我的文本在数组中循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41081613/

相关文章:

javascript - 从 QT 中的 javascript 访问 QML Canvas

jquery - 向按钮添加触发器

javascript - Cordova iOS - CANVAS 获取像素颜色无法正常工作(视网膜尺寸)

javascript - Ember 2.0 中离开路线时提醒用户

javascript - 音频无法与Cookie一起正常使用

javascript - 在 Redux 中将对象转换为数组

javascript - 创建文档并设置日期 - Mongoose

html - 将数据绑定(bind)到另一个组件并使用 @Input、@Output 和 EventEmitter 在 Angular 中使用它

javascript - 如何自动关闭切换按钮

javascript - 用于滚动面板的 HTML5 Canvas 与 Div