1const template = document.createElement("template"); 2template.innerHTML = ` 3 4<div class="appShowcaseApp"> 5<h2 class="largeHidden" id="runnyLarge"> 6 7</h2> 8 9<p class="descSlot"> 10<slot name="desc"></slot> 11</p> 12 13<div id="flexa"> 14 15<img src="images/runny-orig.png" class="app-imga" /> 16<h2 class="titles"></h2> 17</div> 18 19<div class="add"></div> 20 21<div class="oneMoreOverlay modernSection"> 22 23 24 <div class="blobImage blobImageRunny"></div> 25 26<div id="runnyOverlay"> 27 28 29 30<div id="runnysa" class="leftIcon leftIconRunny"> 31 <div class="sidesImages"> 32 <img src="images/runny-orig.png" class="app-img" /> 33 </div> 34 35 <div class="leftAppWrapper"> 36 37 <h2 class="stroked runnyStroked"><slot></slot></h2> 38 <p class="appDesc"> 39 </p> 40 41 <div class="stores"> 42 43 </div> 44 </div> 45</div> 46</div> 47 48<!---Make green gradient blob instead of an image and change its shape on scroll---> 49 50 51 52</div> 53 54 55 56 57</div> 58 59 60<style> 61.titles, .desc, .app-imga, .appstore { 62opacity: 1; 63transform: translateY(100px); 64} 65 66.titles { 67margin-bottom: 3rem; 68letter-spacing: .4rem; 69font-family: Bebas Neue, Roboto Condensed, Arial; 70text-transform: uppercase; 71} 72 73 74.app-imga { 75margin-left: 2rem; 76opacity: 0; 77} 78 79.appstore { 80width: 200px; 81} 82 83.desc { 84color: black; 85padding-bottom: 3rem; 86font-size: 1.6rem; 87} 88 89#runnyOverlay, .blobImage { 90opacity: 0; 91transform: translateY(100px); 92} 93 94.titles { 95font-size: 6rem; 96margin-left: 2rem; 97 98} 99 100 101@media (max-width: 70rem){ 102.titles { 103 font-size: 3rem; 104} 105} 106 107 108* { 109margin: 0; 110} 111 112.appShowCaseApp { 113height: 800px; 114} 115 116#flexa { 117display: flex; 118flex-direction: row; 119 120align-items: center; 121 122} 123 124#flexa img { 125width: 130px; 126height: 100% 127 128} 129 130h2 { 131color: transparent; 132font-family: Arial; 133font-size: 7rem; 134} 135 136.blobImage { 137max-width: 70%; /*was 700px*/ 138height: 600px; 139border-radius: 43% 56% 72% 28% / 42% 42% 56% 48%; 140} 141 142.app-img, .app-imga { 143width: 250px; 144border-radius: 30px; 145opacity: 0; 146} 147 148.app-img { 149display: none; 150} 151/* 152.app-img, .blobImage { 153position: absolute; 154}*/ 155 156 157 158 .cover > img { 159 border-radius: 1rem; 160 } 161 162 .cover { 163 overflow-x: scroll; 164 display: flex; 165 166 justify-content: flex-start; 167 width: 90%; 168 margin-left: auto; 169 margin-right: auto; 170 height: 700px; 171 grid-area: 1 / 1; 172 z-index: 1; 173 margin-top: 14rem; 174 175 } 176 177 .cover::-webkit-scrollbar {
178 display: none; /* Chrome, Safari, Webkit-based browsers */ 179} 180 181 .stroked { 182 z-index: 1; 183 /* Add more styles if necessary */ 184 } 185 186 .screenshot { 187 max-width: 460px; 188 margin: 10px; 189 } 190 191 .desc { 192 font-family: Arial; 193 color: gray; 194 } 195 196 197 198 199@media (max-device-width: 430px) { 200 201 #flexa { 202 flex-direction: column; 203 } 204 205 #flexa img { 206 margin-top: 6rem; 207 } 208 209 210} 211 212</style> 213 214<script> 215alert("a"); 216</script> 217`; 218 219 220class ScrollDrivenArrayInterpolator { 221 constructor(startArray, endArray, scrollStart, scrollEnd) { 222 if (startArray.length !== endArray.length) { 223 throw new Error("Arrays must be of the same length."); 224 } 225 this.startArray = startArray; 226 this.endArray = endArray; 227 this.scrollStart = scrollStart; // Scroll position at which interpolation starts 228 this.scrollEnd = scrollEnd; // Scroll position at which interpolation ends 229 } 230 231 interpolateByScroll(scrollY) { 232 // Clamp scrollY to be within the scroll range 233 const clampedScrollY = Math.min(Math.max(scrollY, this.scrollStart), this.scrollEnd); 234 235 // Normalize scrollY between 0 and 1 236 const t = (clampedScrollY - this.scrollStart) / (this.scrollEnd - this.scrollStart); 237 238 return this.startArray.map((startValue, i) => { 239 const endValue = this.endArray[i]; 240 return startValue + (endValue - startValue) * t; 241 }); 242 } 243} 244 245 246class AppShowcase extends HTMLElement { 247 constructor(){ 248 super(); 249 const shadow = this.attachShadow({mode: "open"}) 250 shadow.append(template.content.cloneNode(true)); 251 this.img = this.shadowRoot.querySelector(".app-img"); 252 this.appimga = this.shadowRoot.querySelector(".app-imga"); 253 this.blobImg = this.shadowRoot.querySelector(".blobImage"); 254 this.cover = this.shadowRoot.querySelector(".cover"); 255 this.titles = this.shadowRoot.querySelector(".titles"); 256 this.appstore = this.shadowRoot.querySelector(".appstore"); 257 this.runnyOverlay = this.shadowRoot.querySelector("#runnyOverlay"); 258 this.desc = this.shadowRoot.querySelector(".desc"); 259 this.imageRange = {min: 0, max: 1500}; 260 this.handleScroll(); 261 262 263 this.runnyOverlay.animate([ 264 { opacity: 1, transform: "translateY(0)" } // Adjust translation 265 ], { 266 duration: 1000, // Duration of the animation in milliseconds 267 fill: 'forwards' // Retain the last keyframe after animation 268 }); 269 270 this.blobImg.animate([ 271 { opacity: 1, transform: "translateY(0)" } // Adjust translation 272 ], { 273 duration: 1000, // Duration of the animation in milliseconds 274 fill: 'forwards' // Retain the last keyframe after animation 275 }); 276 } 277 278 static get observedAttributes() { return ['greeting-name', "app-title", "app-desc", "app-img", "app-background", "app-anim-range", "fire-at-range", "app-minus-constant"]; } 279 attributeChangedCallback(attr, oldVal, newVal) { 280 if (oldVal === newVal) return; // nothing to do 281 switch (attr) { 282 case 'greeting-name': 283 this.p.textContent = `${newVal || 'world'}!`; 284 break; 285 286 case 'app-title': 287 this.er = newVal; 288 console.log(`oValue is ${newVal}`); 289 290 291 if (this.er === "SPATIAL-NETWORK"){ 292 console.log("IOHO"); 293 console.log("OH HELLO"); 294 // alert("Hello") 295 // this.shadowRoot.querySelector(".cover").style.height = "2000px"; 296 // this.shadowRoot.querySelector('.titles').style.fontSize = "8rem"; 297 } else { 298 // this.shadowRoot.querySelector('.titles').style.fontSize = "8rem"; 299 } 300 301 console.log("START IS "); 302 console.log(newVal); 303 // CHANGE THE IMAGE RANGE HERE FROM ATTR 304 305 306 307 let letters = ["A", "B", "C", "D", "E", "G", "H", "I", "N", "O", "P", "Q", "R", "S", "T", "U", "V"]; 308 309 let h1 = document.createElement("h3"); 310 h1.style.textAlign = "center"; 311 312 this.er.split("").map((l, i) => { 313 let gen = document.createElement("span"); 314 gen.textContent = l; 315 gen.setAttribute("id", letters[i]) 316 h1.appendChild(gen); 317 318 if (this.er === "SPATIAL-NETWORK" && l === "L"){ 319 let wbr = document.createElement("br"); 320 h1.appendChild(wbr); 321 console.log("LAPPO") 322 } 323 324 if (this.er === "SPATIAL-GRAVITY" && l === "L"){ 325 let wbr = document.createElement("br"); 326 h1.appendChild(wbr); 327 console.log("LAPPO") 328 } 329 }); 330 331 332 333 this.shadowRoot.querySelector('.titles').appendChild(h1);
334 // this.title.textContent = `${newVal || 'world'}!`; 335 break; 336 337 case 'app-desc': 338 // this.shadowRoot.querySelector('.desc').textContent = newVal; 339 340 case 'app-img': 341 console.log(`aValue is ${newVal}`); 342 this.shadowRoot.querySelector('.app-img').src = newVal; 343 this.shadowRoot.querySelector('.app-imga').src = newVal; 344 // this.title.textContent = `${newVal || 'world'}!`; 345 break; 346 347 348 case 'app-limit': 349 console.log(`Value is ${newVal}`); 350 this.globalLimit = newVal; 351 //this.handleScroll(newVal) 352 // this.title.textContent = `${newVal || 'world'}!`; 353 break; 354 355 case 'fire-at-range': 356 console.warn(`Anim start is ${newVal}`); 357 let mina = Number(newVal.split("-")[0]); 358 let maxa = Number(newVal.split("-")[1]); 359 360 const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); 361 const isEdge = navigator.userAgent.includes("Edg"); 362 363 if (isSafari){ 364 365 mina = mina * .85; 366 // max = max * 1.25; 367 } 368 369 if (isEdge){ 370 mina = mina * 0.85; 371 } 372 373 if (window.matchMedia("(max-width: 430px)").matches){ 374 mina = mina * .82; // 1.25 375 //alert("//") 376 } 377 378 this.fireAtRange = {from: mina, to: maxa}; 379 break; 380 381 case 'app-anim-range': 382 console.warn(`Anim start is ${newVal}`); 383 let min = Number(newVal.split("-")[0]); 384 let max = Number(newVal.split("-")[1]); 385 386 387 388 this.imageRange = {min: min, max: max}; 389 // console.log(rangeObj); 390 // this.globalLimit = newVal; 391 //this.handleScroll(newVal) 392 // this.title.textContent = `${newVal || 'world'}!`; 393 break; 394 395 case 'app-background': 396 console.log(`aValue is ${newVal}`); 397 // this.shadowRoot.querySelector('.titles').style.opacity = 0.6; 398 this.shadowRoot.querySelector('.blobImage').style.backgroundImage = `url("${newVal}")`; 399 this.shadowRoot.querySelector('.blobImage').style.backgroundSize = "900px"; 400 this.shadowRoot.querySelector('.blobImage').style.backgroundRepeat = "no-repeat"; 401 // .background = //"radial-gradient(#2ecc71, #1abc9c)"; 402 //.backgroundImage = `url("https://res.cloudinary.com/simpleview/image/upload/v1579299474/clients/catalinaislandccvb/Untitled_Panorama1_be5bf235-9ac1-4ed9-9ba1-622fcf38611a.jpg")`; 403 404 // this.title.textContent = `${newVal || 'world'}!`; 405 break; 406 407 408 case 'app-minus-constant': 409 console.log(`aValue is ${newVal}`); 410 411 412 this.appMinusConstant = Number(newVal); 413 // this.shadowRoot.querySelector('.titles').style.opacity = 0.6; 414 //this.shadowRoot.querySelector('.blobImage').style.background = "radial-gradient(#2ecc71, #1abc9c)"; 415 //.backgroundImage = `url("https://res.cloudinary.com/simpleview/image/upload/v1579299474/clients/catalinaislandccvb/Untitled_Panorama1_be5bf235-9ac1-4ed9-9ba1-622fcf38611a.jpg")`; 416 417 // this.title.textContent = `${newVal || 'world'}!`; 418 break; 419 } 420 } 421 422 423 connectedCallback() { 424 // Listen for the scroll event and expand the image if scrollY > 600 425 window.addEventListener('scroll', this.handleScroll.bind(this)); 426 } 427 428 disconnectedCallback() { 429 // Clean up the event listener when the element is removed from the DOM 430 window.removeEventListener('scroll', this.handleScroll.bind(this)); 431 } 432 433 434 mapRange(value, inMin, inMax, outMin, outMax) { 435 value = Math.max(inMin, Math.min(value, inMax));
436 return ((value - inMin) * (outMax - outMin)) / (inMax - inMin) + outMin; 437 } 438 439 handleScroll() { 440 let progress = this.mapRange(window.scrollY, 0, 150, 0, 100); 441 console.warn("PROG:" + progress); 442 // this.appimga.style.opacity = 1; 443 // this.desc.style.opacity = progress / 100; 444 445 let el = this.shadowRoot.querySelector(`#A`); 446 447 if (el != null){ 448 449 450 // el.style.transform = `scale(0)`; 451 452 453 const letters = ["A", "B", "C", "D", "E", "G", "H", "I", "N", "O", "P", "Q", "R", "S", "T", "U", "V"]; 454 455 let word = this.er; 456 457 458 for (var i = 0; i < word.length; i++) { 459 460 /* // Define a delay for each letter based on its index 461 let delay = i * 0.1; // Adjust delay as needed (0.1 works well) 462 let progress = this.mapRange(window.scrollY, 0, 150, 0, 1); // Normalized progress (0 to 1) 463 464 // Only start scaling each letter after its delay 465 let adjustedProgress = Math.max(0, (progress - delay) / (1 - delay)); // Adjust for the delay, rescaling to 0-1 range 466 467 // Map scale from 0.3 to 1 as adjustedProgress goes from 0 to 1 468 let scale = this.mapRange(adjustedProgress, 0, 1, 0, 1); 469 470 // Ensure that scale doesn't exceed 1 471 scale = Math.min(scale, 1);*/ 472 473 474 let fireAt = this.fireAtRange; 475 476 if (this.fireAtRange === undefined){ 477 return; 478 } 479 480 if (this.er === "SPATIAL-NETWORK") { 481 this.shadowRoot.querySelector("#I").style.color = "transparent"; 482 } 483 484 // 05/11/25 235651 485 if (this.er === "SPATIAL-GRAVITY") { // is ok 486 this.shadowRoot.querySelector("#I").style.display = "none" //color = "transparent"; 487 } 488 489 490 if (this.er === "RUNNY"){ 491 console.log("For runnya"); 492 console.warn(fireAt); 493 494 } 495 496 497let maxDelay = 0.5; // Maximum delay (in seconds) 498let wordLength = word.length; 499let adjustedMaxDelay = Math.min(maxDelay, 1 / wordLength); // Scale delay based on word length 500 501 // Adjust the delay for each letter 502 let delay = i * adjustedMaxDelay; 503 504 let progress = this.mapRange(window.scrollY, fireAt.from, fireAt.from + 400, 0, 1); // Normalized progress (0 to 1) 505 506 // Adjust for delay, rescaling to 0-1 range 507 let adjustedProgress = Math.max(0, (progress - delay) / (1 - delay)); 508 509 // Scale and rotation transformations 510 let scale = this.mapRange(adjustedProgress, 0, 1, 0, 1); 511 let rotationAngle = this.mapRange(adjustedProgress, 0, 1, 200, 360); 512 513 rotationAngle = Math.max(rotationAngle, 270); 514 515 // not applied to all letters in Spatial Network 516 let el = this.shadowRoot.querySelector(`#${letters[i]}`); 517 if (rotationAngle > 0){ 518 // alert(this.er); 519 520 if (this.er === "SPATIAL-NETWORK"){ 521 el.style.color = "#1abc9c"; 522 } if (this.er === "RELAYS"){ 523 el.style.color = "#3498db"; 524 } else if (this.er === "EVENY"){ 525 el.style.color = "#4EABE8"; 526 } else if (this.er === "RUNNY") { 527 el.style.color = "#1abc9c"; 528 } else if (this.er === "SPATIAL-GRAVITY") { 529 el.style.color = "#daa025ff"; 530 } 531 532 // el.style.color = "white"; 533 534 // el.style.color = "black"; 535 } else { 536 el.style.color = "transparent"; 537 } 538 539 540 541/* 542 543 let scaledScale = scale; 544 //alert(this.er); 545 if (this.er === "SPATIAL-NETWORK"){ 546 if (Math.abs(scale) > 0.8){ 547 scaledScale = 0.8; 548 } 549 } else { 550 scaledScale = Math.abs(scale); 551 } 552 if (this.er === "SPATIAL-NETWORK"){ 553 console.log("SCA" + scaledScale); 554 // alert(scaledScale); 555 }*/ 556 557 558 559 this.appimga.style.opacity = 1; 560 //el.style.textShadow = "3px 3px 10px #808080"; 561 el.style.transform = `scale(0)`; 562 el.style.display = `inline-block`; 563 el.style.transform = `rotate3D(1, 0, 0, ${rotationAngle}deg)`; 564 this.appimga.style.transform = `rotate3D(1, 0, 0, ${rotationAngle}deg) scale(${Math.abs(scale)})`; 565 // el.style.transform = `scale(${Math.abs(scale)})`; 566 } 567 } 568 569 570 571 572 573 if (window.scrollY > 0) { 574 575 // Example range (custom scroll range) 576 const scrollRange = { from: this.imageRange.min, to: /*this.imageRange.max*/ this.imageRange.min + 600 }; // Define the custom range 577 const scrollPositionA = Math.max(0, Math.min(window.scrollY, scrollRange.to)); // Clamp between from and to 578 579 // Normalize scroll position within the range [0, 1] 580 const t = (scrollPositionA - scrollRange.from) / (scrollRange.to - scrollRange.from); 581 582 const startBorderRadius = [42, 56, 72, 28, 42, 42, 56, 48]; // Start values 583 const endBorderRadius = [100, 20, 20, 100, 50, 80, 30, 30]; // End values 584 const [beg, stp] = [scrollRange.from, scrollRange.to]; //[20, 400]; 585 586 const scrollInterpolator = new ScrollDrivenArrayInterpolator(startBorderRadius, endBorderRadius, beg, stp); 587 const interpolatedBorderRadius = scrollInterpolator.interpolateByScroll(window.scrollY); 588 589 590 console.log("INTERPOLAAAA"); 591 console.log(interpolatedBorderRadius); 592 593 if (this.er === "SPATIAL-NETWORK"){ // 2900-3400 expecte range 594 // console.clear(); // REAL RANGE IS 1600-2800 595 console.log("SPATIAL RANGE"); 596 console.log("SR " + scrollRange.from + " - " + scrollRange.to); 597 598 console.log(window.scrollY); 599 console.log(t); 600 } 601 // Apply the calculated border-radius to the blobImg element 602 603 // if (t > 0){ 604 605 /* let offsetScrollYBy = 0; 606 let scroll = ((window.scrollY + offsetScrollYBy) / 10) + 1; 607 scroll = scroll / 50; 608*/ 609 /* let r = 42* scroll; 610 if (43 * scroll < 20){ 611 612 }*/ // scroll si too small 613 // console.log("SCROLL-FACTOR:" + scroll); 614 this.blobImg.style.borderRadius = `${interpolatedBorderRadius[0]}% ${interpolatedBorderRadius[1]}% ${interpolatedBorderRadius[2]}% ${interpolatedBorderRadius[3]}% / ${interpolatedBorderRadius[0]}% ${interpolatedBorderRadius[1]}% ${interpolatedBorderRadius[2]}% ${interpolatedBorderRadius[3]}%`; 615 // } 616 617 618 619 // TEMP HIDE ? 620 this.blobImg.style.display = "none"; 621 622 623 this.appMinusConstant = this.imageRange.min; 624 625 // window.addEventListener("scroll", () => { 626 const scrollPositionAB = window.scrollY - this.appMinusConstant; 627 const maxScrollForW = 300; 628 const clampedScroll = Math.max(0, Math.min(scrollPositionAB, maxScrollForW)); 629 console.log("CL" + clampedScroll); 630 631 if (clampedScroll < 0){ 632 clampedScroll = 0; 633 } 634 635 const scrollPosition = window.scrollY; // Get current scroll position 636 console.log("Scroll event fired. Current scroll position:", scrollPosition); 637 638 // Calculate the translation based on scroll position 639 const translateY = Math.min(scrollPosition, 100); // Limit translation to a maximum of 500px
640 const translateX = Math.min(((100) * scrollPosition / 500), window.innerWidth / 2); // Center the image horizontally 641 this.img.style.transform = `translate(${translateX}px, ${translateY}px)`; 642 } 643 } 644} 645 646// on monday 647// sheep Å¡Ãp 648// palma palm 649 650customElements.define("app-showcase", AppShowcase); 651 652 653/* 654class HelloWorld extends HTMLElement { 655 title = document.createElement("h1"); 656 p = document.createElement('p'); 657 constructor() { 658 super(); 659 this.attachShadow({ mode: 'open' }).append(this.title, this.p);//.append(title); 660 } 661 662 // This has to be here 663 static get observedAttributes() { return ['greeting-name', "app-title"]; } 664 attributeChangedCallback(attr, oldVal, newVal) { 665 if (oldVal === newVal) return; // nothing to do 666 switch (attr) { 667 case 'greeting-name': 668 this.p.textContent = `${newVal || 'world'}!`; 669 break; 670 671 case 'app-title': 672 this.title.textContent = `${newVal || 'world'}!`; 673 break; 674 } 675 } 676 677 connectedCallback() { 678 if (!this.getAttribute('greeting-name')) { this.setAttribute('greeting-name', 'world'); } 679 } 680} 681 682customElements.define('hello-world', HelloWorld);*/
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.