2017-03-08 10 views
10

नोट: मैं शब्द पृष्ठभूमि साथ ओवरले दूसरे के स्थान पर प्रयोग करेंगे।जावास्क्रिप्ट गणित "आकर्षित" कई अन्य आयतों के आसपास आयतों पृष्ठभूमि प्रभाव को प्राप्त करने

मैं वर्तमान में एक गाइड मोड पर काम कर रहा हूं और मैं उन्हें अंधेरे अर्द्ध पारदर्शी पृष्ठभूमि से बाहर खड़े करने के लिए तत्वों को हाइलाइट करता हूं।

तो मूल रूप से, मेरे पास उस तत्व के लिए चयनकर्ता है जिसे मैं ओवरलैड नहीं करना चाहता हूं, और फिर मैं इसे अर्द्ध पारदर्शी अंधेरे divs के साथ घेरता हूं, एक बहिष्कृत तत्व के साथ ओवरले को अनुकरण करता हूं।

मेरा समाधान एक हाइलाइट किए गए तत्व के लिए बहुत अच्छा काम करता है, लेकिन जब यह संख्या 2+ हो जाती है, तो गणना करना मुश्किल हो जाता है कि उन तत्वों के चारों ओर काले divs को कैसे रखा जाए। और बात यह है कि: पृष्ठ से पृष्ठ पर हाइलाइट की ज़रूरतें काफी भिन्न होंगी - ऐसा नहीं है कि वे एकाधिक तत्व स्थिर होंगे।

तो मेरी मुद्दे को वर्णन करने के:

enter image description here

यहाँ आप अलग अलग बक्से आदेश अर्द्ध पारदर्शी अंधेरे divs साथ Box2 और Box2 चारों ओर में पेज में डाल करने की आवश्यकता है देख सकते हैं, मूल रूप से हाइलाइट किए गए तत्वों के साथ ओवरले प्रभाव को अनुकरण करना। इस तरह के एक मामले के लिए, मैं हार्डकोड गणना कर सकता हूं और सबकुछ ठीक होगा, लेकिन क्या होगा यदि बॉक्स 1 बॉक्स 2 से अधिक था? तो क्या होगा यदि वे एक-दूसरे को क्षैतिज रूप से ओवरलैप नहीं कर रहे थे? क्या होगा यदि कोई बॉक्स 3 है जिसे हाइलाइट करने की आवश्यकता है?

किसी भी मामले में, मुझे नहीं पता कि कितने अंधेरे बक्से हैं और उन्हें कहां रखा जाए।

क्या कोई गणितीय सूत्र है जो इस मामले में मेरी सहायता करेगा? JQuery का उपयोग भी संभव है क्योंकि यह मेरी परियोजना में शामिल है।

मैं इस समस्या से कैसे संपर्क करूंगा और इसे विस्तारित कर सकता हूं (एकाधिक बक्से, अलग-अलग पदों)?

+1

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

+1

हे के लिए https://en.wikipedia.org/wiki/Constructive_solid_geometry भी देखें! मैंने एक कामकाजी समाधान प्रस्तुत किया, क्या आप इसे देख सकते हैं? –

+0

जो आप वास्तव में खोज रहे हैं उसे _Region_ डेटा प्रकार कहा जाता है। क्षेत्र 2-डी स्पेस के आयताकार-बाध्य हिस्सों पर यूनियन/चौराहे/घटाव करते हैं, और डिज़ाइन किए गए हैं ताकि आप उन्हें आयताकारों से आसानी से बना सकें और उनसे आयताकारों को रद्द कर सकें। मैंने पहले ऐसा करने के लिए सी में कोड लिखा है, और यह सामान्य मामले में जटिल है। अधिकांश जीयूआई में मूल रूप से एक क्षेत्र प्रकार (विंडोज़, एक्स, और मैक सभी शामिल हैं) शामिल हैं और अधिकांश प्रतिपादन के लिए इसका उपयोग करते हैं, लेकिन ऐसा लगता है कि एक जावास्क्रिप्ट कार्यान्वयन नहीं है जो मुझे मिल सकता है: हैरानी की बात है कि कोई एनपीएम पैकेज उपलब्ध नहीं है यह करने के लिए। –

