import { mountFlex } from "https://cdn.jsdelivr.net/npm/p5.flex@0.2.0/src/p5.flex.min.mjs"
import { mountGrid } from "./Grid.js"
import { mountControl } from "./Controls.js"
import { CopyText } from "./tools.js"
import { PARAMS } from "./panel.js"
import { addBlock, removeBlock } from "./panel.js"
import { typing, onTweakpane, onDrage } from "./panel.js"
import { resetPicked, setPicked } from "./panel.js"
import { copyColors } from "./panel.js"
let [WIDTH, HEIGHT] = [600, 600]
let gs, cols, rows, grid_w, grid_h
let preLength = PARAMS.Colors.length
p.createCanvas(WIDTH, HEIGHT)
gs = p.Grid({ cols, rows, grid_w, grid_h, order: p.LRTB })
const tx = WIDTH / 2 - grid_w / 2
const ty = HEIGHT / 2 - grid_h / 2
ColorsLenChanged() && configGrid()
!noPickedID() && editColor(getPickedID())
setTextStyles(PARAMS.Block.Text)
const content = (cell) => {
const size = cell.w * PARAMS.Block.size
const radius = (cell.w / 2) * PARAMS.Block.radius
const hexCode = PARAMS.Colors[cell.id]
p.translate(cell.w / 2, cell.h / 2)
if (PARAMS.Block.Border.enable) {
p.stroke(toP5Color(PARAMS.Block.Border.color))
p.strokeWeight(PARAMS.Block.Border.thickness)
p.square(x, y, size, radius)
p.clip(() => p.square(x, y, size, radius))
const mouseInteract = mouseIsOver(cell, mx, my)
if (mouseInteract && p.mouseIsPressed) blockEvents(cell)
if (mouseInteract || hasPickedID(cell.id) || PARAMS.Block.Text.showAll)
showText(size, hexCode, -PARAMS.Block.Text.height)
p.square(x, y, size, radius)
const keyEvents = () => {
p.PressDo("ArrowUp", pickNeighbor, [0, -1])
p.PressDo("ArrowDown", pickNeighbor, [0, 1])
p.PressDo("ArrowRight", pickNeighbor, [1, 0])
p.PressDo("ArrowLeft", pickNeighbor, [-1, 0])
p.PressDo("c", copyColors)
p.PressDo("C", copyColors)
p.PressDo("Delete", removeBlock)
p.PressDo("Escape", resetPicked)
p.PressDo("Enter", setPickedToIndex0)
p.PressDo("Home", setPickedToLineHead)
p.PressDo("End", setPickedToLineTail)
!onDrage() && !onTweakpane() && !mouseOnGrid(mx, my) && resetPicked()
const save = () => p.save(PARAMS.Colors.join("-").replace(/#/g, ""))
const ColorsLenChanged = () => {
if (preLength === PARAMS.Colors.length) return false
preLength = PARAMS.Colors.length
const configGrid = () => {
gs.config({ cols, rows, grid_w, grid_h })
const setTextStyles = ({ font, style }) => {
p.textAlign(p.CENTER, p.CENTER)
const getPickedID = () => PARAMS.Palette.pickedID
const noPickedID = () => getPickedID() === null
const hasPickedID = (id) => getPickedID() === id
const setPickedToIndex0 = () => !typing && noPickedID() && setPicked(0)
const setPickedToLineHead = () => {
if (typing || noPickedID()) return
const lineHead = p.floor(getPickedID() / cols) * cols
const setPickedToLineTail = () => {
if (typing || noPickedID()) return
(p.floor(getPickedID() / cols) + 1) * cols - 1,
const blockEvents = (cell) => {
if (onTweakpane()) return
if (p.mouseButton === p.LEFT) setPicked(cell.id)
if (p.mouseButton === p.RIGHT) CopyText(PARAMS.Colors[cell.id])
const pickNeighbor = (cOff, rOff) => {
const currID = getPickedID()
const cell = gs.cells[currID]
const nbrID = gs.getID(cell.col + cOff, cell.row + rOff)
if (nbrID === -1 || nbrID >= PARAMS.Colors.length) return
const editColor = (id) => {
PARAMS.Colors[id] = PARAMS.Palette.picked
PARAMS.Palette.colors = JSON.stringify(PARAMS.Colors, null, 2)
const toP5Color = ({ r, g, b }) => p.color(r, g, b)
const toTextBgColor = (color, darkness) => {
color.setRed(p.red(color) - darkness)
color.setGreen(p.green(color) - darkness)
color.setBlue(p.blue(color) - darkness)
color.setAlpha(p.alpha(color) - darkness)
const mouseIsOver = (cell, mx, my) => {
if (onDrage()) return false
cell.col * cell.w < mx &&
mx < cell.col * cell.w + cell.w &&
cell.row * cell.h < my &&
my < cell.row * cell.h + cell.h
const mouseOnGrid = (mx, my) => {
if (onDrage()) return false
return 0 < mx && mx < grid_w && 0 < my && my < grid_h
const showText = (size, text, textH) => {
p.rect(0, textH, size, size / 4)
p.fill(toP5Color(PARAMS.Block.Text.color))
p.textSize(PARAMS.Block.Text.size * (size / 4))
const resetGridParams = () => {
cols = p.max(1, p.min(PARAMS.Colors.length, 5))
rows = p.max(1, p.ceil(PARAMS.Colors.length / cols))
grid_w = cols * CELL_SIZE
grid_h = rows * CELL_SIZE