JS小练习-线条之美

JS小练习-线条之美

注:最近准备开始好好研究一下js,顺便就写一些好玩的东西。
可以访问进行尝试:
JS小练习-线条之美
先放几个图:
JS小练习-线条之美_第1张图片

JS小练习-线条之美_第2张图片
只是简单的几个参数就画出了非常美的图案,这让我感觉非常的有趣。
源代码如下,前端显示使用了vue的框架:

<template>
  <div>
    <canvas
      ref="canvas"
      :width="canvasWidth"
      :height="canvasHeight"
      style="width: 100%; height: 80%"
    ></canvas>
  </div>
  <div>注:按下鼠标左键可移动图案位置 , Shift+滚轮可以修改图案的缩放比例</div>
  <el-divider />
  <div class="slider-demo-block">
    <el-row>
      <el-col :span="1"></el-col>
      <el-col :span="10">
        <span class="demonstration">角度(0-180):</span>
        <el-slider v-model="angle" show-input :max="180" />
      </el-col>
      <el-col :span="2"></el-col>
      <el-col :span="10">
        <span class="demonstration">线条数:</span>
        <el-slider v-model="depth" show-input :max="5000" />
      </el-col>
      <el-col :span="1"></el-col>
    </el-row>
    <el-row>
      <el-col :span="1"></el-col>
      <el-col :span="10">
        <span class="demonstration">边长:</span>
        <el-slider v-model="len" show-input :max="5000" />
      </el-col>
      <el-col :span="2"></el-col>
      <el-col :span="10">
        <span class="demonstration">边长递减:</span>
        <el-slider v-model="side_decay" show-input :max="20" />
      </el-col>
      <el-col :span="1"></el-col>
    </el-row>
    <el-row>
      <el-col :span="1"></el-col>
      <el-col :span="10">
        <span class="demonstration">缩放比例:</span>
        <el-slider v-model="zoom_ratio" show-input :min="0.1" :max="9" />
      </el-col>
      <el-col :span="2"></el-col>
      <el-col :span="10"></el-col>
      <el-col :span="1"></el-col>
    </el-row>
  </div>
</template>

<script>
export default {
  data() {
    return {
      angle: 119, // 默认角度
      depth: 360, // 默认线条数
      len: 600, // 线条长度
      side_decay: 1, // 边长衰减
      cx: -300,
      cy: -200,
      down_event: 0,
      down_flag: 1,
      move_event: 0,
      event_flag: 0,
      zoom_ratio: 1,
    };
  },
  computed: {
    canvasWidth() {
      return window.innerWidth; // 将画布宽度设置为整个页面的宽度
    },
    canvasHeight() {
      return window.innerHeight; // 将画布高度设置为页面高度的80%
    },
  },
  mounted() {
    this.drawFractal(); // 调用绘制函数绘制分形树
  },
  methods: {
    // 结构绘制
    drawFractal() {
      var x1, y1, x2, y2;
      // 获取 Canvas 元素
      const canvas = this.$refs.canvas;
      canvas.width = this.canvasWidth * this.zoom_ratio;
      canvas.height = this.canvasHeight * this.zoom_ratio;
      const ctx = canvas.getContext("2d");
      ctx.clearRect(0, 0, canvas.width, canvas.height); // 清空画布

      // 计算画布中心点坐标
      if (this.down_flag) {
        x1 = (this.canvasWidth * this.zoom_ratio) / 2 + this.cx;
        y1 = (this.canvasHeight * this.zoom_ratio) / 2 + this.cy;
      } else {
        x1 =
          (this.canvasWidth * this.zoom_ratio) / 2 +
          (this.cx + this.move_event.clientX - this.down_event.clientX);
        y1 =
          (this.canvasHeight * this.zoom_ratio) / 2 +
          (this.cy + this.move_event.clientY - this.down_event.clientY);
      }

      // 根据线条长度计算终点坐标
      x2 = x1 + this.len;
      y2 = y1;
      if (this.event_flag == 0) {
        // 添加鼠标事件监听器
        canvas.addEventListener("mousedown", (event) => {
          canvas.addEventListener("mousemove", onMouseMove);
          this.down_event = event;
          this.down_flag = 0;
          console.log("鼠标左键按下" + this.cx + ":" + this.cy);
        });

        canvas.addEventListener("mouseup", () => {
          canvas.removeEventListener("mousemove", onMouseMove);
          this.down_flag = 1;
          this.cx += this.move_event.clientX - this.down_event.clientX;
          this.cy += this.move_event.clientY - this.down_event.clientY;
          console.log("鼠标左键松开" + this.cx + ":" + this.cy);
        });

        // 添加鼠标滚轮事件监听器
        canvas.addEventListener("wheel", (event) => {
          if (event.shiftKey) {
            // 如果按下了 shift 键
            if (event.deltaY > 0) {
              // 向下滚动,减少 len 的值
              if (this.zoom_ratio >= 1) {
                this.zoom_ratio += 1; // 可以根据需要调整增减的步长
              } else {
                this.zoom_ratio += 0.1; // 可以根据需要调整增减的步长
              }
            } else {
              // 向上滚动,增加 len 的值
              if (this.zoom_ratio > 1) {
                this.zoom_ratio -= 1; // 可以根据需要调整增减的步长
              } else {
                this.zoom_ratio -= 0.1; // 可以根据需要调整增减的步长
              }
            }
          }
        });
        const onMouseMove = (event) => {
          this.move_event = event;
        };
        this.event_flag = 1;
      }

      for (var i = 0; i <= this.depth; i++) {
        const endnew = this.rotatePoint(x2, y2, this.angle * i, x1, y1);
        // 开始绘制线条
        ctx.beginPath();
        ctx.strokeStyle = "#ffffff"; // 设置线条颜色为白色
        ctx.moveTo(x1, y1); // 设置起点坐标为画布中心点
        ctx.lineTo(endnew.x, endnew.y); // 设置终点坐标
        ctx.stroke(); // 绘制线条

        x1 = endnew.x;
        y1 = endnew.y;

        x2 = x1 + this.len - this.side_decay * i;
        y2 = y1;
      }
    },

    // 角度计算
    rotatePoint(x, y, angle, pivotX, pivotY) {
      // 将角度转换为弧度
      const radians = (angle * Math.PI) / 180;

      // 计算相对于旋转中心的坐标
      const newX =
        Math.cos(radians) * (x - pivotX) -
        Math.sin(radians) * (y - pivotY) +
        pivotX;
      const newY =
        Math.sin(radians) * (x - pivotX) +
        Math.cos(radians) * (y - pivotY) +
        pivotY;

      return { x: newX, y: newY };
    },
  },
  watch: {
    angle: "drawFractal",
    depth: "drawFractal",
    len: "drawFractal",
    cx: "drawFractal",
    cy: "drawFractal",
    side_decay: "drawFractal",
    move_event: "drawFractal",
    zoom_ratio: "drawFractal",
  },
};
</script>

<style>
/* canvas {
  border: 1px solid #ccc;
} */
</style>

你可能感兴趣的:(javascript,开发语言)