问题描述
我正在为reverse the draw direction的SVG路径命令编写脚本,到目前为止,一切都工作正常,但无法使用S
路径命令或T
。
在my implementations中仅用于三次贝塞尔曲线C
的路径反向功能中,它可以完美地工作,但是输出路径字符串相当大,有时长度是其两倍或三倍。
这是reversePath.js
的简化版本,到目前为止,它为S
和测试页实现了一些基本处理:
// the script I'm working on works with these arrays
var path = [['M',10,80],['C',40,65,95,['S',150,180,230,270,80]],target = document.getElementById('target');
// our focus is RIGHT HERE
function reversePath(pathInput){
let isClosed = pathInput.slice(-1)[0][0] === 'Z',params = {x1: 0,y1: 0,x2: 0,y2: 0,x: 0,y: 0,qx: null,qy: null},pathCommand = '',pLen = 0,reversedPath = [];
reversedPath = pathInput.map((seg,i,pathArray)=>{
pLen = pathArray.length
pathCommand = seg[0]
switch(pathCommand){
case 'M':
x = seg[1]
y = seg[2]
break
case 'Z':
x = pathArray[0][1]
y = pathArray[0][2]
break
default:
x = seg[seg.length - 2]
y = seg[seg.length - 1]
}
return {
c: pathCommand,x: x,y: y,seg: seg
}
}).map((seg,pathArray)=>{
let segment = seg.seg,prevSeg = i && pathArray[i-1],nextSeg = pathArray[i+1] && pathArray[i+1],result = []
pLen = pathArray.length
pathCommand = seg.c
params.x = i ? pathArray[i-1].x : pathArray[pLen-1].x
params.y = i ? pathArray[i-1].y : pathArray[pLen-1].y
switch(pathCommand){
case 'M':
result = isClosed ? ['Z'] : [pathCommand,params.x,params.y]
break
case 'C':
if ('S' === nextSeg.c) {
params.x2 = params.x1 + params.x2 / 2
params.y2 = params.y1 + params.y2 / 2
result = ['S',params.x2,params.y2,params.y]
} else {
params.x1 = segment[3]
params.y1 = segment[4]
params.x2 = segment[1]
params.y2 = segment[2]
result = [pathCommand,params.x1,params.y1,params.y];
}
break
case 'S':
params.x2 = params.x1 + params.x2 / 2
params.y2 = params.y1 + params.y2 / 2
if (nextSeg && 'S' === nextSeg.c) {
result = [pathCommand,params.y]
} else {
params.x1 = params.x1 + params.x2 / 2
params.y1 = params.y1 + params.y2 / 2
params.x2 = segment[1];
params.y2 = segment[2];
result = ['C',params.y];
}
break
case 'Z':
result = ['M',params.y]
break
default:
result = segment.slice(0,-2).concat([params.x,params.y])
}
return result
})
return isClosed ? reversedPath.reverse() : [reversedPath[0]].concat(reversedPath.slice(1).reverse())
}
function pathToString(pathArray) {
return pathArray.map(x=>x[0].concat(x.slice(1).join(' '))).join(' ')
}
function reverse(){
var reversed = pathToString(reversePath(path));
target.setAttribute('d',reversed)
target.closest('.col').innerHTML += '<br><p class="text-left">'+reversed+'</p>'
}
.row {width: 100%; display: flex; flex-direction: row}
.col {width: 50%; text-align: center}
.text-left {text-align: left}
<button onclick="reverse()">REVERSE</button>
<hr>
<div class="row">
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 270 160">
<path id="example" d="M10 80 C40 10,65 10,95 80S 150 150,180 80S 230 10 270 80" stroke="green" stroke-width="2" fill="transparent" />
</svg>
normal path
</div>
<div class="col">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 270 160">
<path id="target" d="M0 0L0 0" stroke="orange" stroke-width="2" fill="transparent" />
</svg>
reversed path (click the button)
</div>
</div>
我从Raphael.js实现开始,将S和Q和T路径命令转换为C
(cubicBezier),思考和进行逆向工程也许可以找到一种使之工作的方法。 / p>
因此,在反转形状时,我需要一点帮助来为这些S
和T
路径命令找出正确的公式。如果有人可以帮助我S
,我可以在T
上找到自己。
感谢您的回复。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)