खोज…


एक उत्तरदायी पूर्ण पृष्ठ कैनवास बनाना

एक पूर्ण पृष्ठ कैनवास बनाने और हटाने के लिए स्टार्टर कोड जो जावास्क्रिप्ट के माध्यम से घटनाओं का आकार देने के लिए प्रतिक्रिया करता है।

var canvas;    // Global canvas reference
var ctx;       // Global 2D context reference
// Creates a canvas
function createCanvas () {                
    const canvas = document.createElement("canvas"); 
    canvas.style.position = "absolute"; // Set the style 
    canvas.style.left     = "0px";      // Position in top left
    canvas.style.top      = "0px";
    canvas.style.zIndex   = 1;        
    document.body.appendChild(canvas);  // Add to document
    return canvas;
}
// Resizes canvas. Will create a canvas if it does not exist
function sizeCanvas () {                
    if (canvas === undefined) {         // Check for global canvas reference
        canvas = createCanvas();        // Create a new canvas element
        ctx = canvas.getContext("2d");  // Get the 2D context
    }
    canvas.width  = innerWidth;         // Set the canvas resolution to fill the page
    canvas.height = innerHeight;        
}
// Removes the canvas
function removeCanvas () {
    if (canvas !== undefined) {              // Make sure there is something to remove
        removeEventListener("resize", sizeCanvas); // Remove resize event
        document.body.removeChild(canvas);   // Remove the canvas from the DOM
        ctx = undefined;                     // Dereference the context
        canvas = undefined;                  // Dereference the canvas
     }
}

// Add the resize listener
addEventListener("resize", sizeCanvas); 
// Call sizeCanvas to create and set the canvas resolution
sizeCanvas();
// ctx and canvas are now available for use.

आप अब कैनवास की जरूरत है आपको कॉल करके इसे हटा सकते हैं removeCanvas()

Jsfiddle पर इस उदाहरण का एक डेमो

आकार बदलने के बाद माउस निर्देशांक (या स्क्रॉल करना)

कैनवस ऐप अक्सर माउस के साथ उपयोगकर्ता की बातचीत पर बहुत अधिक भरोसा करते हैं, लेकिन जब विंडो को आकार दिया जाता है, तो माउस ईवेंट समन्वयित करता है कि कैनवस पर निर्भर होने की संभावना है क्योंकि आकार बदलने से कैनवास विंडो के सापेक्ष एक अलग स्थिति में ऑफसेट होने का कारण बनता है। इस प्रकार, उत्तरदायी डिज़ाइन के लिए यह आवश्यक है कि विंडो के आकार बदलने पर कैनवास ऑफ़सेट स्थिति पुनर्गणना हो - और विंडो स्क्रॉल होने पर पुनर्गणना भी हो।

यह कोड विंडो को आकार देने वाली घटनाओं के लिए सुनता है और माउस ईवेंट हैंडलर में उपयोग किए जाने वाले ऑफ़सेट को पुन: संयोजित करता है:

// variables holding the current canvas offset position
//    relative to the window
var offsetX,offsetY;

// a function to recalculate the canvas offsets
function reOffset(){
    var BB=canvas.getBoundingClientRect();
    offsetX=BB.left;
    offsetY=BB.top;        
}

// listen for window resizing (and scrolling) events
//     and then recalculate the canvas offsets
window.onscroll=function(e){ reOffset(); }
window.onresize=function(e){ reOffset(); }

// example usage of the offsets in a mouse handler
function handleMouseUp(e){
    // use offsetX & offsetY to get the correct mouse position
    mouseX=parseInt(e.clientX-offsetX);
    mouseY=parseInt(e.clientY-offsetY);
    // ...
}

उत्तरदायी कैनवास घटनाओं के आकार के बिना एनिमेशन।

उपयोगकर्ता के इनपुट डिवाइस की गति के जवाब में विंडो आकार परिवर्तन ईवेंट आग लगा सकता है। जब आप एक कैनवास का आकार बदलते हैं तो यह स्वचालित रूप से साफ़ हो जाता है और आपको सामग्री को फिर से प्रस्तुत करने के लिए मजबूर किया जाता है। एनिमेशन के लिए आप यह requestAnimationFrame माध्यम से कहे जाने वाले मुख्य लूप फ़ंक्शन के माध्यम से हर फ्रेम करते हैं जो प्रदर्शन हार्डवेयर के साथ रेंडरिंग को बनाए रखने की पूरी कोशिश करता है।

