首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >尝试将颜色渐变添加到画布文本

尝试将颜色渐变添加到画布文本
EN

Stack Overflow用户
提问于 2020-06-25 21:44:08
回答 1查看 55关注 0票数 3

我试图在此代码中为画布文本添加颜色渐变,但我尝试过的效果都不好。

我是个新手,所以我很难找到解决方案。

这种效果有可能实现吗?我找到了使用ctx.fillStyle =gradient更改文本颜色的代码;

但它似乎不起作用。我甚至不知道该把它插在哪里。

有谁知道如何做到这一点吗?

代码语言:javascript
复制
window.onresize = function() {
  resize();
  return true;
};
var pixels = []
var canv = $('canv')
var ctx = canv.getContext('2d')
var wordCanv = $('wordCanv')
var wordCtx = wordCanv.getContext('2d')
var mx = -1
var my = -1
var words = ''
var txt = []
var cw = 0
var ch = 0
var resolution = 1
var n = 0
var timerRunning = false
var resHalfFloor = 0
var resHalfCeil = 0
var width = 600
var height = 600

function canv_mousemove(evt) {
  mx = evt.clientX - canv.offsetLeft
  my = evt.clientY - canv.offsetTop
}

function Pixel(homeX, homeY) {
  this.homeX = homeX
  this.homeY = homeY

  this.x = Math.random() * cw
  this.y = Math.random() * ch

  this.xVelocity = Math.random() * 10 - 5
  this.yVelocity = Math.random() * 10 - 5
}

Pixel.prototype.move = function() {
  var homeDX = this.homeX - this.x
  var homeDY = this.homeY - this.y
  var homeDistance = Math.sqrt(Math.pow(homeDX, 2) + Math.pow(homeDY, 2))
  var homeForce = homeDistance * 0.01
  var homeAngle = Math.atan2(homeDY, homeDX)

  var cursorForce = 0
  var cursorAngle = 0

  if (mx >= 0) {
    var cursorDX = this.x - mx
    var cursorDY = this.y - my
    var cursorDistanceSquared = Math.pow(cursorDX, 2) + Math.pow(cursorDY, 2)
    cursorForce = Math.min(10000 / cursorDistanceSquared, 10000)
    cursorAngle = Math.atan2(cursorDY, cursorDX)
  } else {
    cursorForce = 0
    cursorAngle = 0
  }

  this.xVelocity +=
    homeForce * Math.cos(homeAngle) + cursorForce * Math.cos(cursorAngle)
  this.yVelocity +=
    homeForce * Math.sin(homeAngle) + cursorForce * Math.sin(cursorAngle)

  this.xVelocity *= 0.92
  this.yVelocity *= 0.92

  this.x += this.xVelocity
  this.y += this.yVelocity
}

function $(id) {
  return document.getElementById(id)
}

function timer() {
  if (!timerRunning) {
    timerRunning = true
    setTimeout(timer, 33)
    for (var i = 0; i < pixels.length; i++) {
      pixels[i].move()
    }

    drawPixels()
    n++
    if (
      n % 10 == 0 &&
      (cw != width || ch != height)
    )
      body_resize()
    timerRunning = false
  } else {
    setTimeout(timer, 5)
  }
}

function drawPixels() {
  var imageData = ctx.createImageData(cw, ch)
  var actualData = imageData.data

  var index
  var goodX
  var goodY
  var realX
  var realY

  for (var i = 0; i < pixels.length; i++) {
    goodX = Math.floor(pixels[i].x)
    goodY = Math.floor(pixels[i].y)

    for (
      realX = goodX - resHalfFloor; realX <= goodX + resHalfCeil && realX >= 0 && realX < cw; realX++
    ) {
      for (
        realY = goodY - resHalfFloor; realY <= goodY + resHalfCeil && realY >= 0 && realY < ch; realY++
      ) {
        index = (realY * imageData.width + realX) * 4
        actualData[index + 3] = 255
      }
    }
  }

  imageData.data = actualData
  ctx.putImageData(imageData, 0, 0)
}

