【JS】canvas实现的类似选择框的效果界面

在这里插入图片描述
效果图如图
用的canvas实现的效果 ,点击获取或重点的颜色信息。
直接上代码

<template>
<div>
  <canvas ref="dotBoard" class="canvas" :width="dotBoardWidth" :height="dotBoardHeight" @mousemove="mousePoint" @click="getColor"/>
  <div>大小:{
   
   {size}}</div>
  <button @click="createImage">导出</button>
  <div :style="{background:pointColor}">
    {
   
   { pointColor }}
  </div>
  <img  :src="image"/>
</div>
</template>

<script setup>
import { randColor , randColorByIndex } from '@/utils/color.js'
import {ref,onMounted} from 'vue'
const dotBoard = ref(null)
let canvas = ''
let ctx = ''
const boardWidth = 800
const boardHeight = 800
let width = 100
let height = 100
let rectWidth = parseInt(boardWidth/width)
let rectHeight =  parseInt(boardHeight/height)
let dotBoardWidth = ref(boardWidth)
let dotBoardHeight = ref(boardHeight)
const image = ref('')
const size = ref(0)
const x = ref(0)
const y = ref(0)
const pointColor = ref('')
let imageData = ''

const initCanvas = () => {
  console.log("初始化")
  canvas = dotBoard.value
  console.log('canvas',canvas)
  if (canvas.getContext) {
    console.log('支持画布');
    ctx = canvas.getContext('2d');
  }
}
const randDraw = (count) => {
  let i = 0
  const timer = setInterval(() => {
    for ( let j = 0 ; j < width ; j++ ) {
      let x = j
      let y = i
      // let color = randColorByIndex(i)
      let color = randColor()
      draw(x,y,color)
    }
    i++
    if(i> count ) {
      imageData = ctx.getImageData(0,0,boardWidth,boardHeight)
      console.log('画布数据',imageData)
      clearInterval(timer)
    }
  },1)
}
const draw = (x,y,color) =>{
  ctx.fillStyle=color;
  ctx.fillRect(x*rectWidth,y*rectHeight,rectWidth,rectHeight);
}
const createImage = () => {
  console.log("生成图片")
  // const data = canvas.toDataURL("image/png")
  const data = canvas.toDataURL("image/jpeg")
  console.log('图片',data)
  image.value=data
}
const mousePoint = (e) => {
  // console.log("鼠标",e.x,e.y)
  let ws = parseInt(boardWidth/width)
  let hs = parseInt(boardHeight/height)
  let ex = parseInt(e.x / ws) * ws
  let ey = parseInt(e.y / hs) * hs
  if ( e.x > boardWidth - ws/2){
    ex += 1
  }
  if ( e.y > boardHeight - hs/2){
    ey += 1
  }
  if ( x.value !== ex || y.value !== ey) {
    drawSight(ex,ey)
    x.value = ex
    y.value = ey
  }
}
const drawSight = (x,y) => {
  if ( !imageData ) {
    return
  }
  // 检查XY坐标
  clearBoard()
  let color = getPointColor(x,y)
  ctx.putImageData(imageData,0,0)
  const size = 10
  const lineWidth = 4
  const x1 = x - size
  const x2 = x + size
  const y1 = y - size
  const y2 = y + size
  ctx.beginPath();
  ctx.fillStyle=color
  ctx.fillRect(x1,y1,size*2,size*2);
  ctx.stroke();
  // 框
  ctx.lineWidth = lineWidth
  ctx.moveTo(x1,y1);
  ctx.lineTo(x1,y2);
  ctx.lineTo(x2,y2);
  ctx.lineTo(x2,y1);
  ctx.lineTo(x1-lineWidth/2,y1);
  ctx.stroke();
  // 线
  ctx.lineWidth = lineWidth/2
  let line1 = {
    x1:0,
    y1:y,
    x2:x-(size + lineWidth) / 1.5 ,
    y2:y
  }
  ctx.moveTo(line1.x1,line1.y1);
  ctx.lineTo(line1.x2,line1.y2);
  let line2 = {
    x1:x,
    y1:0,
    x2:x,
    y2:y-(size + lineWidth) / 1.5
  }
  ctx.moveTo(line2.x1,line2.y1);
  ctx.lineTo(line2.x2,line2.y2);
  let line3 = {
    x1:boardWidth,
    y1:y,
    x2:x+(size + lineWidth) / 1.5 ,
    y2:y
  }
  ctx.moveTo(line3.x1,line3.y1);
  ctx.lineTo(line3.x2,line3.y2);
  let line4 = {
    x1:x,
    y1:boardHeight,
    x2:x,
    y2:y+(size + lineWidth) / 1.5
  }
  ctx.moveTo(line4.x1,line4.y1);
  ctx.lineTo(line4.x2,line4.y2);
  ctx.stroke();
  ctx.closePath()
}
const getPointColor = (x,y) => {
  const index = ((x + (y)*boardHeight ))*4
  // console.log("获取颜色",index,x,y)
  let r = imageData.data[index]
  let g = imageData.data[index+1]
  let b = imageData.data[index+2]
  let s = imageData.data[index+3]
  return `rgb(${r},${g},${b})`
}
const clearBoard = () => {
  ctx.clearRect(0,0,boardWidth,boardHeight);
  ctx.fillStyle='#ffffff';
  ctx.fillRect(0,0,boardWidth,boardHeight);
}
const getColor = (e) => {
  // console.log("鼠标",e.x,e.y)
  let ws = parseInt(boardWidth/width)
  let hs = parseInt(boardHeight/height)
  let ex = parseInt(e.x / ws) * ws
  let ey = parseInt(e.y / hs) * hs
  if ( e.x > boardWidth - ws/2){
    ex += 1
  }
  if ( e.y > boardHeight - hs/2){
    ey += 1
  }
  if ( x.value !== ex || y.value !== ey) {
    x.value = ex
    y.value = ey
  }
  let color = getPointColor(ex,ey)
  console.log("当前点颜色",color)
  pointColor.value = color
}
onMounted(() => {
  console.log("挂载")
  initCanvas()
  randDraw(height)
})
</script>

<style scoped>
.canvas{
  cursor: none;
}
</style>

猜你喜欢

转载自blog.csdn.net/sky529063865/article/details/130385514