1class DZMProgressbar{ 2 static Scan(){ 3 let wrappers = document.querySelectorAll('[data-dzm-pb-wrapper]'); 4 //console.log('SCAN', wrappers); 5 wrappers.forEach(w=>{ 6 (new DZMProgressbar()).init(w); 7 }); 8 } 9 constructor(selector = false) { 10 11 this.markElements = []; 12 this.marks = []; 13 this.goalWrapper = false 14 this.barColor = '#A9A29D' 15 this.progressColor = '#BFD037' 16 this.fillColor = '#ffffff' 17 this.showInfoText = true 18 this.unitBefore = false 19 20 this.offset = 0; 21 this.state = 0; 22 this.goal = 0; 23 24 this.nextGoal = 0; 25 this.prevGoal = 0; 26 27 this.wrapper = false; 28 this.barWrapper = false; 29 this.progressbar = false; 30 this.mode = 'all'; // all|single|next 31 this.showSpecialMark = true; 32 this.markPoints = { 33 min:false, 34 prev:false, 35 next:false, 36 special:false, 37 max:false, 38 } 39 this.infoTextWrapper = false;
40 41 this.selectors = { 42 wrapper:selector === false ? '[data-dzm-pb-wrapper]' : selector, 43 barWrapper:'.dzm-pb', 44 goalWrapper:"[data-dzm-pb-goal]", 45 marker:'[data-dzm-pb-marker]', 46 markerValue:'data-dzm-pb-marker', 47 markerType:'data-dzm-pb-marker-type', 48 progressbar:'[data-dzm-pb-progress]', 49 progressbarValue:'data-dzm-pb-progress', 50 localStorageProgressState:'dzmProgressState'+(selector === false ? '.dzm-pb' : selector), 51 localStorageLastGoal:'dzmLastGoal'+(selector === false ? '.dzm-pb' : selector), 52 infoTextWrapper:'[data-dzm-pb-info-text]', 53 setting:'[data-dzm-pb-setting]', 54 settings:{ 55 mode:'dzmPbSettingsMode', 56 barColor:'dzmPbSettingsBarcolor', 57 progressColor:'dzmPbSettingsProgresscolor', 58 fillColor:'dzmPbSettingsFillcolor', 59 showSpecialMark:'dzmPbSettingsShowspecialmark', 60 showInfoText:'dzmPbSettingsShowinfotext', 61 unitBefore:'dzmPbSettingsUnitbefore', 62 strings:{ 63 outOf:'dzmPbSettingsStringsOutof', 64 unit:'dzmPbSettingsStringsUnit', 65 stateTextBefore:'dzmPbSettingsStringsStatetextbefore', 66 stateTextAfter:'dzmPbSettingsStringsStatetextafter', 67 } 68 69 } 70 } 71 72 this.settings={ 73 duration:1, 74 fps:60 75 } 76 77 this.strings = { 78 outOf:'von', 79 unit:'', 80 stateTextBefore:'', 81 stateTextAfter:'', 82 } 83 } 84 85 init(wrapper){ 86 //console.warn('INIT PROGRESSBAR',this.selectors.wrapper) 87 88 // GET COMPONENTS 89 this.wrapper = wrapper 90 if(!this.wrapper){ 91 console.log('no wrapper', this.selectors.wrapper) 92 return 93 } 94 95 // Eindeutiger Speicher-Key pro Bar. Frueher war der Key global ('dzmLastGoal.dzm-pb'), 96 // wodurch sich mehrere Bars und alte Warenkorbwerte gegenseitig ueberschrieben haben 97 // (Bar mal voll, mal leer, Flackern). Die Wrapper-ID (Portlet-UID bzw. statische ID) 98 // ist pro Bar stabil und eindeutig. 99 this.storageKey = 'dzmLastGoal_' + (this.wrapper.id || 'global'); 100 101 102 103 this.barWrapper = this.wrapper.querySelector(this.selectors.barWrapper) 104 // SET WIDTH FOR INITIAL OPEN LOADING EFFECT 105 this.barWrapper.style.width = '100%'; 106 // GET PROGRESSBAR COMPONENT AND MARKS 107 this.progressbar = this.wrapper.querySelector(this.selectors.progressbar) 108 this.markElements = this.wrapper.querySelectorAll(this.selectors.marker) 109 this.goalWrapper = this.wrapper.querySelector(this.selectors.goalWrapper) 110 111 112 113 // GET OPTIONS 114 let settings = this.wrapper.querySelector(this.selectors.setting); 115 this.mode = settings.dataset[this.selectors.settings.mode] || this.mode; 116 this.barColor = settings.dataset[this.selectors.settings.barColor] || this.barColor; 117 this.progressColor = settings.dataset[this.selectors.settings.progressColor] || this.progressColor; 118 this.fillColor = settings.dataset[this.selectors.settings.fillColor] || this.fillColor; 119 this.showSpecialMark = settings.dataset[this.selectors.settings.showSpecialMark] === 'true' || this.showSpecialMark; 120 this.showInfoText = settings.dataset[this.selectors.settings.showInfoText] === 'true' || this.showInfoText; 121 this.unitBefore = settings.dataset[this.selectors.settings.unitBefore] === 'true' || this.unitBefore; 122 this.strings.outOf = settings.dataset[this.selectors.settings.strings.outOf] || this.strings.outOf; 123 this.strings.unit = settings.dataset[this.selectors.settings.strings.unit] || this.strings.unit; 124 this.strings.stateTextBefore = settings.dataset[this.selectors.settings.strings.stateTextBefore] || this.strings.stateTextBefore; 125 this.strings.stateTextAfter = settings.dataset[this.selectors.settings.strings.stateTextAfter] || this.strings.stateTextAfter; 126 127 128 /*this.mode = options.mode || this.mode; 129 this.barColor = options.barColor || this.barColor; 130 this.progressColor = options.progressColor || this.progressColor; 131 this.fillColor = options.fillColor || this.fillColor; 132 this.showInfoText = 'showInfoText' in options ? options.showInfoText : this.showInfoText; 133 this.showSpecialMark = 'showSpecialMark' in options ? options.showSpecialMark : this.showSpecialMark;*/ 134 135 if(this.showInfoText){ 136 this.infoTextWrapper = this.wrapper.querySelector(this.selectors.infoTextWrapper) 137 } 138 139 /*this.strings = { 140 outOf:options.strings.outOf||this.strings.outOf, 141 unit:options.strings.unit||this.strings.unit, 142 stateTextBefore:options.strings.stateTextBefore||this.strings.stateTextBefore, 143 stateTextAfter:options.strings.stateTextAfter||this.strings.stateTextAfter, 144 }; 145 this.unitBefore = options.strings.unitBefore||this.unitBefore,*/ 146 147 // GET CURRENT TARGET VALUE BY ATTRIBUTE 148 this.goal = parseFloat(this.progressbar.getAttribute(this.selectors.progressbarValue)); 149 this.state = this.goal; 150 if((this.state = localStorage.getItem(this.storageKey)) === null){ 151 this.state =0 152 localStorage.setItem(this.storageKey, this.state); 153 154 155 }else{ 156 // DEACTIVATE ANIMATION, SO IT IS NOT ANIMATING ALL THE TIME 157 this.barWrapper.classList.toggle('dzm-pb--no-animation',true) 158 } 159 this.state = parseFloat(this.state) 160 161 162 163
164 this.markElements.forEach(marker=>{ 165 let markerValue = parseFloat(marker.getAttribute(this.selectors.markerValue)); 166 let markerType = marker.getAttribute(this.selectors.markerType); 167 let newMark = { 168 value:markerValue, 169 type: markerType, 170 mark:marker, 171 description:marker.dataset.dzmPbMarkerDescription 172 } 173 this.marks.push(newMark) 174 175 176 }) 177 178 179 this.marks.sort((a, b) => a.value - b.value); 180 181 this.setupMarkPoints(); 182 183 184 185 this.setMarks() 186 187 188 let statePercent = this.nextGoal > 0 189 ? (this.state - this.prevGoal) * 100 / (this.nextGoal - this.prevGoal === 0 ? 1 : this.nextGoal - this.prevGoal) 190 : 0; 191 this.progressbar.style.width =statePercent + '%'; 192 193 // VIEW THE PROGRESS BAR 194 this.barWrapper.style.opacity = '1'; 195 // ACTIVATE ANIMATIONS 196 setTimeout(()=>{ 197 this.barWrapper.classList.toggle('dzm-pb--no-animation',false) 198 },1) 199 200 window.progressBar = this 201 this.setProgress( this.goal) 202 } 203 setGoalString(){ 204 if(!this.goalWrapper && !this.infoTextWrapper) 205 return; 206 let set = false; 207 this.marks.forEach(mark=>{ 208 if((mark.value > this.goal || mark.isMax) && !set){ 209 if(this.goalWrapper){ 210 this.goalWrapper.innerText = Math.min(this.goal,this.marks[this.markPoints.max].value).toFixed(2) + ' '+this.strings.outOf+' ' +mark.value.toFixed(2) 211 } 212 if(this.showInfoText && mark.value-this.goal > 0){ 213 let infoText = ''; 214 infoText = this.strings.stateTextBefore+ ' '; 215 if(this.unitBefore){ 216 infoText += this.strings.unit + ' ' + (mark.value-this.goal).toFixed(2) + ' '; 217 }else{ 218 infoText += (mark.value-this.goal).toFixed(2) + ' ' + this.strings.unit + ' '; 219 } 220 infoText += mark.description + ' ' + this.strings.stateTextAfter; 221 222 this.infoTextWrapper.innerText = infoText; 223 }else{ 224 this.infoTextWrapper.innerText = ''; 225 226 } 227 set = true 228 } 229 230 }) 231 } 232 233 setProgress( target=0){ 234 235 // Kein gueltiges Ziel (z.B. einziger Marker mit Schwelle 0) -> Bar leer lassen statt 236 // durch die "=== 0 ? 1"-Division eine explodierende Breite zu erzeugen. 237 if(this.nextGoal <= 0){ 238 this.progressbar.style.width = '0%'; 239 return; 240 } 241 242 // CALC THE DIFF PERCENTAGE OF TARGET FROM SAVEDPROGRESS, BUT MAX 100% 243 244 let statePercent = (this.state - this.prevGoal) * 100 / (this.nextGoal - this.prevGoal === 0 ? 1 : this.nextGoal - this.prevGoal) 245 246 let targetPercent = ((Math.min(target,this.nextGoal) - this.prevGoal) * 100 / ((this.nextGoal - this.prevGoal === 0 ? 1 : this.nextGoal - this.prevGoal))) - statePercent; 247 248 249 250 251 let time = 0; 252 let interval = setInterval(()=>{ 253 time += 1 / this.settings.fps; 254 // Animation nach Ablauf der Dauer sauber beenden. Frueher wurde per Float-Gleichheit 255 // (currentProgress === targetPercent+statePercent) terminiert -> durch Rundungsfehler 256 // konnte das Intervall ueberschiessen oder gar nicht stoppen. 257 let finished = time >= this.settings.duration; 258 let progress = this.easeInOutQuad(time * 100 / this.settings.duration, time, 0, targetPercent, this.settings.duration); 259 let currentProgress = finished ? (statePercent + targetPercent) : (statePercent + progress); 260 261 this.progressbar.style.width =currentProgress + '%'; 262 this.marks.forEach(mark=>{ 263 let markPercentValue = (mark.value-this.prevGoal) * 100 / (this.nextGoal-this.prevGoal); 264 265 this.toggleDone(mark.mark,markPercentValue <= currentProgress) 266 }) 267 268 if (finished) { 269 270 clearInterval(interval); 271 this.state = Math.min(target,this.nextGoal) 272 localStorage.setItem(this.storageKey, this.state); 273 274 275 276 if(this.mode !== 'all' && ( 277 (this.markPoints.next !== false && this.markPoints.next !== this.markPoints.max ) 278 || (this.markPoints.prev !== false && target <= this.marks[this.markPoints.prev].value))){ 279 this.checkNextGoales(currentProgress, target) 280 } 281 } 282 }, 1000 / this.settings.fps); 283 284 285 } 286 287 toggleDone(mark,on = true){ 288 mark.classList.toggle('done', on) 289 if(on){ 290 mark.firstElementChild.style.backgroundColor = this.progressColor; 291 }else{ 292 mark.firstElementChild.style.backgroundColor = this.barColor; 293 } 294 } 295 296 checkNextGoales(currentProgress,target){ 297 298 299 let lastNextGoal = this.nextGoal; 300 let lastPrevGoal = this.prevGoal; 301 302 303 this.setupMarkPoints() 304 this.setMarks() 305 306 if(lastNextGoal === this.nextGoal && lastPrevGoal === this.prevGoal) 307 return; 308 let statePercent = (this.state - this.prevGoal) * 100 / (this.nextGoal - this.prevGoal === 0 ? 1 : this.nextGoal - this.prevGoal) 309 this.progressbar.style.width =statePercent + '%'; 310 311 312 313 this.setProgress(target) 314 315 316 317 } 318 319 setupMarkPoints(){ 320 this.marks.forEach(mark=>{ 321 mark.isMin = false;
322 mark.isMax = false; 323 mark.isPrev = false; 324 mark.isSpecial = false; 325 mark.isNext = false; 326 this.markPoints.min = false; 327 this.markPoints.max = false; 328 this.markPoints.prev = false; 329 this.markPoints.next = false; 330 this.markPoints.special = false; 331 }) 332 this.marks.forEach((mark,i)=>{ 333 if(i===0){ 334 this.markPoints.min = i; 335 mark.isMin = true; 336 } 337 if(i === this.marks.length - 1){ 338 this.markPoints.max = i; 339 mark.isMax = true; 340 } 341 342 if(mark.type === 'special'){ 343 this.markPoints.special = i; 344 mark.isSpecial = true; 345 } 346 347 if(mark.value <= this.state && !mark.isMax){ 348 this.markPoints.prev = i; 349 mark.isPrev = true; 350 if(i>0){ 351 this.marks[i-1].isPrev = false 352 } 353 } 354 355 if(mark.value > this.state && this.markPoints.next === false){ 356 this.markPoints.next = i; 357 mark.isNext = true; 358 } 359 }) 360 361 if(this.mode === 'all'){ 362 this.nextGoal = this.marks[this.markPoints.max].value 363 this.prevGoal = 0; 364 }else if(this.mode === 'next'){ 365 if(this.markPoints.next !== false){ 366 if(this.showSpecialMark && ((this.markPoints.special !== false && this.marks[this.markPoints.special].value > this.marks[this.markPoints.next].value) 367 368 )){ 369 this.nextGoal = this.marks[this.markPoints.special].value; 370 }else{ 371 this.nextGoal = this.marks[this.markPoints.next].value; 372 } 373 }else{ 374 this.nextGoal = this.marks[this.markPoints.max].value; 375 } 376 377 this.prevGoal = 0; 378 }else if(this.mode ==='single'){ 379 if(this.markPoints.next !== false){ 380 if(this.showSpecialMark && this.markPoints.special !== false && this.marks[this.markPoints.special].value > this.marks[this.markPoints.next].value){ 381 this.nextGoal = this.marks[this.markPoints.special].value; 382 }else{ 383 this.nextGoal = this.marks[this.markPoints.next].value; 384 } 385 }else{ 386 this.nextGoal = this.marks[this.markPoints.max].value; 387 } 388 if(this.markPoints.prev !== false){ 389 this.prevGoal = this.marks[this.markPoints.prev].value; 390 }else{ 391 this.prevGoal = 0; 392 } 393 394 } 395 396 397 398 } 399 400 setMarks(){ 401 402 this.marks.forEach((mark,i)=>{ 403 let position = 0; 404 mark.mark.style.zIndex = 'unset'; 405 switch (this.mode){ 406 case 'all': 407 position = mark.value * 100 / this.nextGoal 408 mark.mark.style.left = position + '%'; 409 this.toggleDone(mark.mark,mark.value <= this.state) 410 break; 411 case 'next': 412 position = mark.value * 100 / this.nextGoal 413 414 console.log(mark); 415 mark.mark.style.left = position + '%'; 416 this.toggleDone(mark.mark,mark.value <= this.state) 417 if(mark.value > this.state){ 418 if (mark.isNext || (this.showSpecialMark && mark.isSpecial) || (this.showSpecialMark && mark.value <= this.marks[this.markPoints.special].value)) { 419 420 421 }else{ 422 mark.mark.style.zIndex = '-1'; 423 } 424 } 425 426 break; 427 case 'single': 428 if(mark.isMax){ 429 position = 100; 430 }else{ 431 432 position = Math.max(0,(mark.value - this.prevGoal) * 100 / (this.nextGoal - this.prevGoal)) 433 } 434 435 mark.mark.style.left = position + '%'; 436 this.toggleDone(mark.mark,mark.value <= this.state) 437 if(mark.value > this.state){ 438 if (mark.isNext || (this.showSpecialMark && mark.isSpecial) || (this.showSpecialMark && mark.value <= this.marks[this.markPoints.special].value)) { 439 440 441 }else{ 442 mark.mark.style.zIndex = '-1'; 443 } 444 } 445 446 447 } 448 449 }) 450 451 this.setGoalString() 452 453 } 454 455 easeInOutQuad(x, t, b, c, d) { 456 if ((t /= d / 2) < 1) { 457 return c / 2 * Math.pow(t, 4) + b; 458 } else { 459 let adjustedT = t - 2; 460 return -c / 2 * (Math.pow(adjustedT, 4) - 2) + b; 461 } 462 } 463 464 465 466} 467 468dzm.dispatcher.listen([ 469 dzm.events.DOM.contentLoaded, 470 dzm.events.quickbuy.addedToCart, 471 dzm.events.sidebar.cartLoaded, 472],()=>{ 473 DZMProgressbar.Scan(); 474}) 475
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.