Chat Artifacts Gallery Guilds Search Wiki Login Register

Welcome, Guest. Please login or register. - Thinking of joining the forum??
April 28, 2026 - @927.07 (what is this?)
Activity rating: Three Stars Posts & Arts: 39/1k.beats Random | Recent Posts | Guild Recents
News: :sleep: These are fast times on the World Wide Web~ Guild Events: There are no events!

+  MelonLand Forum
|-+  Life & The Web
| |-+  ✁ ∙ Web Crafting
| | |-+  ☔︎ ∙ I need Help!
| | | |-+  how to toggle if background gifs play or not?


« previous next »
Pages: [1] Print
Author Topic: how to toggle if background gifs play or not?  (Read 39 times)
halcybutton
Full Member ⚓︎
***
View Profile WWWArt


i may be cringe but i am free
⛺︎ My Room
SpaceHey: Friend Me!
StatusCafe: halcybutton
iMood: halcybutton
Matrix: Chat!

Guild Memberships:
Artifacts:
First 1000 Members!Joined 2023!
« on: Today at @48.65 »

so on my site i use freezeframe to pause gifs, which is great for stuff within the html itself. however, i have gifs in the css themes themselves that i have no idea how to make it so that you can pause/play them with a button press (preferably with having them start paused). i suppose i could just have no gifs in the background, but i wish i could make it an option instead. anyone have any idea how to make it so that i can have freezeframe affect my css? or if it's a separate process that's needed, how to do so? if it's impossible i understand that as well. i had a bit of success with using an :active class and having png stills of the gifs, but it broke when multiple themes got involved with my tinkering, so i scrapped it for the time being

css
Code
:root {  
  --primary-bg: #f8f8ff;
  --secondary-bg: #DCDCDC;
  --bg: url(/root/backgrounds/greyflowr.gif);
  --button-bg: #838996;  
  --button-text: white;  
  --header-bg: url(/root/header/stars.gif);
  --boxes-bg: url(/root/backgrounds/swirls.gif);
  --main2-bg: url(/root/backgrounds/stripes.gif);
}  
 @font-face {
  font-family: retro; 
  src: url(/root/fonts/retrocomp.ttf); 
}
 @font-face {
  font-family: DS; 
  src: url(/root/fonts/DS.ttf); 
}
* {
  cursor: url('https://cdn.cursors-4u.net/previews/the-moon-482c66bd-32.webp') 32 32, auto !important;
}
body {  
  background: var(--bg);
  font-family: monospace;
  padding: 5px;
    }
    .container {
  display: flex;
  border: 1px solid black;
  background: var(--secondary-bg);
  text-align: center;
  height: 800px;
  overflow: hidden;
  flex: 0 0 100%;
  flex-flow: row wrap;
  font-family: DS;
}
@media (max-width: 600px) {
  .container {
    flex-direction: column wrap;
      flex: 100%;
      overflow: auto;
  }
}
@media all and (min-width: 600px) {
  .aside { flex: 1 0 0; }
  
}


@media all and (min-width: 800px) {
  .main    { flex: 3 800px; }
  .primary-div { order: 2; } 
  .main    { order: 3; }
  .secondary-div { order: 4; }
  .header  { order: 1; }
}

.header {
  background: var(--header-bg);
  width: 100%;
  margin-top: 0px;
  height: 150px;
}
 .primary-div {
      background: var(--secondary-bg);
      overflow: auto;
      scrollbar-width: none;
      height: 625px;
      flex-grow: 0;
      padding: 5px;
      text-align: left;
    }
    .main {
      width: auto;
      height: 700px;
      text-align: center;
      font-size: 20px;
      overflow: auto;
      scrollbar-width: none;
      border: black 1px solid;
      background: var(--primary-bg);
      flex-grow: 1;
      padding: 5px;
      align-items: center;
    }
    .secondary-div {
      background: var(--secondary-bg);
      overflow: auto;
      scrollbar-width: none;
      height: 625px;
      flex-grow: 0;
      padding: 5px;
    }
    .main2 {
        width: 90%;
        height: 150px;
        overflow: auto;
        scrollbar-width: none;
        background: var(--main2-bg);
        border: 1px dotted black;
        padding: 5px;
        text-align: center;
    }
.container2 {
    display: flex;
    flex-flow: row nowrap;
    height: 35%;
    overflow: hidden;
}
@media (max-width: 600px) {
  .container2 {
    flex-flow: column wrap;
      flex: 100%;
      overflow: auto;
  }
}

.box1 {
    flex: 1;
    border: 1px dotted black;
    background: var(--boxes-bg);
    overflow: auto;
    scrollbar-width: none;
    padding: 5px;
}  
.box1:first-child {
    margin-right: 20px;
    border: 1px dotted black;
    background: var(--boxes-bg);
    overflow: auto;
    scrollbar-width: none;
    padding: 5px;
} 
table.tables {
  width: 100%;
  background-color: #F8F8FF;
  border-collapse: collapse;
  border-width: 2px;
  border-color: #000000;
  border-style: solid;
  color: #000000;
}

