關(guān)于canvas在連接多點(diǎn)畫(huà)線時(shí)使用曲線優(yōu)化的一點(diǎn)心得

1.前言

canvas將多個(gè)點(diǎn)連接成線,最主要還是用于使用鼠標(biāo)繪畫(huà)之類(lèi)的用途,但是我們往往會(huì)發(fā)現(xiàn)使用這些點(diǎn)連接起來(lái)的線非常不規(guī)整,很不自然
所以大多數(shù)人想到優(yōu)化這一點(diǎn)的方法應(yīng)該就是將簡(jiǎn)單的點(diǎn)與點(diǎn)的直線連接改為帶一定曲度的曲線

2.參考

帶著目的我在網(wǎng)上查找相應(yīng)的文章然后找到了這個(gè)博客
但是這個(gè)博客不早知道是沒(méi)講清楚還是寫(xiě)錯(cuò)了,你是沒(méi)辦法直接使用他的方法的,里面有些參數(shù)不清楚,而且因?yàn)樘玫木壒世锩娴逆溄佣际Я?br> 所以我在網(wǎng)上搜索了里面提供的關(guān)鍵字:貝塞爾曲線控制點(diǎn)確定的方法.doc 百度文庫(kù)里有

根據(jù)里面的秒速完善了方法

        getCtrlPoint(ps, i, a, b){
            if(!a||!b){
                a=0.25;
                b=0.25;
            }
            let p_1 = ps[i-1],p = ps[i],p1 = ps[i+1],p2 = ps[i+2];
            if(typeof p_1 != 'number'){
                p_1 = p;
            }
            if(typeof p1 != 'number'){
                p1 = p;
            }
            if(typeof p2 != 'number'){
                p2 = p;
            }
            var pAx = p[0] + (p1[0] - p_1[0])*a;
            var pAy = p[1] + (p1[1] - p_1[1])*a;
            var pBx = p1[0] + (p2[0] - p[0])*b;
            var pBy = p1[1] + (p2[1] - p[1])*b;

            return {
                pA:{x:pAx,y:pAy},
                pB:{x:pBx,y:pBy}
            }
        }

第一個(gè)點(diǎn)和最后兩個(gè)點(diǎn)的算法文檔里面有說(shuō)明我就不多說(shuō)了

3.結(jié)果

context(){//canvas對(duì)象
    return canvas.getContext("2d");
},

根據(jù)方法使用曲線畫(huà)線方法劃線

//index表示當(dāng)前畫(huà)的是第幾個(gè)點(diǎn) for循環(huán)里的參數(shù)
var ctrlP = this.getCtrlPoint(points,index);
//這里坐標(biāo)減0.5是為了能讓線寬1px的線能顯示正常
this.context.bezierCurveTo(ctrlP.pA.x - 0.5, ctrlP.pA.y - 0.5, ctrlP.pB.x - 0.5,ctrlP.pB.y -0.5, point[0] - 0.5, point[1] - 0.5);

這里將直線改為曲線算成功了,但是我發(fā)現(xiàn)直接使用鼠標(biāo)畫(huà)的線依然很難看不自熱,這是因?yàn)槭髽?biāo)劃線點(diǎn)過(guò)于密集的原因,可以在劃線時(shí)間隔曲線將圖形模糊處理

//這個(gè)loop方法是我寫(xiě)的,你們可以使用forEach,只需要注意里面的this變量就行
//fuzzy這個(gè)變量表示當(dāng)前點(diǎn)是它的整倍數(shù)時(shí)才計(jì)入劃線點(diǎn),當(dāng)然這個(gè)數(shù)字不能太大不然會(huì)失真
points.loop(this,function(point,index){
    if(index%fuzzy == 0){
        var ctrlP = this.getCtrlPoint(points,index);
        this.context.bezierCurveTo(ctrlP.pA.x - 0.5, ctrlP.pA.y - 0.5, ctrlP.pB.x - 0.5,ctrlP.pB.y -0.5, point[0] - 0.5, point[1] - 0.5);
    }
});

老實(shí)說(shuō)感覺(jué)還是畫(huà)出來(lái)的線比原來(lái)是好點(diǎn),但是還是不自然的樣子

最后結(jié)果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容