html5 - कैनवास तत्व - कई परतें


176

किसी भी विस्तार पुस्तकालय के बिना, क्या एक ही कैनवास तत्व में कई परतें होना संभव है?

तो अगर मैं शीर्ष परत पर एक स्पष्ट व्याख्या करता हूं, तो यह नीचे वाले को नहीं मिटाएगा?

धन्यवाद।


आप radikalfx.com/2009/10/16/canvas-collage पर एक नज़र डालना चाहते हैं । वह "लेयर्स" तकनीक का उपयोग करता है।
मैथ्यू

2
इसे देखें .. html5.litten.com/using-multiple-html5-canvases-as-layers इससे आपको अपने मुद्दे को उचित तरीके से हल करने में मदद मिलेगी
दैनिक

@Dakshika उस लिंक के लिए धन्यवाद, इसने कुछ वर्षों पहले कैनवास का उपयोग करने में आई एक समस्या के बारे में बताया कि एक लाइब्रेरी ने मेरा ख्याल रखा।
फेयरिंग

जवाबों:


267

नहीं, हालाँकि, आप <canvas>एक-दूसरे के ऊपर कई तत्वों को परत कर सकते हैं और कुछ इसी तरह पूरा कर सकते हैं।

<div style="position: relative;">
 <canvas id="layer1" width="100" height="100" 
   style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
 <canvas id="layer2" width="100" height="100" 
   style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
</div>

layer1कैनवास पर अपनी पहली परत , और दूसरी परत को कैनवास पर खींचें layer2। फिर जब आप clearRectऊपरी परत पर होते हैं, तो निचले कैनवास पर जो कुछ भी होता है, वह दिखाएगा।


वहाँ एक परत को छुपाने / अनहाइड करने का एक तरीका है .. जैसे कि मैं लेयर 1 को छुपा सकता हूँ और लेयर 2 दिखा सकता हूँ और आवश्यकता पड़ने पर इसके विपरीत कर सकता हूँ .. ??
जराकी

4
आप इसे CSS - यानी के साथ छिपा सकते हैं display: none;। या बस कैनवास को साफ करें, अगर यह परत को फिर से दिखाने के लिए इसे फिर से लाल करने के लिए सुपर महंगा नहीं है, तो परत को दिखाया जाना चाहिए।
जिमर

'वाम' और 'शीर्ष' को दिए गए मानों को '0px' होना चाहिए, न कि '0'।
ब्रायन ग्रीन

6
@BryanGreen सच नहीं है। "हालांकि, शून्य लंबाई के लिए यूनिट आइडेंटिफायर वैकल्पिक है (अर्थात वाक्य-रचना को <संख्या> 0) के रूप में दर्शाया जा सकता है।" w3.org/TR/css3-values/#lengths
xehpuk

क्या मैं कई कैनवस के लिए कंपोजीशन टाइप को नियंत्रित कर सकता हूं?
जियाआंग

40

इससे संबंधित:

यदि आपके पास अपने कैनवास पर कुछ है और आप इसके पीछे कुछ आकर्षित करना चाहते हैं - तो आप इसे संदर्भ में बदलकर कर सकते हैं। GlobalCompositeOperation सेटिंग को 'गंतव्य-ओवर' तक - और फिर इसे 'सोर्स-ओवर' पर लौटाएं जब आप ' फिर से किया।

   var context = document.getElementById('cvs').getContext('2d');

    // Draw a red square
    context.fillStyle = 'red';
    context.fillRect(50,50,100,100);



    // Change the globalCompositeOperation to destination-over so that anything
    // that is drawn on to the canvas from this point on is drawn at the back
    // of what's already on the canvas
    context.globalCompositeOperation = 'destination-over';



    // Draw a big yellow rectangle
    context.fillStyle = 'yellow';
    context.fillRect(0,0,600,250);


    // Now return the globalCompositeOperation to source-over and draw a
    // blue rectangle
    context.globalCompositeOperation = 'source-over';

    // Draw a blue rectangle
    context.fillStyle = 'blue';
    context.fillRect(75,75,100,100);
<canvas id="cvs" />


हाँ, यह ठीक है लेकिन मिटाने के मामले में, जैसा कि सवाल में पूछा गया है। यह दोनों परतों को समानांतर रूप से मिटा देगा। जो फिर से सही नहीं है।
परदीप जैन

27

आप canvasउन्हें दस्तावेज़ में शामिल किए बिना कई तत्व बना सकते हैं । ये आपकी परतें होंगी :

फिर आप उनके साथ जो भी करना चाहते हैं और अंत में अपनी सामग्री को गंतव्य कैनवास पर उचित क्रम में उपयोग करके प्रस्तुत drawImageकरें context

उदाहरण:

