mattdesl / canvas-sketch

[beta] A framework for making generative artwork in JavaScript and the browser.
MIT License
4.97k stars 393 forks source link

Very Complex to specify a generated canvas to a class #176

Closed whizzbbig closed 1 year ago

whizzbbig commented 1 year ago

Why is it so complex to add the canvas to the class @mattdesl here i am trying to set the generated canvases to the canvas that i created in index.html Repo but it seems to complicated to add them like i almost achieved the 70% of the goal but idk from where it generates those canvas down and .sketch-05 isn't behaving correctly

whizzbbig commented 1 year ago

https://user-images.githubusercontent.com/54703305/206434608-9daaca02-f7df-483b-9c0a-6ba8f5609c4d.mov

@mattdesl Please help me with this and also can you please explain me why 5th canvas isn't adding to .sketch-05 because of this error my creativecoding streak broke :c

sfrieson commented 1 year ago

It might be easier for you to instead set the canvas to be used by the sketch. In the DOM Settings section, it shows how you can supply a canvas element for your sketch to run on.

Does that help this situation?

whizzbbig commented 1 year ago

It might be easier for you to instead set the canvas to be used by the sketch. In the DOM Settings section, it shows how you can supply a canvas element for your sketch to run on.

Does that help this situation?

it gives me this error

Uncaught (in promise) Error: The specified { canvas } element does not have a getContext() function, maybe it is not a <canvas> tag?

however here is the code i just try to get context from the settings.canvas and replace it to the places where i mentioned typeCanvas

/* eslint-disable prefer-const */
import canvasSketch from 'canvas-sketch'
import random from 'canvas-sketch-util/random'

const settings = {
  dimensions: [1080, 1080],
  animate: true,
  fps: 10,
  playbackRate: 'throttle',
  canvas: '.sketch-05'
}

let manager

let text = 'A'
let fontSize = 1200
let fontFamily = 'serif'

const typeCanvas = document.querySelector('.sketch-05')
const typeContext = typeCanvas.getContext('2d')

const sketch = ({ context, width, height }) => {
  const cell = 20
  const cols = Math.floor(width / cell)
  const rows = Math.floor(height / cell)
  const numCells = cols * rows

  context.canvas.classList.className = '.sketch-05'

  typeCanvas.width = cols
  typeCanvas.height = rows

  return ({ context, width, height }) => {
    typeContext.fillStyle = 'black'
    typeContext.fillRect(0, 0, cols, rows)

    fontSize = cols * 1.2

    typeContext.fillStyle = 'white'
    typeContext.font = `${fontSize}px ${fontFamily}`
    typeContext.textBaseline = 'top'

    const metrics = typeContext.measureText(text)
    const mx = metrics.actualBoundingBoxLeft * -1
    const my = metrics.actualBoundingBoxAscent * -1
    const mw = metrics.actualBoundingBoxLeft + metrics.actualBoundingBoxRight
    const mh = metrics.actualBoundingBoxAscent + metrics.actualBoundingBoxDescent

    const tx = (cols - mw) * 0.5 - mx
    const ty = (rows - mh) * 0.5 - my

    typeContext.save()
    typeContext.translate(tx, ty)

    typeContext.beginPath()
    typeContext.rect(mx, my, mw, mh)
    typeContext.stroke()

    typeContext.fillText(text, 0, 0)
    typeContext.restore()

    const typeData = typeContext.getImageData(0, 0, cols, rows).data

    context.fillStyle = 'black'
    context.fillRect(0, 0, width, height)

    context.textBaseline = 'middle'
    context.textAlign = 'center'

    context.drawImage(typeCanvas, 0, 0)

    for (let i = 0; i < numCells; i++) {
      const col = i % cols
      const row = Math.floor(i / cols)

      const x = col * cell
      const y = row * cell

      const r = typeData[i * 4 + 0]
      //   const g = typeData[i * 4 + 1]
      //   const b = typeData[i * 4 + 2]
      //   const a = typeData[i * 4 + 3]

      const glyph = getGlyph(r)

      context.font = `${cell * 2}px ${fontFamily}`
      if (Math.random() < 0.1) context.font = `${cell * 6}px ${fontFamily}`

      context.fillStyle = 'white'

      context.save()
      context.translate(x, y)
      context.translate(cell * 0.5, cell * 0.5)

      context.fillText(glyph, 0, 0)

      // circle
      //   context.beginPath()
      //   context.arc(0, 0, cell * 0.5, 0, Math.PI * 2)
      //   context.fill()

      context.restore()
    }
  }
}

const getGlyph = (v) => {
  if (v < 50) return ''
  if (v < 100) return '.'
  if (v < 150) return '-'
  if (v < 200) return 'a'

  const glyphs = '_=/'.split('')

  return random.pick(glyphs)
}

const onKeyUp = (e) => {
  text = e.key.toUpperCase()
  manager.render()
}

document.addEventListener('keyup', onKeyUp)

const start = async () => {
  manager = await canvasSketch(sketch, settings)
}
start()
sfrieson commented 1 year ago

The docs make it look like the settings want the canvas element itself, not a selector.

  canvas: document.querySelector('.sketch-05');

I currently don’t have a computer to check this on though.

whizzbbig commented 1 year ago

The docs make it look like the settings want the canvas element itself, not a selector.

  canvas: document.querySelector('.sketch-05');

I currently don’t have a computer to check this on though.

love you brother it solved the error here see the version now https://creative-ice.vercel.app the 5th one added because of you thanks alot

sfrieson commented 1 year ago

🎉Glad that worked.