function readWords() {
  var randomWords = ['Text goes here', 'Text 2 goe ']
  words = item = randomWords[Math.floor(Math.random() * randomWords.length)]
  txt = words.split('\n')
}

function init() {
  readWords()
  var fontSize = 100
  var wordWidth = 0
  do {
    wordWidth = 0
    fontSize -= 5
    wordCtx.font = fontSize + 'px sans-serif'
    for (var i = 0; i < txt.length; i++) {
      var w = wordCtx.measureText(txt[i]).width
      if (w > wordWidth) wordWidth = w
    }
  } while (wordWidth > cw - 50 || fontSize * txt.length > ch - 50)
  wordCtx.clearRect(0, 0, cw, ch)
  wordCtx.textAlign = 'center'
  wordCtx.textBaseline = 'middle'

  for (var i = 0; i < txt.length; i++) {
    wordCtx.fillText(
      txt[i],
      cw / 2,
      ch / 2 - fontSize * (txt.length / 2 - (i + 0.5))
    )
  }

  var index = 0

  var imageData = wordCtx.getImageData(0, 0, cw, ch)
  for (var x = 0; x < imageData.width; x += resolution) {
    for (var y = 0; y < imageData.height; y += resolution) {
      i = (y * imageData.width + x) * 4

      if (imageData.data[i + 3] > 128) {
        if (index >= pixels.length) {
          pixels[index] = new Pixel(x, y)
        } else {
          pixels[index].homeX = x
          pixels[index].homeY = y
        }
        index++
      }
    }
  }

  pixels.splice(index, pixels.length - index)
}

function body_resize() {
  cw = width
  ch = height
  canv.width = cw
  canv.height = ch
  wordCanv.width = cw
  wordCanv.height = ch
  init()
}

resHalfFloor = Math.floor(resolution / 2)
resHalfCeil = Math.ceil(resolution / 2)

body_resize()
timer()
setInterval(init, 3000)
代码语言:javascript
复制
<canvas id="wordCanv" width="100%" height="600px" style="border:10px solid rgb(255,255,255);display:none;">
</canvas>
<canvas id="canv" onmousemove="canv_mousemove(event);" onmouseout="mx=-1;my=-1;" width="100%" height="600px">
</canvas>

EN

回答 1

Stack Overflow用户

发布于 2020-06-26 03:46:48

目前还不清楚你想要达到什么样的渐变效果。

所以我猜任何一个都会让你行动起来,请看下面的代码

我刚刚添加了以下内容:

actualData[index + 1] = realX % 255

在您的函数drawPixels中

使用这些值,直到得到所需的组合

我假设你熟悉ImageData,如果不是在这里阅读更多:

代码语言:javascript
复制
var pixels = []
var canv = $('canv')
var ctx = canv.getContext('2d')
var wordCanv = $('wordCanv')
var wordCtx = wordCanv.getContext('2d')
var mx = -1
var my = -1
var words = ''
var txt = []
var cw = 0
var ch = 0
var resolution = 1
var n = 0
var timerRunning = false
var resHalfFloor = 0
var resHalfCeil = 0
var width = 560
var height = 200

function canv_mousemove(evt) {
  mx = evt.clientX - canv.offsetLeft
  my = evt.clientY - canv.offsetTop
}

function Pixel(homeX, homeY) {
  this.homeX = homeX
  this.homeY = homeY

  this.x = Math.random() * cw
  this.y = Math.random() * ch

  this.xVelocity = Math.random() * 10 - 5
  this.yVelocity = Math.random() * 10 - 5
}

