2016-12-02 184 views
0

我想在下面的图片来绘制鼠标一个扇形的矩形状绘制一个扇形的矩形

enter image description here

我能够用代码绘制矩形下方

function Rectangle(start, end) { 
 
    var w = (end.x - start.x); 
 
    var h = (end.y - start.y); 
 
    return ["M", start.x, start.y, "L", (start.x + w), start.y, "L", start.x + w, start.y + h, "L", start.x, start.y + h, "L", start.x, start.y].join(' '); 
 
} 
 

 
var point; 
 
document.addEventListener('mousedown', function(event) { 
 
    point = { 
 
    x: event.clientX, 
 
    y: event.clientY 
 
    } 
 
}); 
 

 
document.addEventListener('mousemove', function(event) { 
 
    var target = { 
 
    x: event.clientX, 
 
    y: event.clientY 
 
    } 
 
    if(point) { 
 
    var str = Rectangle(point, target); 
 
    document.getElementById('test').setAttribute('d', str); 
 
    } 
 
}); 
 

 
document.addEventListener('mouseup', function(event) { 
 
    point = null; 
 
});
body, html { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0; 
 
    padding: 0 
 
} 
 
svg { 
 
    height:100%; 
 
    width: 100% 
 
}
<svg> 
 
    <path id="test" style="stroke-width: 4; stroke: RGBA(212, 50, 105, 1.00); fill: none" /> 
 
    </svg>

但是,当我尝试转换成扇形矩形我看到不同的模式完全匹配Infinite Monkey Theorm

我试过的方法是,在虚拟元素上绘制一个矩形路径。将每个点乘以15直到总长度。然后在这些点之间绘制弧线。它不工作。另外,我想避免使用getPointAtLength,因为它的移动支持不是很好。

var pathEle = document.createElementNS('http://www.w3.org/2000/svg', 'path'); 
 
pathEle.setAttribute('d', rectangle(point, target)); 
 
window.pathEle = pathEle; 
 

 
var points = []; 
 
for (var i = 0; i < pathEle.getTotalLength(); i += 15) { 
 
    points.push(pathEle.getPointAtLength(i)); 
 
} 
 

 
document.getElementById('test1').setAttribute('d', toSVGPath(points));

+0

会发生什么,如果矩形的边的长度不是15的倍数?应该如何处理这个小的剩余长度? –

+0

@PaulLeBeau它不会是对称的。附图中的第一个框就是我想要实现的一个完美例子。角落应该成为弧形。所以数字15是随机抽取的,我认为它应该是计算值 – Exception

回答

2

像这样的事情?

我正在使用弧来制作扇贝。你可能想调整扇贝的计算方式以获得更好的角落。但我会把它留给你。

var scallopSize = 30; 
 

 
function Rectangle(start, end) { 
 
    var minX = Math.min(start.x, end.x); 
 
    var minY = Math.min(start.y, end.y); 
 
    var w = Math.abs(end.x - start.x); 
 
    var h = Math.abs(end.y - start.y); 
 

 
    // Calculate scallop sizes 
 
    var numW = Math.round(w/scallopSize); 
 
    if (numW === 0) numW = 1; 
 
    var numH = Math.round(h/scallopSize); 
 
    if (numH === 0) numH = 1; 
 
    var stepW = w/numW; 
 
    var stepH = h/numH; 
 

 
    // top 
 
    var p = minX + stepW/2; // start each size at half a scallop along 
 
    var path = ["M", p, minY]; 
 
    for (var i=1; i < numW; i++) { // numW-1 scallops per side 
 
    p += stepW; 
 
    path.push('A'); 
 
    path.push(stepW/2 + 1); // Add 1 to the radius to ensure it's 
 
    path.push(stepW/2 + 1); // big enough to span the stepW 
 
    path.push("0 0 1"); 
 
    path.push(p); 
 
    path.push(minY); 
 
    } 
 
    // top right 
 
    var p = minY + stepH/2; 
 
    path.push('A'); 
 
    path.push(stepH/2.8); // 2 * sqrt(2) 
 
    path.push(stepH/2.8); // corners are a little smaller than the scallops 
 
    path.push("0 0 1"); 
 
    path.push(minX + w); 
 
    path.push(p); 
 
    // right 
 
    for (var i=1; i < numH; i++) { 
 
    p += stepH; 
 
    path.push('A'); 
 
    path.push(stepH/2 + 1); 
 
    path.push(stepH/2 + 1); 
 
    path.push("0 0 1"); 
 
    path.push(minX + w); 
 
    path.push(p); 
 
    } 
 
    // bottom right 
 
    var p = minX + w - stepW/2; 
 
    path.push('A'); 
 
    path.push(stepH/2.8); 
 
    path.push(stepH/2.8); 
 
    path.push("0 0 1"); 
 
    path.push(p); 
 
    path.push(minY + h); 
 
    // bottom 
 
    for (var i=1; i < numW; i++) { 
 
    p -= stepW; 
 
    path.push('A'); 
 
    path.push(stepW/2 + 1); 
 
    path.push(stepW/2 + 1); 
 
    path.push("0 0 1"); 
 
    path.push(p); 
 
    path.push(minY + h); 
 
    } 
 
    // bottom left 
 
    var p = minY + h - stepH/2; 
 
    path.push('A'); 
 
    path.push(stepH/2.8); 
 
    path.push(stepH/2.8); 
 
    path.push("0 0 1"); 
 
    path.push(minX); 
 
    path.push(p); 
 
    // left 
 
    for (var i=1; i < numH; i++) { 
 
    p -= stepH; 
 
    path.push('A'); 
 
    path.push(stepH/2 + 1); 
 
    path.push(stepH/2 + 1); 
 
    path.push("0 0 1"); 
 
    path.push(minX); 
 
    path.push(p); 
 
    } 
 
    // top left 
 
    path.push('A'); 
 
    path.push(stepH/2.8); 
 
    path.push(stepH/2.8); 
 
    path.push("0 0 1"); 
 
    path.push(minX + stepW/2); 
 
    path.push(minY); 
 
    path.push('Z'); 
 

 
    return path.join(' '); 
 
} 
 

 
var point; 
 
document.addEventListener('mousedown', function(event) { 
 
    point = { 
 
    x: event.clientX, 
 
    y: event.clientY 
 
    } 
 
}); 
 

 
document.addEventListener('mousemove', function(event) { 
 
    var target = { 
 
    x: event.clientX, 
 
    y: event.clientY 
 
    } 
 
    if(point) { 
 
    var str = Rectangle(point, target); 
 
    document.getElementById('test').setAttribute('d', str); 
 
    } 
 
}); 
 

 
document.addEventListener('mouseup', function(event) { 
 
    point = null; 
 
});
body, html { 
 
    height: 100%; 
 
    width: 100%; 
 
    margin: 0; 
 
    padding: 0 
 
} 
 
svg { 
 
    height:100%; 
 
    width: 100% 
 
}
<svg> 
 
    <path id="test" style="stroke-width: 4; stroke: RGBA(212, 50, 105, 1.00); fill: none" /> 
 
    </svg>

+0

这看起来很好 – Exception

+0

这是我正在寻找的确切的东西。你可以调整角落也是与其他扇贝相同的大小。 – Exception

+0

我会把它作为一个练习。我的答案旨在告诉你如何开始。如果你想雇用我来让这个例子完全按照你的想法工作,那么让我知道。 –