table.tables td, table.tables th {
  border-width: 2px;
  border-color: #000000;
  border-style: solid;
  padding: 5px;
}

table.tables thead {
  background-color: #D0D6F8;
}
 
h3 {
    font-family: retro;
    border: 1px solid black;
    background: url(/root/backgrounds/snowAC.gif);
    text-align: center;
}

button {
  background: var(--button-bg);
  color: var(--button-text);
  border: 1px solid black;
}
ul {
  list-style-image: url('/root/favicons/starshoot.gif');
}
a:link {
  color: #778899;
  text-decoration: none;
}

a:visited {
  color: #536878;
  text-decoration: none;
}

a:hover {
  color: blue;
  text-decoration: underline;
}

a:active {
  color: red;
  text-decoration: underline;
}

.marquee {
  width: 90%;
  height: 40px;
  background: #8c92ac;
  border: 1px dotted black;
  white-space: nowrap;
  overflow: hidden;
}
.marquee2 {
  width: 90%;
  height: 25px;
  background: #8c92ac;
  border: 1px dotted black;
  white-space: nowrap;
  overflow: hidden;
}

.marquee div {
  padding-left: 50%;
  display: inline-block;
  animation: animate 25s linear infinite;
    align-items: center;
}
.marquee2 div {
  padding-left: 50%;
  display: inline-block;
  animation: animate 25s linear infinite;
    align-items: center;
}

@keyframes animate {
  100% {
    transform: translate(-100%, 0);
  }
}
.generator {
  background: url(/root/backgrounds/stripes.gif);
  height: 200px;
  width: 350px;
  border: 1px dotted black;
  text-align: center;
  color: black;
  font-family: DS;
}

.generator button {
  background: #3b444b;
  border: 3px inset aliceblue;
  color: #e5e4e2;
  padding: .5em;
  font-family: retro;
  font-weight: bolder;
}
html / freezeframe
Code
<!DOCTYPE html>  
<html lang="en">  
<head>  
  <meta charset="UTF-8">  
  <meta name="viewport" content="width=device-width, initial-scale=1.0">  
  <title>halcyon daze</title>  
<link rel="icon" type="image/x-icon" href="/root/favicons/paw.gif">
  <link id="theme-stylesheet" rel="stylesheet" href="/css/light.css">  
     <script src="https://iframe.chat/scripts/main.min.js"></script>
          <script>class FreezeImages {
  constructor(options = {}) {
    // Set default params
    this.selector = options.selector || "freeze"
    this.imgCls = "ff-img";
    this.canvasCls = "ff-canvas";
    this.hover = (options.hover === true || options.hover === "true") ? true : false;
    this.noCSS = (options.no_css === true || options.hover === "true") ? true : false;
    this.smoothing = (options.smoothing === false) ? false : true;

    // Finds all images with selector class and within elements with the selected class
    //  and creates list
    const imgList = document.querySelectorAll(`img.${this.selector}, .${this.selector} img`);
    this.imgList = imgList;

    // Creates <style> tag for new elements
    if (!this.noCSS) {
      const style = document.createElement('style');
      style.textContent = `
        .ff-container {
          display: inherit;
          width: 7.5px;
        }

        .ff-container img,
        .ff-container canvas {
          align-self: start;
        }

        .ff-container.ff-hover:hover .ff-active {
          position: absolute;
          opacity: 0;
        }

        .ff-container.ff-hover:hover .ff-inactive {
          position: static;
          opacity: 1;
          z-index: 1;
        }

        .ff-inactive {
          position: absolute;
          opacity: 0;
          z-index: -99;
        }
      `;
      document.head.appendChild(style);
    }

    // Loops through all images
    for (const img of this.imgList) {
      // Gives <img> the inactive class, which hides GIF by default
      img.className = `${this.imgCls} ff-inactive`;

      // Creates <canvas> of GIF and copies data of first frame of animation
      let canvas = document.createElement("canvas");
      canvas.width = img.width;
      canvas.height = img.height;
      canvas.className = `${this.canvasCls} ff-active`;
      canvas.getContext('2d').imageSmoothingEnabled = this.smoothing;
      canvas.getContext('2d').drawImage(img, 0, 0, img.width, img.height);

      // Creates container that will hold both <img> and <canvas>
      let wrapper = document.createElement("div");
      wrapper.className = "ff-container";
      if (this.hover) wrapper.classList.add("ff-hover");

      // Inserts container with <img> and <canvas> where <img> originally was
      img.parentNode.insertBefore(wrapper, img);
      wrapper.appendChild(img);
      wrapper.appendChild(canvas);
    }
  }

  start() { // Starts animation
    for (const img of this.imgList) {
      img.className = `${this.imgCls} ff-active`;
      img.nextSibling.className = `${this.canvasCls} ff-inactive`;
    }
  }

  stop() { // Stops animation
    for (const img of this.imgList) {
      img.className = `${this.imgCls} ff-inactive`;
      img.nextSibling.className = `${this.canvasCls} ff-active`;
    }
  }

  toggle() { // Toggles animation based on current state
    for (const img of this.imgList) {
      let imgNewCls = (img.className.includes('ff-inactive')) ? "ff-active": "ff-inactive";
      let canvasNewCls = (img.className.includes('ff-inactive')) ? "ff-inactive": "ff-active";

      img.className = `${this.imgCls} ${imgNewCls}`;
      img.nextSibling.className = `${this.canvasCls} ${canvasNewCls}`;
    }
  }
}