Pixel.prototype.move = function() {
  var homeDX = this.homeX - this.x
  var homeDY = this.homeY - this.y
  var homeDistance = Math.sqrt(Math.pow(homeDX, 2) + Math.pow(homeDY, 2))
  var homeForce = homeDistance * 0.01
  var homeAngle = Math.atan2(homeDY, homeDX)

  var cursorForce = 0
  var cursorAngle = 0

  if (mx >= 0) {
    var cursorDX = this.x - mx
    var cursorDY = this.y - my
    var cursorDistanceSquared = Math.pow(cursorDX, 2) + Math.pow(cursorDY, 2)
    cursorForce = Math.min(10000 / cursorDistanceSquared, 10000)
    cursorAngle = Math.atan2(cursorDY, cursorDX)
  } else {
    cursorForce = 0
    cursorAngle = 0
  }

  this.xVelocity +=
    homeForce * Math.cos(homeAngle) + cursorForce * Math.cos(cursorAngle)
  this.yVelocity +=
    homeForce * Math.sin(homeAngle) + cursorForce * Math.sin(cursorAngle)

  this.xVelocity *= 0.92
  this.yVelocity *= 0.92

  this.x += this.xVelocity
  this.y += this.yVelocity
}

function $(id) {
  return document.getElementById(id)
}

function timer() {
  if (!timerRunning) {
    timerRunning = true
    setTimeout(timer, 33)
    for (var i = 0; i < pixels.length; i++) {
      pixels[i].move()
    }

    drawPixels()
    n++
    if (
      n % 10 == 0 &&
      (cw != width || ch != height)
    )
      body_resize()
    timerRunning = false
  } else {
    setTimeout(timer, 5)
  }
}

function drawPixels() {
  var imageData = ctx.createImageData(cw, ch)
  var actualData = imageData.data

  var index
  var goodX
  var goodY
  var realX
  var realY

  for (var i = 0; i < pixels.length; i++) {
    goodX = Math.floor(pixels[i].x)
    goodY = Math.floor(pixels[i].y)

    for (
      realX = goodX - resHalfFloor; realX <= goodX + resHalfCeil && realX >= 0 && realX < cw; realX++
    ) {
      for (
        realY = goodY - resHalfFloor; realY <= goodY + resHalfCeil && realY >= 0 && realY < ch; realY++
      ) {
        index = (realY * imageData.width + realX) * 4
        
        actualData[index + 1] = realX % 255    
        actualData[index + 3] = 255
      }
    }
  }

  imageData.data = actualData
  ctx.putImageData(imageData, 0, 0)
}

function readWords() {
  var randomWords = ['Text 4 foo ', 'Text 2 goe ']
  words = item = randomWords[Math.floor(Math.random() * randomWords.length)]
  txt = words.split('\n')
}

function init() {
  readWords()
  var fontSize = 80
  var wordWidth = 0
  wordCtx.font = fontSize + 'px sans-serif'
  do {
    wordWidth = 0
    fontSize -= 10
    
    for (var i = 0; i < txt.length; i++) {
      var w = wordCtx.measureText(txt[i]).width
      if (w > wordWidth) wordWidth = w
    }
  } while (wordWidth > cw - 50 || fontSize * txt.length > ch - 50)
  wordCtx.clearRect(0, 0, cw, ch)
  wordCtx.textAlign = 'center'
  wordCtx.textBaseline = 'middle'

  for (var i = 0; i < txt.length; i++) {
    wordCtx.fillText(
      txt[i],
      cw / 2,
      ch / 2 - fontSize * (txt.length / 2 - (i + 0.5))
    )
  }

  var index = 0

  var imageData = wordCtx.getImageData(0, 0, cw, ch)
  for (var x = 0; x < imageData.width; x += resolution) {
    for (var y = 0; y < imageData.height; y += resolution) {
      i = (y * imageData.width + x) * 4

      if (imageData.data[i + 3] > 128) {
        if (index >= pixels.length) {
          pixels[index] = new Pixel(x, y)
        } else {
          pixels[index].homeX = x
          pixels[index].homeY = y
        }
        index++
      }
    }
  }

  pixels.splice(index, pixels.length - index)
}

function body_resize() {
  cw = width
  ch = height
  canv.width = cw
  canv.height = ch
  wordCanv.width = cw
  wordCanv.height = ch
  init()
}

resHalfFloor = Math.floor(resolution / 2)
resHalfCeil = Math.ceil(resolution / 2)

body_resize()
timer()
setInterval(init, 3000)
代码语言:javascript
复制
<canvas id="wordCanv" width="100%" height="200px" style="display:none;">
</canvas>
<canvas id="canv" width="100%" height="200px">
</canvas>

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62576834

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档