/* using canvas from DOM */
var domCanvas = document.getElementById('some-canvas');
var domContext = domCanvas.getContext('2d');
domContext.fillRect(50,50,150,50);

/* virtual canvase 1 - not appended to the DOM */
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.fillStyle = 'blue';
ctx.fillRect(50,50,150,150);

/* virtual canvase 2 - not appended to the DOM */    
var canvas2 = document.createElement('canvas')
var ctx2 = canvas2.getContext('2d');
ctx2.fillStyle = 'yellow';
ctx2.fillRect(50,50,100,50)

/* render virtual canvases on DOM canvas */
domContext.drawImage(canvas, 0, 0, 200, 200);
domContext.drawImage(canvas2, 0, 0, 200, 200);

और यहाँ कुछ कोडपेन है: https://codepen.io/anon/pen/mQWMMW


4
@ एससीएलआईओ ने कहा कि "प्रदर्शन हत्यारा है। लगभग ~ 10 गुना धीमा" पूरी तरह से गलत है। एक ही डोम कैनवास का उपयोग करने वाले मामलों पर निर्भर करता है और ऑफस्क्रीन कैनवस को प्रस्तुत करना डोम में कैनवास को स्टैक करने की तुलना में तेज है। आम गलती बेंचमार्किंग कॉल्स की बेंचमार्किंग है, कैनवस ड्रॉ कॉल्स को समयबद्ध किया जा सकता है, डोम रेंडरिंग जॅवास्क्रिप्शंस के संदर्भ से बाहर है और इसे टाइम नहीं किया जा सकता है। परिणाम यह है कि
बीओएम

@ Blindman67 मुझे पता है कि आपका क्या मतलब है। बस इस बेंचमार्क की जाँच करें: jsfiddle.net/9a9L8k7k/1 । यदि आप गलत समझते हैं, तो तीन कैनवस हैं, कैनवास 1 (ctx1) एक वास्तविक कैनवास है। कैनवास 2 (ctx2) और कैनवास 3 (ctx) ऑफ स्क्रीन हैं। छवि को पहले ctx3 पर प्रस्तुत किया गया है। इस बेंचमार्क के परीक्षण 1 में, मैं सीधे ctx1 को ctx1 पर प्रस्तुत करता हूं। टेस्ट 2 में, मैं ctx2 पर ctx3 और फिर ctx2 को ctx1 पर रेंडर करता हूं। मेरे कंप्यूटर पर टेस्ट 1 की तुलना में टेस्ट 2 30 गुना धीमा है। यही कारण है कि मैं कहता हूं कि एक मध्यवर्ती कैनवास का उपयोग करना बहुत धीमा है।
SCLeo

@ Blindman67 ऑफ-स्क्रीन कैनवास की चाल केवल तभी काम करती है, जब ऑफ़-स्क्रीन कैनवास स्थिर हो। गतिशील कैनवस का उपयोग प्रदर्शन को बहुत नुकसान पहुंचाएगा। (फिर से, जो मैं कहने की कोशिश कर रहा हूं कि डायनामिक ऑफ-स्क्रीन कैनवास बेहद धीमा है, संभवतः यह तकनीक (कई ऑफ-स्क्रीन कैनवास द्वारा नकली परतें) वांछनीय नहीं होंगी)
SCLeo

@ Blindman67 महत्वपूर्ण: बेंचमार्क का पता है https://jsfiddle.net/9a9L8k7k/3 , मैं संपादन के बाद बचाने के लिए भूल जाते हैं और स्टैक ओवरफ़्लो नहीं करता है मुझे अब और पिछली टिप्पणी को बदलने के लिए ...
SCLeo

4
@ Blindman67 मुझे खेद है, यह मेरी गलती है। मैंने परीक्षण किया और पाया कि मल्टीपल ऑफ स्क्रीन कैनवस का उपयोग करना बहुत आसान है। मुझे अभी भी यकीन नहीं है कि क्यों बेंचमार्क दिखाता है कि ऑफ स्क्रीन कैनवास का उपयोग करना धीमा है।
SCLeo

6

मुझे भी यही समस्या हो रही थी, मैंने स्थिति के साथ कई कैनवास तत्वों को: निरपेक्ष काम करता है, यदि आप आउटपुट को एक छवि में सहेजना चाहते हैं, तो यह काम नहीं करेगा।

इसलिए मैंने आगे बढ़कर कोड करने के लिए एक सरल लेयरिंग "सिस्टम" किया जैसे कि प्रत्येक परत का अपना कोड होता है, लेकिन यह सभी एक ही तत्व में प्रदान किया जाता है।

https://github.com/federicojacobi/layeredCanvas

मैं अतिरिक्त क्षमताओं को जोड़ने का इरादा रखता हूं, लेकिन अभी के लिए यह करेगा।

