2012-11-29 16 views
6

के साथ बीच में एक छेद वाला पॉलीगॉन <canvas> टैग का उपयोग करके मुझे बहुभुज में एक छेद खींचने में सक्षम होना चाहिए।एचटीएमएल 5 के कैनवास

अभी मेरे पास कुछ आसान है जो startPath() का उपयोग करता है, फिर प्रत्येक बिंदु के लिए lineTo() करता है। फिर इसे भरने के साथ भर दिया जाता है()।

मैं एक बेकार बहुभुज के साथ एक पूर्ण बहुभुज के साथ एक डोनट की तरह नहीं देख सकता। मैं एक डोनट नहीं बना रहा हूं लेकिन यह इस उदाहरण के लिए उपयुक्त है।

क्या मुझे कुछ याद आ रही है? मैं इसे पूरी तरह से भरे नहीं खींचूंगा, फिर बीच को फिर से खींचना होगा।

+1

क्यों नहीं करते आप एक बनाना चाहते डोनट ? डोनट्स बहुत अच्छे हैं! कृपया आकृतियों को आकर्षित करने के लिए इस लिंक का संदर्भ लें: https://developer.mozilla.org/en-US/docs/Canvas_tutorial/Drawing_shapes – jazzytomato

+0

मैं डोनट्स के ड्रॉ के लायक होने के साथ सहमत हूं। यह लिंक: http://www.w3schools.com/tags/ref_canvas.asp भी उपयोगी हो सकता है। – GameAlchemist

+1

सिर्फ स्पष्टीकरण के लिए, मैं सैकड़ों अंकों के साथ एक जटिल बहुभुज चित्रित कर रहा हूं। एक बहुभुज के बीच में एक छेद रखने के लिए एक डोनट सिर्फ एक समानता है। – Nick

उत्तर

18

यह क्या मैं यह काम किया जाता है:

var ctx = canvas.getContext("2d");  
ctx.beginPath(); 

//polygon1--- usually the outside polygon, must be clockwise 
ctx.moveTo(0, 0); 
ctx.lineTo(200, 0); 
ctx.lineTo(200, 200); 
ctx.lineTo(0, 200); 
ctx.lineTo(0, 0); 
ctx.closePath(); 

//polygon2 --- usually hole,must be counter-clockwise 
ctx.moveTo(10, 10); 
ctx.lineTo(10,100); 
ctx.lineTo(100, 100); 
ctx.lineTo(100, 10); 
ctx.lineTo(10, 10); 
ctx.closePath(); 

// add as many holes as you want 
ctx.fillStyle = "#FF0000"; 
ctx.strokeStyle = "rgba(0.5,0.5,0.5,0.5)"; 
ctx.lineWidth = 1; 
ctx.fill(); 
ctx.stroke(); 

यहाँ मुख्य विचार आप केवल beginPath एक बार उपयोग कर सकते हैं; बाहरी बहुभुज घड़ी की दिशा में होना चाहिए और छेद दक्षिणावर्त होना चाहिए।

+0

बिल्कुल सही, आईएमओ स्वीकार किया जाना चाहिए। –

+0

यह सही काम करता है, लेकिन अब मैं सोच रहा हूं कि अंक को दक्षिणावर्त या विपरीत घड़ी के क्रम में ऑर्डर करने का कोई मौका है। मुझे कुछ एल्गोरिदम मिले लेकिन उनमें से कोई भी गैर-उत्तल बहुभुज के साथ काम नहीं करता है। –

+0

ऐसा लगता है कि छेद के लिए बाहरी पॉली और सीसीडब्ल्यू के लिए उन्मुखता को सीडब्ल्यू नहीं होना चाहिए - उन्हें सिर्फ विपरीत होना चाहिए। संदर्भ कम से कम क्रोम में _right_ एक के रूप में पहले इनपुट बहुभुज के अभिविन्यास को मानता है। –

1

अपना आकार इना घड़ी घड़ी दिशा (उदाहरण के लिए) बनाएं। फिर आप त्रिज्या को बढ़ा या घटा सकते हैं और विरोधी घड़ी की दिशा में जा सकते हैं।

+0

-1 कोई स्पष्टीकरण के लिए, केवल एक लिंक पोस्ट करना जो संभवतः मृत हो सकता है ठीक नहीं है – Aprillion

+1

स्पष्टीकरण पहला वाक्य है। – Richard

+1