// Waits for page to finish loading
document.addEventListener("readystatechange", function () {
  if (document.readyState === "complete") {
    // Initialize script
    const f = new FreezeImages (
  {
    selector: "freeze",
  }
)

    // Set event listeners for all buttons
    for(const el of document.getElementsByClassName('play-gif')) {
      el.addEventListener('click', () => f.start());
    }

    for(const el of document.getElementsByClassName('stop-gif')) {
      el.addEventListener('click', () => f.stop());
    }

    for(const el of document.getElementsByClassName('toggle-gif')) {
      el.addEventListener('click', () => f.toggle());
    }
  }
});</script>
</head> 
<body> 
<div class="container">
<header class="header"></header>
 <aside class="primary-div">
     <br>
     <center>
  <button onclick="lightmode()">light</button> - 
<button onclick="darkmode()">dark</button> - 
<button onclick="brightmode()">vivid</button>
<script src="/css/script2.js"></script><br>
<i>eyestrain & flash/glitch warning for vivid</i>
</center>
<br>
<center><button class="toggle-gif">toggle gifs (w.i.p)</button></center>
 </aside>
  <article class="main">  
    <center><div class="main2">
    </div></center>
    <br>
        <div class="container2">
  <div class="box1">
  </div>
  <div class="box1 child">
  </div>
</div>
  </article>  
  <aside class="secondary-div">
  </aside>
</div>
</body>  
</html>  

i only included one css file of the three i use as i figure if one is figured out, the others will have the same/similar solution as the only differences are the files/colors used in the root... though admittedly that didn't seem to work when i tried messing with :active lol. regardless, if needed i can provide the other two css files. i hope i explained myself/what i'm needing clearly, if any clarification is needed i will do my best to elaborate. if you want to see my site, it's here. (it's also linked on my profile)
Logged

https://pixelsafari.neocities.org/favicon/symbol/heart/blue1.gif HALCYON  https://pixelsafari.neocities.org/favicon/animals/fishshark.gif
none/it/ey - EST
https://www.internetbumperstickers.com/066811/i01/intrnt_celeb_training.png
Dan Q
Hero Member ⚓︎
*****
View Profile WWWArt


I have no idea what I am doing
⛺︎ My Room
RSS: RSS

Guild Memberships:
« Reply #1 on: Today at @331.64 »

As I see it, you've got fundamentally two options. Here they are:

  • Use freezeframe but put a canvas in the background - that freezeframe script you talk about looks like it just renders to a <canvas>, right? Well how about using CSS to position that canvas as a background? Put it early in the page (to save you fiddling with z-indexes) and set something like position: fixed; top: 0; left: 0; width: 100vw; height: 100vw; object-fit: cover; I've not tried it but there's probably a solution in this vein somewhere.
  • Do an image swap - the classic way to pause/play a GIF is to have two images: one is a still frame, the other is the animation. Then just use JS to swap them (or have two elements, one with each, and swap them: slightly more-complicated but reduces the risk of a FOUS).

Just wanted to type in a quick answer before I go to work; can help get to the bottom of either approach later if it's useful.

(Or maybe this is an excuse for me to bust out Yet Another Web Component...)
Logged

https://danq.me/_q26t/badges/dan-q-88x31-lighter.gif https://danq.me/_q26t/badges/dan-q-88x31-peekaboo-scroller.gif https://beige-buttons.danq.dev/beige-buttons-88x31.gif https://embed-html.danq.dev/embed-html-88x31.gif

Artifact Swap: I met Dan Q on Melonland!PolyamorousBouncy Egg!Joined 2025!Lurby
Pages: [1] Print 
« previous next »
 

Melonking.Net © Always and ever was! SMF 2.0.19 | SMF © 2021 | Privacy Notice | ~ Send Feedback ~ Forum Guide | Rules | RSS | WAP | Mobile


MelonLand Badges and Other Melon Sites!

MelonLand Project! Visit the MelonLand Forum! Support the Forum
Visit Melonking.Net! Visit the Gif Gallery! Pixel Sea TamaNOTchi

MelonLand Nav

@000

Want to Login or Join ?

Minecraft: Online
Who: AAAAAAAAAAA13