扫码关注官方订阅号
要用前端代码写这样的一个图形;需要达到的交互效果是:
当鼠标移动到里面某个区域时,该扇形区域变成灰色块
并且对应的外圈,边框变成红色
人生最曼妙的风景,竟是内心的淡定与从容!
单纯的DOM非常麻烦,你应该用SVG或者canvas
这是SVG的例子
http://jsbin.com/fedehodaku/e...
<svg width="500" height="500" viewBox="0 0 1000 1000" xmlns="http://www.w3.org/2000/svg" style="position: fixed; top: 0px; left: 0px; background-color: white;"> <style> path.area { fill-opacity: 0; fill: #CCCCCC; } path.area:hover { fill-opacity: 1; } </style> <g stroke="gray" stroke-dasharray="10 10" fill-opacity="0"> <circle cx="500" cy="500" r="200"></circle> <circle cx="500" cy="500" r="300"></circle> <circle cx="500" cy="500" r="400"></circle> <circle cx="500" cy="500" r="500" stroke="#FF6666"></circle> </g> <g stroke="gray"> <line x1="600" x2="1000" y1="500" y2="500"></line> <line x1="570.71" x2="853.55" y1="570.71" y2="853.55"></line> <line x1="500" x2="500.00" y1="600" y2="1000"></line> <line x1="429.28" x2="146.44" y1="570.71" y2="853.55"></line> <line x1="400" x2="0" y1="500" y2="500.00"></line> <line x1="429.28" x2="146.44" y1="429.28" y2="146.44"></line> <line x1="500" x2="499.99" y1="400" y2="0"></line> <line x1="570.71" x2="853.55" y1="429.28" y2="146.44"></line> </g> <circle cx="500" cy="500" r="100" fill="#FF6666" stroke-opacity="0"></circle> <path d="M600 500 A100 100 0 0 1 570.71 570.71 L641.42 641.42 A200 200 0 0 0 700 500 Z" class="area"></path> <path d="M570.71 570.71 A100 100 0 0 1 500 600 L500 700 A200 200 0 0 0 641.42 641.42 Z" class="area"></path> <path d="M500 600 A100 100 0 0 1 429.28 570.71 L358.57 641.42 A200 200 0 0 0 500 700 Z" class="area"></path> <path d="M429.28 570.71 A100 100 0 0 1 400 500 L300 500 A200 200 0 0 0 358.57 641.42 Z" class="area"></path> <path d="M400 500 A100 100 0 0 1 429.28 429.28 L358.57 358.57 A200 200 0 0 0 300 500 Z" class="area"></path> <path d="M429.28 429.28 A100 100 0 0 1 500 400 L499.99 300 A200 200 0 0 0 358.57 358.57 Z" class="area"></path> <path d="M500 400 A100 100 0 0 1 570.71 429.28 L641.42 358.57 A200 200 0 0 0 499.99 300 Z" class="area"></path> <path d="M570.71 429.28 A100 100 0 0 1 600 500 L700 499.99 A200 200 0 0 0 641.42 358.57 Z" class="area"></path> <path d="M700 500 A200 200 0 0 1 641.42 641.42 L712.13 712.13 A300 300 0 0 0 800 500 Z" class="area"></path> <path d="M641.42 641.42 A200 200 0 0 1 500 700 L500 800 A300 300 0 0 0 712.13 712.13 Z" class="area"></path> <path d="M500 700 A200 200 0 0 1 358.57 641.42 L287.86 712.13 A300 300 0 0 0 500 800 Z" class="area"></path> <path d="M358.57 641.42 A200 200 0 0 1 300 500 L200 500.00 A300 300 0 0 0 287.86 712.13 Z" class="area"></path> <path d="M300 500 A200 200 0 0 1 358.57 358.57 L287.86 287.86 A300 300 0 0 0 200 500.00 Z" class="area"></path> <path d="M358.57 358.57 A200 200 0 0 1 499.99 300 L499.99 200 A300 300 0 0 0 287.86 287.86 Z" class="area"></path> <path d="M499.99 300 A200 200 0 0 1 641.42 358.57 L712.13 287.86 A300 300 0 0 0 499.99 200 Z" class="area"></path> <path d="M641.42 358.57 A200 200 0 0 1 700 499.99 L800 499.99 A300 300 0 0 0 712.13 287.86 Z" class="area"></path> <path d="M800 500 A300 300 0 0 1 712.13 712.13 L782.84 782.84 A400 400 0 0 0 900 500 Z" class="area"></path> <path d="M712.13 712.13 A300 300 0 0 1 500 800 L500 900 A400 400 0 0 0 782.84 782.84 Z" class="area"></path> <path d="M500 800 A300 300 0 0 1 287.86 712.13 L217.15 782.84 A400 400 0 0 0 500 900 Z" class="area"></path> <path d="M287.86 712.13 A300 300 0 0 1 200 500.00 L100 500.00 A400 400 0 0 0 217.15 782.84 Z" class="area"></path> <path d="M200 500.00 A300 300 0 0 1 287.86 287.86 L217.15 217.15 A400 400 0 0 0 100 500.00 Z" class="area"></path> <path d="M287.86 287.86 A300 300 0 0 1 499.99 200 L499.99 100 A400 400 0 0 0 217.15 217.15 Z" class="area"></path> <path d="M499.99 200 A300 300 0 0 1 712.13 287.86 L782.84 217.15 A400 400 0 0 0 499.99 100 Z" class="area"></path> <path d="M712.13 287.86 A300 300 0 0 1 800 499.99 L900 499.99 A400 400 0 0 0 782.84 217.15 Z" class="area"></path> <path d="M900 500 A400 400 0 0 1 782.84 782.84 L853.55 853.55 A500 500 0 0 0 1000 500 Z" class="area"></path> <path d="M782.84 782.84 A400 400 0 0 1 500 900 L500.00 1000 A500 500 0 0 0 853.55 853.55 Z" class="area"></path> <path d="M500 900 A400 400 0 0 1 217.15 782.84 L146.44 853.55 A500 500 0 0 0 500.00 1000 Z" class="area"></path> <path d="M217.15 782.84 A400 400 0 0 1 100 500.00 L0 500.00 A500 500 0 0 0 146.44 853.55 Z" class="area"></path> <path d="M100 500.00 A400 400 0 0 1 217.15 217.15 L146.44 146.44 A500 500 0 0 0 0 500.00 Z" class="area"></path> <path d="M217.15 217.15 A400 400 0 0 1 499.99 100 L499.99 0 A500 500 0 0 0 146.44 146.44 Z" class="area"></path> <path d="M499.99 100 A400 400 0 0 1 782.84 217.15 L853.55 146.44 A500 500 0 0 0 499.99 0 Z" class="area"></path> <path d="M782.84 217.15 A400 400 0 0 1 900 499.99 L1000 499.99 A500 500 0 0 0 853.55 146.44 Z" class="area"></path> </svg>
你可以自己写个代码,然后哪里出错,不通了来求助,你这样直接把需求粘贴出来,你来找免费劳动力了??兄弟我感觉不会有人给你回答的
想到一种 思路 四个 方块 盒子 ,
这四个 盒子 做为 父级盒子, 注意overflow : hidden , 每一个盒子 内 有 两个 用border-radius 处理的 1 / 4 圆
将 1/ 4 旋转一下,每个1/4圆 都被 方形 父盒子 遮住一半。
就可以实现了 ,
另外如果感觉 麻烦 的话, 就用CANVAS 慢慢画吧
!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中文网服务号
QQ扫码加入技术交流群
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
PHP学习
技术支持
返回顶部
单纯的DOM非常麻烦,你应该用SVG或者canvas
这是SVG的例子
http://jsbin.com/fedehodaku/e...
你可以自己写个代码,然后哪里出错,不通了来求助,你这样直接把需求粘贴出来,你来找免费劳动力了??兄弟我感觉不会有人给你回答的
想到一种 思路 四个 方块 盒子 ,
这四个 盒子 做为 父级盒子, 注意overflow : hidden , 每一个盒子 内 有 两个 用border-radius 处理的 1 / 4 圆
将 1/ 4 旋转一下,每个1/4圆 都被 方形 父盒子 遮住一半。
就可以实现了 ,
另外如果感觉 麻烦 的话, 就用CANVAS 慢慢画吧
给你个提示:用border-radius做
用角度和距离圆心距离确定鼠标位置,就是那个灰色的块用canvas画出来。
dom不用考虑,即使能实现,兼容性什么的也很难保证,这种复杂不规则图形用canvas或SVG把
实现第一点的话,一个字,(算法)
这又是楼主的大学期末作业把
其实这种图用D3写也不麻烦、基于svg