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

21 篇文章 0 订阅
14 篇文章 0 订阅
该文章展示了一个Vue组件,利用HTML5的Canvas元素实现颜色网格,用户可以通过点击获取特定位置的颜色信息,并能导出图像。点击事件触发getColor函数获取颜色,mousePoint函数处理鼠标移动时的坐标显示,drawSight函数描绘选中点的视觉效果,最后提供了从canvas转成image数据的方法。
摘要由CSDN通过智能技术生成

在这里插入图片描述
效果图如图
用的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>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
若依架是一个基于Vue.js的开源架,提供了一套完整的前端解决方案,包括了界面流程图的实现。若依架的界面流程图使用了mxGraph这个JavaScript库来实现,mxGraph是一个基于HTML5 Canvas的图形库,可以用来创建各种类型的图形,包括流程图、组织结构图、UML图等等。 若依架的界面流程图主要包括以下几个部分: 1. 工具栏:提供了各种绘图工具,包括选择、矩形、圆形、直线、箭头、文本等。 2. 画布:用于绘制流程图,支持缩放、拖拽等操作。 3. 属性面板:用于设置选元素的属性,包括颜色、大小、字体等。 4. 右键菜单:提供了各种操作选元素的菜单,包括复制、粘贴、删除等。 若依架的界面流程图使用了Vue.js的组件化开发方式,将不同的功能模块封装成了不同的组件,方便维护和扩展。同时,若依架的界面流程图还提供了丰富的API,可以通过代码来控制流程图的各种操作。 以下是一个简单的若依界面流程图的代码示例: ```vue <template> <div> <toolbar></toolbar> <canvas></canvas> <property-panel></property-panel> <context-menu></context-menu> </div> </template> <script> import Toolbar from './Toolbar.vue' import Canvas from './Canvas.vue' import PropertyPanel from './PropertyPanel.vue' import ContextMenu from './ContextMenu.vue' export default { components: { Toolbar, Canvas, PropertyPanel, ContextMenu } } </script> ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值