उत्तर

9

आप अतिसंवेदनशील हैं! जो आप खोज रहे हैं वह एक निश्चित HTML और CSS लेआउट के साथ प्राप्त किया जा सकता है।

.container 
    .overlay 
    .box 
    .box 
    .box 
    .box 

चाल एक पूर्ण-चौड़ाई, अर्द्ध पारदर्शी ओवरले का उपयोग करें और तत्वों सामने से प्रकाश डाला करने की आवश्यकता है लाना है:

आप एक लेआउट इस के समान उपयोग करना होगा। ओवरले में pointer-events: none असाइन करना बहुत महत्वपूर्ण बात है ताकि आप इसके माध्यम से क्लिक कर सकें!

बनाओ .box की, कहते हैं, 1 और .overlay100 के z-index मूल्य एक z-index मूल्य की है। एक निश्चित .box को हाइलाइट करने के लिए, अपने z-index से 101 पर सेट करें। इस तरह यह हाइलाइट दिखाई देगा।

मैं मोबाइल पर अभी हूँ, लेकिन मैं Codepen पर एक बुनियादी सबूत अवधारणा-का-डाल दिया। उन्हें हाइलाइट करने के लिए बॉक्स पर क्लिक करें, पूर्ववत करने के लिए फिर से क्लिक करें। कई बक्से के साथ काम करता है!

+0

यह अच्छी तरह से काम करता है! हालांकि, "उस लड़के" होने के बावजूद, आपके न्यूनतम समर्थित लक्ष्य के आधार पर, ध्यान रखें कि आईई 10 और नीचे 'पॉइंटर-इवेंट' संपत्ति का समर्थन नहीं करते हैं। –

+0

@ जोनाथन बॉमैन प्रतिक्रिया के लिए धन्यवाद! मुझे इसके बारे में पता है और आईई-विशिष्ट हैक शामिल है जिसमें '\ 9' iirc शामिल है। ओपी ने ब्राउज़र समर्थन के बारे में कुछ भी नहीं कहा है, इसलिए मुझे लगता है कि यह कोई समस्या नहीं है। असल में, ओपी ने ** ** कुछ भी नहीं कहा है, शायद वह बक्षीस नहीं देना चाहता: डी –

+0

हाहा, अच्छी तरह से उम्मीद है कि यह मामला नहीं है :) मुझे जांच करनी होगी यह हैक, क्योंकि पॉइंटर-इवेंट वास्तव में उपयोगी है लेकिन मुझे कुछ कंपनियों (जैसे मैं काम करता हूं) जानता हूं, अभी भी आईई 9 पर ग्राहकों के बारे में चिंता करने के लिए ग्राहक हैं। और हाँ, आप बिल्कुल सही हैं, उन्होंने क्लाइंट सपोर्ट का जिक्र नहीं किया है, मुझे पता है कि कभी-कभी आप इस तरह की चीज़ों से काटते हैं, इसलिए मैं इसमें शामिल होना चाहता था। हालांकि कामकाज पर टिप के लिए धन्यवाद, मैं इसे देख लूंगा! –

1

आप इसे छाया का उपयोग करके आसानी से हल कर सकते हैं।

उसके बाद, आप केवल क्षेत्र के लिए 2 भागों

body, html { 
 
    height: 100%; 
 
} 
 

 
body { 
 
    background-image: linear-gradient(45deg, yellow, tomato); 
 
} 
 
