Mari kita lihat sintaks lukisan kanvas biasa:
ctx.arc(centerX,centerY,radius,0,PI*2,true);
ctx.shadowColor = 'rgba(0,0,0,0.5)';
ctx.shadowBlur = "10" ;
ctx.fill();
ctx.beginPath();
ctx.shadowColor = 'rgba(0,0,0,0)';
ctx.moveTo( centerX-radius, centerY);
ctx.lineTo(centerX-radius,centerY - 50);
ctx.lineTo(centerX radius,centerY - 50);
ctx.lineTo(centerX radius,centerY) ;
// ctx.lineTo(centerX-radius,centerY);
ctx.fill();
ctx.beginPath();
ctx.fillStyle = 'rgba(255,0,0 ,1)' ;
ctx.arc(centerX,centerY-50,radius,0,PI*2,true);
ctx.fill();
Saya bukan gembira dengan sintaks kanvas asli Terdapat dua perkara: 1. Setiap ayat didahului oleh ctx (iaitu, objek konteks2d kanvas), dan 2. Setiap fungsi atau atribut mengambil satu baris, yang merupakan pembaziran ruang.
Saya sangat menghargai sintaks rantai jQuery, seperti:
$('#div1').show(300).html(p).delay(3000).slideUp(300).remove();
Oleh itu, saya juga ingin menggunakan sintaks ini untuk lukisan kanvas:
ctx.moveTo(500,0).lineTo(500,500).strokeStyle('#f00').stroke();
Salah satu cara ialah mensimulasikan objek context2d, ini Objek menyokong semua kaedah context2d asli, tetapi juga menyokong rantaian.
Walau bagaimanapun, anda tidak boleh mempunyai terlalu banyak kod, jika tidak, tiada siapa yang akan mahu menggunakannya.
Berikut ialah coretan kod lengkap yang saya namakan "kelas" ini XtendCanvas (ia bermula dengan X semula):
// Biarkan kanvas menyokong sintaks rantaian, daripada Ten Years Light
~fungsi () {var pro = ['simpan ','restore', 'skala', 'putar', 'terjemah', 'transform', 'createLinearGradient', 'createRadialGradient', 'getLineDash', 'clearRect', 'fillRect', 'beginPath', 'closePath', 'moveTo', 'lineTo', 'quadraticCurveTo', 'bezierCurveTo', 'arcTo', 'rect', 'arka', 'fill', 'stroke', 'clip', 'isPointInPath', 'measureText', 'clearShadow ', 'fillText', 'strokeText', 'strokeRect', 'drawImage', 'drawImageFromRect', 'putImageData', 'createPattern', 'createImageData', 'getImageData', 'lineWidth', 'strokeStyle', 'globalAlpha', 'fillStyle','font','shadowOffsetX','shadowOffsetY','shadowBlur','shadowColor','lineCap','lineJoin','miterLimit'];
fungsi XtendCanvas (kanvas) {
var ctx = canvas.getContext('2d'),
fn = function(){},
fnP = fn.prototype;
for(var j = 0,p=pro[0] ;p;p=pro[j ]) {
fn.prototype[p] = function (p) {
return function () {
var args = Array.prototype.slice.call(arguments) ;
// console.log(args);
if(typeof ctx[p] == 'function') {
ctx[p].apply(ctx,args);
} else {
ctx[p] = args '';
}
kembalikan fnP;
};
}(p);
}
kembalikan fn baharu;
};
tetingkap. Ia boleh digunakan seperti context2d biasa, tetapi perbezaannya ialah ia menyokong sintaks rantai:
Salin kodctx.moveTo(500,0 ).lineTo(500,500) .strokeStyle('#f00').stroke();
Dengan cara ini anda boleh meletakkan semua operasi dalam satu ayat, dan anda juga boleh mengganggu pada bila-bila masa, melakukan perkara lain, dan kemudian meneruskan.
Kod ini bukan peningkatan kepada kanvas, tetapi hanya membenarkan ia menyokong sintaks rantaian. Tetapi kelebihannya ialah ia mempunyai kurang kod dan boleh dibenamkan dalam mana-mana perpustakaan JS Di sini saya berharap untuk mendapat "pengesyoran" daripada anda
Mesti ada kawasan yang patut diperbaiki dalam kod itu dan semua orang boleh memperbaikinya. dengan sendiri. Tetapi - jangan lupa penggali sumur apabila anda minum air Saya harap semua orang akan mengingati saya. Inilah ideanya:
Seperti yang anda lihat, bahagian terpanjang kod ialah array pro yang menyimpan nama kaedah, manakala kod teras adalah sangat pendek. Mengapa saya perlu mencipta tatasusunan sedemikian?
Pada asalnya, saya ingin mewarisi semua kaedah asli terus daripada CanvasRenderingContext2D, tetapi apabila melintasi CanvasRenderingContext2D ini dalam setiap penyemak imbas, hasilnya tidak konsisten. Jika saya mewarisinya secara langsung, maka apabila anda ingin menggunakan kaedah dalam Chrome untuk melaksanakan dalam Firefox, ralat akan dilaporkan.
Jadi saya hanya mengekstrak kaedah dan nama sifat biasa yang tidak boleh dibantah dalam CanvasRenderingContext2D Tiada cara lain selain membina tatasusunan tetap - anda boleh menambah kaedah anda pada budi bicara anda sendiri.
Kaedah dan sifat diekstrak, dan kemudian kaedah asli ditambahkan pada objek baharu saya. Saya mencipta fungsi kosong yang dipanggil fn untuk meletakkan kaedah saya.
Memandangkan elemen dalam tatasusunan ini mempunyai kedua-dua fungsi dan atribut, saya menilai sama ada ia adalah fungsi dalam gelung Jika ia adalah fungsi, ia akan dilaksanakan dengan parameter jika ia bukan fungsi ia mestilah atribut , tetapkan parameter kepada atribut ini.
Dengan cara ini, apabila anda menetapkan atribut kanvas, anda tidak perlu mengganggu rantai Anda hanya boleh menghantar nilai atribut secara langsung sebagai parameter, contohnya:
ctx.strokeStyle('#f00')
Akhir sekali, kunci utama , iaitu mengembalikan fn. Helah ini dipelajari daripada jQuery dan merupakan kunci untuk menyokong sintaks rantai.
Fungsi tanpa nama, penutupan, prototaip dan gelung pelik yang saya bincangkan dalam artikel sebelum ini digunakan dalam perenggan ini.
Nampaknya agak mudah untuk dikatakan, tetapi saya benar-benar memikirkannya untuk masa yang lama, saya harap ia akan berguna kepada semua orang.
Dalam proses menulis kod, saya mendapati bahawa Chrome mempunyai pendekatan yang sangat baik Ia mempunyai satu siri fungsi bermula dengan set, seperti setStrokeColor, setLineCap dan fungsi lain Dengan menghantar parameter kepada mereka, ia boleh gantikan gaya stroke dan lineCap yang sepadan, iaitu, kanvasnya penuh dengan fungsi dan tiada atribut Dalam kes itu, saya tidak perlu menilai sama ada ia adalah fungsi atau atribut. Tetapi tidak ada perkara sedemikian dalam firefox, jadi saya hanya boleh menggunakan idea sebelumnya.
Izinkan saya juga melepaskan fungsi set
:
var bak = ['setTransform','setAlpha', 'setCompositeOperation', 'setLineWidth', 'setLineCap', 'setLineJoin', 'setMiterLimit', 'setLineDash', 'setShadow','setStrokeColor','setFillColor'];
Penggunaannya mudah difahami sepintas lalu. Anda juga boleh memilih beberapa untuk ditambahkan pada tatasusunan pro dalam kod sebelumnya.
Akhir sekali, saya tertanya-tanya mengapa kod saya tidak diserlahkan. . . Jika anda telah menontonnya sehingga akhir, maka anda juga boleh memberi saya cadangan, supaya saya juga boleh menjadi sia-sia.