आपका उत्तर पोस्ट करने के लिए धन्यवाद! कृपया सावधानीपूर्वक [स्व-संवर्धन पर अक्सर पूछे जाने वाले प्रश्न] (http://stackoverflow.com/faq#promotion) को पढ़ना सुनिश्चित करें। यह भी ध्यान रखें कि यह * आवश्यक * है कि जब भी आप अपनी साइट/उत्पाद से लिंक करते हैं तो आप एक अस्वीकरण पोस्ट करते हैं। –

12

आपके पास HTML5 कैनवास के साथ छेद खींचने के लिए 2 विकल्प हैं।

विकल्प 1:
विभिन्न घड़ी दिशा में बाहरी आकार और आंतरिक आकार बनाएं।

बाहरी आकार घड़ी की दिशा और आंतरिक आकार विरोधी घड़ी की दिशा में।
या बाहरी आकार दक्षिणावर्त और आंतरिक आकार विरोधी घड़ी की दिशा में।

ctx.beginPath(); 
//outer shape, clockwise 
ctx.moveTo(100,20); 
ctx.lineTo(200,200); 
ctx.lineTo(20,200); 
ctx.closePath(); 
//inner shape (hole), counter-clockwise 
ctx.moveTo(100,100); 
ctx.lineTo(70,170); 
ctx.lineTo(140,170); 
ctx.closePath(); 
//fill 
ctx.fillStyle = "#FF0000"; 
ctx.fill(); 

कोडिंग ड्राइंग दिशा का पता लगाने के लिए थोड़ा दर्द है जब हम कोडिंग कर रहे हैं।

आप पता लगाने के लिए कि क्या डॉट्स की एक श्रृंखला दक्षिणावर्त है या नहीं की जरूरत है, यहाँ एक अच्छा कार्य है:

function isClockwise(dots){ 
    var sum = 0; 
    for(var i=1, n=dots.length; i<n; i++){ 
     sum += (dots[i][0] - dots[i-1][0]) * (dots[i][1] + dots[i-1][1]); 
    } 
    sum += (dots[0][0] - dots[n-1][0]) * (dots[0][1] + dots[n-1][1]); 
    return sum < 0; 
} 
console.log(isClockwise([[100,20], [200,200], [20,200]])); //true 
console.log(isClockwise([[100,20], [20,200], [200,200]])); //false 

अपने डॉट्स दक्षिणावर्त है, लेकिन आप वामावर्त, .reverse (की जरूरत है) अपने डॉट्स सरणी।

var dots = [[100,20], [200,200], [20,200]]; 
dots.reverse(); 

विकल्प 2:
प्रयोग करें 'evenodd', शासन को भरने के किसी भी दिशा में अपने आकार आकर्षित।

इस तरह चुनाव 1.
fill() method API देखने के तुलना में बहुत सरल है:

void ctx.fill(); 
    void ctx.fill(fillRule); 
    void ctx.fill(path, fillRule); 

fillRule"अशून्य" हो सकता है या "evenodd"
"अशून्य": गैर शून्य घुमावदार नियम, जो डिफ़ॉल्ट नियम है।
"evenodd": यहां तक ​​कि विषम घुमावदार नियम।

enter image description here

1

आप evenodd भरने नियम का उपयोग कर सकते हैं: fill('evenodd')

Even-odd rule

// properties 
 
// - outer square 
 
var outerLength = 200; 
 
// - inner length 
 
var innerLength = outerLength/2; 
 

 
// cnavas 
 
var canvas = document.getElementById('canvas'); 
 
var width = canvas.width = document.body.clientWidth; 
 
var height = canvas.height = document.body.clientHeight; 
 
var context = canvas.getContext('2d'); 
 

 
// path 
 
// - outer square 
 
context.rect(
 
    (width - outerLength)/2, 
 
    (height - outerLength)/2, 
 
    outerLength, 
 
    outerLength 
 
); 
 
// - inner square 
 
var x0 = (width - innerLength)/2; 
 
var y0 = (height - innerLength)/2; 
 
context.moveTo(x0, y0); 
 
context.rect(
 
    x0, 
 
    y0, 
 
    innerLength, 
 
    innerLength 
 
); 
 

 
// draw 
 
// - stroke 
 
context.lineWidth = 10; 
 
context.stroke(); 
 
// - fill 
 
context.fillStyle = 'red'; 
 
context.fill('evenodd');
html, 
 
body { 
 
    margin: 0; 
 
    height: 100%; 
 
    overflow: hidden; 
 
}
<canvas id="canvas"><canvas>

संबंधित मुद्दे