आप कई कार्य कर सकते हैं और उन्हें "नकली" परतों के लिए कॉल कर सकते हैं।


यह एक सही है।
नादिर

4

आप http://www.concretejs.com को भी चेकआउट कर सकते हैं , जो कि एक आधुनिक, हल्का, Html5 कैनवस फ्रेमवर्क है जो हिट डिटेक्शन, लेयरिंग और बहुत सी अन्य परिधीय चीजों को सक्षम बनाता है। आप इस तरह की चीजें कर सकते हैं:

var wrapper = new Concrete.Wrapper({
  width: 500,
  height: 300,
  container: el
});

var layer1 = new Concrete.Layer();
var layer2 = new Concrete.Layer();

wrapper.add(layer1).add(layer2);

// draw stuff
layer1.sceneCanvas.context.fillStyle = 'red';
layer1.sceneCanvas.context.fillRect(0, 0, 100, 100);

// reorder layers
layer1.moveUp();

// destroy a layer
layer1.destroy();

किस तरह से उन परतों को डोम में खत्म हो जाएगा? प्रत्येक एक सीएसएस के माध्यम से सुलभ?
गरवानी

0

मैं समझता हूं कि क्यू एक पुस्तकालय का उपयोग नहीं करना चाहता है, लेकिन मैं इसे Google खोजों से आने वाले अन्य लोगों के लिए पेश करूंगा। @EricRowell ने एक अच्छे प्लगइन का उल्लेख किया है, लेकिन, एक और प्लगइन भी है जिसे आप आज़मा सकते हैं, html2canvas

हमारे मामले में हम z-index"उत्पाद निर्माता" विजेट के रूप में स्तरित पारदर्शी पीएनजी का उपयोग कर रहे हैं । Html2canvas ने शानदार ढंग से स्टैक को छवियों को धक्का दिए बिना उबालने के लिए काम किया, और न ही जटिलताओं, वर्कअराउंड और "गैर-उत्तरदायी" कैनवास का उपयोग किया। हम इसे वेनिला कैनवास + जेएस के साथ सुचारू रूप से करने में सक्षम नहीं थे।

z-indexएक रिश्तेदार तैनात आवरण के भीतर स्तरित सामग्री उत्पन्न करने के लिए पूर्ण divs पर पहला उपयोग । फिर html2canvas के माध्यम से रैपर को एक प्रदान किए गए कैनवास को प्राप्त करने के लिए पाइप करें, जिसे आप एक इमेज के रूप में छोड़ सकते हैं, या आउटपुट के रूप में, ताकि एक क्लाइंट इसे बचा सके।


यदि आपके पास भारी छवियां हैं, तो एचटीएमएल को कैनवस में बदलने में कुछ समय लगेगा, हमें इससे सिर्फ इसलिए दूर जाना पड़ा क्योंकि प्रतिपादन में लंबा समय लगा।
विलिअस

@Vilius हाँ भारी / बड़ी छवियों पर अच्छा कॉल। हमने ४०० से अधिक परतों के साथ ३००K या उससे कम छवियों के साथ चिपके रहने की कोशिश की, अन्यथा संसाधन त्रस्त ग्राहक अंतिम खाद छवि डाउनलोड करते समय जला महसूस करेंगे। जिज्ञासु, आपने उस कम समय में क्या किया?
ढपिन

ठीक है, हमने पहली बार में कुछ आकर्षित करने के लिए HTML तत्वों का उपयोग करके एक बड़ी गलती की। क्योंकि हमारी एपी एक्स, वाई, चौड़ाई और ऊंचाई लौटा, हम HTML तत्वों का उपयोग करने के बजाय छवि खींचने के लिए jscanavs में चले गए। ध्यान रखें कि हमने रोटेशन के साथ कुछ मुद्दों को जोड़ा था (शुरुआती बिंदु थोड़े अजीब और अप्रत्याशित थे) और विशिष्ट आयामों का उपयोग करके इसमें छवियां लागू की गईं लेकिन सभी अंततः हल हो गए। हमने यह भी पाया कि हमारा इमेज प्रोसेसिंग एप्लिकेशन बहुत सारे संसाधनों को नष्ट कर रहा था, इसलिए हम उससे भी दूर चले गए।
विलिअस

0

लेकिन परत 02, परत 01 में सभी ड्राइंग को कवर करेगा। मैंने इसका उपयोग दोनों परतों में ड्राइंग दिखाने के लिए किया। उपयोग (पृष्ठभूमि-रंग: पारदर्शी;) शैली में।

    <div style="position: relative;"> 
      <canvas id="lay01" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 0; background-color: transparent;">
      </canvas> 
      <canvas id="lay02" width="500" height="500" style="position: absolute; left: 0; top: 0; z-index: 1; background-color: transparent;">
      </canvas>
</div>

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.