.mask { 
 
    overflow: hidden; 
 
    width: 50%; 
 
    height: 100%; 
 
    display: inline-block; 
 
    position: relative; 
 
} 
 

 
#mask1 { 
 
    left: 0px; 
 
} 
 

 
#mask2 { 
 
    right: 0px; 
 
} 
 

 
.hole { 
 
    width: 150px; 
 
    height: 90px; 
 
    position: absolute; 
 
    box-shadow: 0px 0px 0px 2000px rgba(0,0,0,0.5); 
 
} 
 

 
#mask1 .hole { 
 
    left: 40px; 
 
    top: 40px; 
 
} 
 

 
#mask2 .hole { 
 
    left: 140px; 
 
    top: 20px; 
 
}
<div class="mask" id="mask1"> 
 
    <div class="hole"></div> 
 
</div><div class="mask" id="mask2"> 
 
    <div class="hole"></div> 
 
</div>

1

में स्क्रीन की जरूरत क्षेत्र

का उपयोग करते हुए एक ओर जहां अच्छा जवाब के एक नंबर यहाँ हैं पर विचार करें, और आप शायद @WearyAdventurer जैसे तत्वों को स्थानांतरित करने पर विचार करना चाहें, अन्य उत्तरों में से कोई भी वास्तव में मूल प्रश्न को संबोधित नहीं करता है:

मैं इस तरह से तत्व कैसे बना सकता हूं कि वे अन्य तत्वों के चारों ओर घूमते हैं?

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

या जब तक मैं इसे करने के लिए लाइब्रेरी नहीं लिखता तब तक वे अनुपस्थित थे।

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


बेसिक आइडिया

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

var screenRegion = new Region([0, 0, viewportWidth, viewportHeight]); 
var elemRegion1 = new Region(element1); 
var elemRegion2 = new Region(element2); 
var coverRegion = screenRegion.subtract(elemRegion1).subtract(elemRegion2); 
var coverRectangles = coverRegion.getRects(); 

आयतों की जिसके परिणामस्वरूप सरणी है, तो आप सिर्फ साधारण वस्तुओं है कि x/y/width/height/top/left/right/bottom निर्देशांक हैं प्रत्येक से <div> तत्व बनाएं, और आप कर चुके हैं।

// Generate regions for each of the objects. 
 
var containerRegion = new Region2D($(".container")[0]); 
 
var target1Region = new Region2D($(".target1")[0]); 
 
var target2Region = new Region2D($(".target2")[0]); 
 

 
// Subtract the targets from the container, and make an array of rectangles from it. 
 
var coverRegion = containerRegion.subtract(target1Region).subtract(target2Region); 
 
var coverRects = coverRegion.getRects(); 
 

 
// Create gray <div> elements for each rectangle. 
 
for (var i = 0, l = coverRects.length; i < l; i++) { 
 
    var coverRect = coverRects[i]; 
 
    var coverElement = $("<div class='cover'>"); 
 
    coverElement.css({ 
 
     left: (coverRect.x - 1) + "px", top: (coverRect.y - 1) + "px", 
 
     width: coverRect.width + "px", height: coverRect.height + "px" 
 
    }); 
 
    coverElement.appendTo($(".container")); 
 
}
.container, .target1, .target2, .cover { position: absolute; top: 0; left: 0; box-sizing: border-box; } 
 
.target1, .target2 { border: 1px solid red; } 
 
.container { width: 330px; height: 230px; border: 1px solid blue; } 
 
.target1 { top: 40px; left: 40px; width: 100px; height: 80px; } 
 
.target2 { top: 100px; left: 180px; width: 100px; height: 80px; } 
 
.cover { background: rgba(0, 0, 0, 0.5); border: 1px solid #000; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://unpkg.com/[email protected]/plain/region2d.min.js"></script> 
 

 
<div class="container"> 
 
    <div class="target1"></div> 
 
    <div class="target2"></div> 
 
</div>
:


कार्यान्वयन कार्य तो यहाँ वास्तविक समस्या, प्रस्तुत के रूप में मेरे Region2D लाइब्रेरी का उपयोग कर भारी एल्गोरिथम उठाने करने के लिए के लिए एक समाधान की एक काम कार्यान्वयन है

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