<template>
  <div class="cap-wrap" @click="refresh" :title="'点击刷新验证码'">
    <canvas ref="cv" :width="w" :height="h"></canvas>
  </div>
</template>

<script>
export default {
  name: "CaptchaCanvas",
  props: { value: String, w: { type: Number, default: 173 }, h: { type: Number, default: 64 } },
  data() { return { code: "" }; },
  mounted() { this.refresh(); },
  methods: {
    randChar() {
      const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
      return chars[Math.floor(Math.random() * chars.length)];
    },
    refresh() {
      this.code = Array.from({ length: 4 }).map(() => this.randChar()).join("");
      this.$emit("input", this.code);
      const cv = this.$refs.cv;
      const ctx = cv.getContext("2d");

      // 背景
      ctx.clearRect(0, 0, this.w, this.h);
      const g = ctx.createLinearGradient(0, 0, this.w, this.h);
      g.addColorStop(0, "rgba(14,45,120,0.65)");
      g.addColorStop(1, "rgba(8,20,55,0.85)");
      ctx.fillStyle = g;
      ctx.fillRect(0, 0, this.w, this.h);

      // 干扰线
      for (let i = 0; i < 5; i++) {
        ctx.strokeStyle = `rgba(60,180,255,${0.15 + Math.random()*0.25})`;
        ctx.beginPath();
        ctx.moveTo(Math.random() * this.w, Math.random() * this.h);
        ctx.lineTo(Math.random() * this.w, Math.random() * this.h);
        ctx.stroke();
      }

      // 字符
      ctx.font = "bold 22px Arial";
      ctx.textBaseline = "middle";
      for (let i = 0; i < this.code.length; i++) {
        const x = 22 + i * 32;
        const y = this.h / 2 + (Math.random() * 6 - 4);
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate((Math.random() * 14 - 7) * Math.PI / 180);
        ctx.fillStyle = "rgba(210,245,255,0.92)";
        ctx.fillText(this.code[i], -8, 0);
        ctx.restore();
      }
    }
  }
};
</script>

<style scoped>
.cap-wrap{
  width: 165px;
  height: 54px;
  border: 1px solid #3D6EB8;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
}
canvas{ display:block; }
</style>