रिसाइज़ इवेंट के साथ समस्या यह है कि जब माउस का उपयोग विंडो को आकार देने के लिए किया जाता है, तो घटनाओं को ब्राउज़र के मानक 60fps दर की तुलना में कई गुना तेज गति से ट्रिगर किया जा सकता है। जब रिसाइज़ ईवेंट से कैनवास बैक बफर बाहर निकलता है, तो उसे प्रदर्शन डिवाइस के साथ सिंक से बाहर DOM पर प्रस्तुत किया जाता है, जिससे बाल काटना और अन्य नकारात्मक प्रभाव हो सकते हैं। जीसी की कुछ समय बाद सफाई होने पर एनीमेशन की बहुत अधिक आवश्यकता और आवंटन भी जारी हो सकता है।


स्पष्ट आकार परिवर्तन घटना

आकार बदलने की घटना की उच्च फायरिंग दरों से निपटने का एक सामान्य तरीका है, आकार बदलने की घटना की आलोचना करना।

 // Assume canvas is in scope
 addEventListener.("resize", debouncedResize );

 // debounce timeout handle
 var debounceTimeoutHandle;

 // The debounce time in ms (1/1000th second)
 const DEBOUNCE_TIME = 100; 

 // Resize function 
 function debouncedResize () { 
     clearTimeout(debounceTimeoutHandle);  // Clears any pending debounce events

     // Schedule a canvas resize 
     debounceTimeoutHandle = setTimeout(resizeCanvas, DEBOUNCE_TIME);
 }

 // canvas resize function
 function resizeCanvas () { ... resize and redraw ... }

उपरोक्त उदाहरण कैनवास के आकार बदलने की घटना के बाद 100ms तक देरी करता है। यदि उस समय में आगे की घटनाओं का आकार बदल जाता है तो मौजूदा आकार परिवर्तन रद्द हो जाता है और एक नया शेड्यूल किया जाता है। यह प्रभावी रूप से अधिकांश आकार बदलने वाली घटनाओं का उपभोग करता है।

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

अधिक कोड समस्याओं को कम कर सकते हैं! अधिक कोड भी अपनी नई समस्याएं पैदा करता है।


सरल और सबसे अच्छा आकार

कैनवस के आकार को सुचारू रूप से जटिल करने के लिए, समस्या को अनदेखा करने के लिए (जो भी किसी को परवाह करता है)?

KISS कुछ सबसे प्रोग्रामर के बारे में पता होना चाहिए ((कश्मीर eep मैं टी एस imple एस tupid) बेवकूफ साल पहले। इसके बारे में सोचा नहीं होने के लिए मेरे पास संदर्भित करता है) है और यह पता चला है सबसे अच्छा समाधान सभी का सबसे सरल है।

बस मुख्य एनीमेशन लूप के भीतर से कैनवास का आकार बदलें। यह डिस्प्ले डिवाइस के साथ सिंक में रहता है, इसमें कोई अनावश्यक रेंडरिंग नहीं है, और पूर्ण फ्रेम दर को बनाए रखते हुए संसाधन प्रबंधन न्यूनतम संभव है। न ही आपको खिड़की या किसी अतिरिक्त आकार के कार्यों के लिए एक आकार बदलने की घटना को जोड़ने की आवश्यकता है।

आप उस आकार को जोड़ते हैं जहाँ आप सामान्य रूप से कैनवास की जाँच करके साफ करते हैं कि क्या कैनवास का आकार खिड़की के आकार से मेल खाता है। अगर इसका आकार नहीं बदल रहा है।

// Assumes canvas element is in scope as canvas

// Standard main loop function callback from requestAnimationFrame
function mainLoop(time) {

    // Check if the canvas size matches the window size
    if (canvas.width !== innerWidth || canvas.height !== innerHeight) {
        canvas.width = innerWidth;    // resize canvas
        canvas.height = innerHeight;  // also clears the canvas
    } else {
        ctx.clearRect(0, 0, canvas.width, canvas.height); // clear if not resized
    }

    // Animation code as normal.



    requestAnimationFrame(mainLoop);
}


Modified text is an extract of the original Stack Overflow Documentation
के तहत लाइसेंस प्राप्त है CC BY-SA 3.0
से संबद्ध नहीं है Stack Overflow