javascript - 前端代码如何写出带交互效果的八卦图?
黄舟
黄舟 2017-04-11 11:38:50
[JavaScript讨论组]

要用前端代码写这样的一个图形;
需要达到的交互效果是:

  1. 当鼠标移动到里面某个区域时,该扇形区域变成灰色块

  2. 并且对应的外圈,边框变成红色

黄舟
黄舟

人生最曼妙的风景,竟是内心的淡定与从容!

全部回复(9)
伊谢尔伦

你可以自己写个代码,然后哪里出错,不通了来求助,你这样直接把需求粘贴出来,你来找免费劳动力了??兄弟我感觉不会有人给你回答的

天蓬老师
!function () {

  class Panel {
    constructor(canvas, x, y, r, n) {
      this.canvas = canvas;
      this.ctx = canvas.getContext('2d');
      this.ratio = 1;
      this.initScreenRatio();
      this.x = x * this.ratio;
      this.y = y * this.ratio;
      this.r = r * this.ratio;
      this.n = n * this.ratio;
      this.dr = Math.round(this.r / this.n);
      this.basePos = this.canvas.getBoundingClientRect();
      this.prePos = null;
      this.drawPanel();
      this.initEvent();
    }

    initScreenRatio() {
      const devicePixelRatio = window.devicePixelRatio || 1;
      const backingStoreRatio = this.ctx.webkitBackingStorePixelRatio ||
        this.ctx.mozBackingStorePixelRatio ||
        this.ctx.msBackingStorePixelRatio ||
        this.ctx.oBackingStorePixelRatio ||
        this.ctx.backingStorePixelRatio || 1;

      const ratio = devicePixelRatio / backingStoreRatio;
      this.canvas.style.borderWidth = 0;
      this.canvas.style.width = this.canvas.offsetWidth;
      this.canvas.style.height = this.canvas.offsetHeight;
      this.canvas.width = ratio * this.canvas.offsetWidth;
      this.canvas.height = ratio * this.canvas.offsetHeight;
      this.ratio = ratio;
    }


    drawPanel(clear) {
      const {x, y, ctx, r, dr, n,actived} = this;
      const _2PI = 2 * Math.PI;
      let i = 1;
      if(clear!==false){
        this.clear();
      }
      ctx.save();
      ctx.strokeStyle = '#ddd';
      ctx.setLineDash([8, 4]);

      //圆盘
      ctx.save();
      for (; i < n + 1; i++) {
        ctx.beginPath();
        ctx.arc(x, y, i * dr, 0, _2PI);
        if(i===n){
          ctx.strokeStyle = actived?'#f00':'#ddd';
        }
        ctx.stroke();
      }
      ctx.restore();
      //分割线
      ctx.translate(x, y);
      ctx.setLineDash([]);
      for (i = 0; i < 8; i++) {
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.lineTo(0, r);
        ctx.stroke();
        ctx.rotate(_2PI / 8);
      }
      ctx.restore();
    }

    clear(){
      this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height);
    }

    getArea(px, py) {
      const {basePos, x, y, dr} = this;
      const dx = (px - basePos.left) * this.ratio - x;
      const dy = (py - basePos.top) * this.ratio - y;
      const d = Math.ceil(Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)));
      let anum = Math.ceil(d / dr);
      if (dx === 0) {
        anum = 0;
      }
      const actan = dx > 0 ? (dy > 0 ? Math.atan(dy / dx) : 2 * Math.PI + Math.atan(dy / dx)) : Math.PI + Math.atan(dy / dx);
      return {
        n: anum > this.n ? null : anum,
        rotate: Math.floor(actan * 4 / Math.PI)
      }
    }

    fillCellPath(pos, col) {
      const {ctx, dr, x, y} = this;
      if (pos.n) {
        this.clear();
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(pos.rotate * Math.PI / 4);
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.arc(0, 0, (pos.n) * dr, 0, Math.PI / 4);
        ctx.closePath();
        ctx.fillStyle = col || '#000';
        ctx.fill();
        ctx.beginPath();
        ctx.moveTo(0, 0);
        ctx.arc(0, 0, (pos.n - 1) * dr, 0, Math.PI / 4);
        ctx.closePath();
        ctx.fillStyle = '#fff';
        ctx.fill();
        ctx.restore();
        this.drawPanel(false);
      }
    }

    initEvent() {
      this.canvas.addEventListener('mousemove', (e) => {
        const pos = this.getArea(e.pageX, e.pageY);
        if (!this.prePos || this.prePos.n !== pos.n || this.prePos.rotate !== pos.rotate && pos.n) {
          this.actived = true;
          if (this.prePos) {
            this.fillCellPath(this.prePos, '#fff');
          }
          this.fillCellPath(pos, '#000');
          this.prePos = pos;
        }else if(!pos.n){
          this.actived = false;
          this.drawPanel();
        }
      })
    }

  }


  const canvas = document.getElementById('canvas');
  const panel = new Panel(canvas, 300, 300, 250, 5);

} ()
大家讲道理

给你个提示:用border-radius做

天蓬老师

用角度和距离圆心距离确定鼠标位置,就是那个灰色的块用canvas画出来。

阿神

dom不用考虑,即使能实现,兼容性什么的也很难保证,这种复杂不规则图形用canvas或SVG把

高洛峰

实现第一点的话,一个字,(算法)

巴扎黑

这又是楼主的大学期末作业把

天蓬老师

其实这种图用D3写也不麻烦、基于svg

迷茫

坐等楼主写完。。
想过几个方案,感觉都太麻烦,,,,

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号