DIR : /home/kozerus/public_html/ko/timer13.htm

/home/kozerus/public_html/ko

<html>
<head>

<style>
* {
  box-sizing: border-box;
  outline: none;
  user-select: none;
}
body {
  align-items: center;
  background: radial-gradient(ellipse at center, rgba(255,179,206,0) 0%, rgba(255,180,199,0) 43%, rgba(255,181,189,0.43) 100%);
  background-attachment: fixed;
  background-repeat: no-repeat;
  display: flex;
  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ffb3ce', endColorstr='#6effb5bd', GradientType=1);
  flex-direction: column;
  font-family: "Open Sans", sans-serif;
  height: 100vh;
  justify-content: center;
  min-width: 184px;
  overflow-x: hidden;
  transition: background-color .2s;
}
#pomodoro {
  margin-bottom: 43px;
  max-width: 512px;
  width: 100%;
  #clock {
    background: url(https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/bg.png) no-repeat center center;
    background-size: contain;
    display: flex;
    justify-content: center;
    margin-bottom: -6.25vw;
    padding: 40vw 0;
    @media all and (min-width: 512px){
      margin-bottom: -32px;
      padding: 204px 0;
    }
    @media all and (max-width: 184px){
      margin-bottom: -20px;
      margin-bottom: -11.5px;
      padding: 73px 0;
    }
    #timer {
      $hover: 5;
      align-items: center;
      cursor: pointer;
      display: flex;
      flex-direction: column;
      #title {
        color: #FF8B8A;
        font-size: 28px;
        line-height: 28px;
        margin: 3px 0 1px;
        @media all and (max-width: 512px){
          font-size: 5.5vw;
          line-height: 5.5vw;
        }
        @media all and (max-width: 184px){
          font-size: 10px;
          line-height: 10px;
        }
      }
      #countdown {
        color: #ff778d;
        display: flex;
        font-size: 43px;
        font-weight: 600;
        line-height: 43px;
        @media all and (max-width: 512px){
          font-size: 8.4vw;
          line-height: 8.4vw;
        }
        @media all and (max-width: 184px){
          font-size: 15.4px;
          line-height: 15.4px;
        }
        #minutes::after {
          content: ":";
        }
      }
      #controls {
        align-items: center;
        display: flex;
        color: #FF6292;
        flex-direction: column;
        font-size: 15px;
        font-weight: 700;
        line-height: 15px;
        margin-top: 5px;
        text-align: center;
        text-transform: uppercase;
        .fas, .svg-inline--fa {
          position: relative;
        }
        #start, #pause, #reset {
          white-space: nowrap;
        }
        #start {
          .fa-play {
            font-size: 77%;
            top: -1px;
          }
          &:hover {
            color: darken(#FF6292, $hover);
          }
        }
        #pause {
          .fa-pause {
            font-size: 90%;
            top: -1px;
            transform: scaleX(.84);
          }
          &:hover {
            color: darken(#FF6292, $hover);
          }
        }
        #reset {
          position: absolute;
          margin-top: 17.56px;
          transition: margin-top .43s, opacity .43s;
          .fa-sync-alt {
            font-size: 84%;
          }
          &:hover {
            color: darken(#FF6292, $hover);
          }
        }
        &.reset {
          #pause {
            display: none;
          }
          #reset {
            margin-top: 0;
            opacity: 0;
            z-index: -1;
          }
        }
        &.started {
          #start {
            display: none;
          }
          #reset {
            opacity: 0;
          }
        }
        &.paused {
          #pause {
            display: none;
          }
        }
        @media all and (max-width: 512px){
          font-size: 5.5vw;
          line-height: 5.5vw;
          #start, #pause, #reset {
            font-size: 3vw;
            line-height: 3vw;
          }
          #reset {
            margin-top: 3.43vw;
          }
        }
        @media all and (max-width: 184px){
          font-size: 10px;
          line-height: 10px;
          #start, #pause, #reset {
            font-size: 5.5px;
            line-height: 5.5px;
          }
          #reset {
            margin-top: 6.31px;
          }
        }
      }
    }
  }
  #options {
    color: #FF6292;
    display: flex;
    font-size: 28px;
    font-weight: normal;
    justify-content: center;
    margin-bottom: 28px;
    text-align: center;
    .option-title {
      color: #FF6F8A;
      font-size: 14px;
      font-weight: bold;
      margin-top: 8px;
      margin-bottom: -6px;
      text-transform: uppercase;
    }
    .fa-angle-double-up {
      color: #FF848A;
      cursor: pointer;
    }
    .fa-angle-double-down {
      color: #FF5792;
      cursor: pointer;
    }
    #session, #break {
      align-items: center;
      display: flex;
      flex-direction: column;
    }
    input[type=number]{
      background: linear-gradient(lighten(#FF8B8A, 20), lighten(#FF6292, 22));
      border: 0;
      border-bottom: calc(3px + .28vw) solid #FF6292;
      border-radius: 10px;
      color: #FF6292;
      font: bold calc(21px + 1.43vw) "Open Sans", sans-serif;
      margin: calc(5px + .43vw) calc(3px + .43vw);
      padding: calc(3px + .43vw) calc(5px + .43vw);
      text-align: center;
      &::-webkit-inner-spin-button, 
      &::-webkit-outer-spin-button { 
        -webkit-appearance: none; 
      }
      @media all and (min-width: 512px){
        border-bottom: 4.43px solid #FF6292;
        font: bold 28.43px "Open Sans", sans-serif;
        margin: 7.2px 5.2px;
        padding: 5.2px 7.2px;
      }
      @media all and (max-width: 184px){
        border-bottom: 3.5px solid #FF6292;
        font: bold 23.6px "Open Sans", sans-serif;
        margin: 5.7px 3.7px;
        padding: 3.7px 5.7px;
      }
    }
  }
}
audio { 
  display: none;
}
#audio-selector {
  display: flex;
  left: 0;
  position: fixed;
  top: 0;
  width: 100vw;
  .theme {
    background: linear-gradient(to bottom, rgba(255,99,127,0.28) 0%, rgba(255,99,127,0.28) 1%, rgba(255,98,143,0) 84%, rgba(255,98,146,0) 100%);
    color: darken(desaturate(#FF7B8A, 30), 10);
    cursor: pointer;
    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#47ff637f', endColorstr='#00ff6292', GradientType=0);
    flex: 1 1 25%;
    font: 600 calc(9px + 1vw) "Open Sans", sans-serif;
    margin: 0 2px 0 0;
    padding: 2vw 1vw 5vw;
    text-align: center;
    transition: all .43s;
    white-space: nowrap;
    &:last-child {
      margin-right: 0;
    }
    &:hover, &.selected {
      background: linear-gradient(to bottom, rgba(255,99,127,0.43) 0%, rgba(255,99,127,0.43) 1%, rgba(255,98,143,0) 84%, rgba(255,98,146,0) 100%);
      filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#6eff637f', endColorstr='#00ff6292', GradientType=0);
    }
    @media all and (min-width: 512px){
      font-size: 15.33px;
      padding: 9px 5px 25px;
    }
  }
  @media all and (max-width: 300px){
    flex-wrap: wrap;
    .theme {
      flex: 1 0 100%;
      font-size: 14px;
      padding: 7px;
    }
  }
}
	</style>


<script>

$(() => {

  let $audio = $("audio"), // from https://tide.moreless.io/en/
      $theme = $(".theme"),
      $title = $("#title"),
      $controls = $("#controls"),
      $options = $("#options"),
      $minutes = $("#minutes"),
      $seconds = $("#seconds"),
      $start = $("#start"),
      $pause = $("#pause"),
      $reset = $("#reset"),
      $incrSession = $("#incrSession"),
      $sessionInput = $("#sessionInput"),
      $decrSession = $("#decrSession"),
      $incrBreak = $("#incrBreak"),
      $breakInput = $("#breakInput"),
      $decrBreak = $("#decrBreak"),
      breakLength = 5 * 60,
      breakMax = 10,
      breakMin = 1,
      sessionLength = 30 * 60,
      sessionMax = 60,
      sessionMin = 5,
      sessionNum = 0,
      countdown,
      countType,
      remainingTime = sessionLength;

  init();

  function init(){
    $audio.prop("volume", 0);
    $incrSession.click(() => incrSession());
    $decrSession.click(() => decrSession());
    $incrBreak.click(() => incrBreak());
    $decrBreak.click(() => decrBreak());
    $sessionInput.on("change", e => updateSession(e.target.value));
    $breakInput.on("change", e => updateBreak(e.target.value));
    $start.click(() => { if (countType === "break"){ startBreak(); } else { startSession(); } });
    $pause.click(() => pause());
    $reset.click(() => reset());
    $theme.click(e => audioSelect(e));
  }
  function startSession(){
    sessionNum++;
    countType = "session";
    $options.slideUp(143);
    $controls.removeClass().addClass("started");
    $title.fadeOut(43, function(){
      $(this).html("Session " + sessionNum).fadeIn();
    });
    $audio.animate({volume: 1}, 1000);
    start(remainingTime || sessionLength);
  }
  function startBreak(){
    countType = "break";
    $title.fadeOut(43, function(){
      $(this).html("Break " + sessionNum).fadeIn();
    });
    $audio.animate({volume: 0}, 5000);
    start(remainingTime || breakLength);
  }
  function start(timeLeft){
    clearInterval(countdown);
    countdown = setInterval(() => {
      timeLeft--;
      remainingTime = timeLeft;
      let minLeft = Math.floor(timeLeft / 60),
          secLeft = timeLeft - minLeft * 60;
      updateMinutes(minLeft);
      updateSeconds(secLeft < 10 ? "0" + secLeft : secLeft);
      if (timeLeft < 1){
        if (countType === "session"){
          startBreak(breakLength);
        } else {
          startSession();
        }
      }
    }, 1000);
  }
  function pause(){
    sessionNum--;
    $audio.animate({volume: 0}, 1000);
    clearInterval(countdown);
    $options.slideDown(143);
    $controls.removeClass().addClass("paused");
    $title.fadeOut(43, function(){
      $(this).html("Paused").fadeIn();
    });
  }
  function reset(){
    clearInterval(countdown);
    updateMinutes(sessionLength / 60);
    updateSeconds("00");
    countType = undefined;
    $controls.removeClass().addClass("reset");
    $title.html("Ready?");
    remainingTime = sessionLength;
  }
  function incrSession(){
    let num = Number($sessionInput.val());
    num = num + (num === sessionMax ? 0 : 1);
    sessionLength = num * 60;
    updateSession(num);
    updateMinutes(num);
    updateSeconds("00");
    reset();
  }
  function decrSession(){
    let num = Number($sessionInput.val());
    num = num - (num === sessionMin ? 0 : 1);
    sessionLength = num * 60;
    updateSession(num);
    updateMinutes(num);
    updateSeconds("00");
    reset();
  }
  function incrBreak(){
    let num = Number($breakInput.val());
    num = num + (num === breakMax ? 0 : 1);
    breakLength = num * 60;
    updateBreak(num);
    reset();
  }
  function decrBreak(){
    let num = Number($breakInput.val());
    num = num - (num === breakMin ? 0 : 1);
    breakLength = num * 60;
    updateBreak(num);
    reset();
  }
  function updateMinutes(num){
    $minutes.text(num);
  }
  function updateSeconds(num){
    $seconds.text(num);
  }
  function updateSession(num){
    num = num < sessionMin ? sessionMin : num > sessionMax ? sessionMax : num;
    $sessionInput.val(num).blur();
    updateMinutes(num);
    updateSeconds("00");
    sessionLength = num * 60;
    reset();
  }
  function updateBreak(num){
    $breakInput.val(num < breakMin ? breakMin : num > breakMax ? breakMax : num).blur();
    breakLength = num * 60;
    reset();
  }
  function audioSelect(e){
    $theme.removeClass("selected");
    $(e.target).addClass("selected");
    switch(e.target.id){
      case "forest": $audio.attr("src", "https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/forest.mp3"); break;
      case "ocean": $audio.attr("src", "https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/ocean.mp3"); break;
      case "rainy": $audio.attr("src", "https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/rain.mp3"); break;
      case "peace": $audio.attr("src", "https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/peace.mp3"); break;
      case "cafe": $audio.attr("src", "https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/cafe.mp3"); break;
    }
  }

});
	</script>

	</head>
<body bgcolor=linen>

<!-- --------------------------------------------- -->
<!-- Image inspired by Tide, a pomodoro app I use. -->
<!-- Check it out at: https://tide.moreless.io/en/ -->
<!-- --------------------------------------------- -->

<div id="pomodoro">
  <div id="clock">
    <div id="timer">
      <div id="title">Ready?</div>
      <div id="countdown">
        <span id="minutes">30</span>
        <span id="seconds">00</span>
      </div>
      <div id="controls" class="reset">
        <div id="start"><i class="fas fa-play"></i> Start</div>
        <div id="pause"><i class="fas fa-pause"></i> Pause</div>
        <div id="reset"><i class="fas fa-sync-alt"></i> Reset</div>
      </div>
    </div>
  </div>
  <div id="options">
    <div id="session">
      <i id="incrSession" class="fas fa-angle-double-up"></i>
      <span class="option-title">Session</span>
      <input id="sessionInput" type="number" value="30" max="60" min="5">
      <i id="decrSession" class="fas fa-angle-double-down"></i>
    </div>
    <div id="break">
      <i id="incrBreak" class="fas fa-angle-double-up"></i>
      <span class="option-title">Break</span>
      <input id="breakInput" type="number" value="5" max="10" min="1">
      <i id="decrBreak" class="fas fa-angle-double-down"></i>
    </div>
  </div>
</div>
<div id="audio-selector">
  <div id="forest" class="theme"><!--🌲 -->Forest</div>
  <div id="ocean" class="theme"><!--🌊 -->Ocean</div>
  <div id="rainy" class="selected theme"><!--🌧 -->Rainy</div>
  <div id="peace" class="theme"><!--🧘 -->Peace</div>
  <div id="cafe" class="theme"><!--☕ -->Caf&eacute;</div>
</div>
<audio loop autoplay="false" src="https://joeweaver.me/codepenassets/freecodecamp/challenges/build-a-pomodoro-clock/rain.mp3">

	</body>
	</html>
//


koh5_pano



Your browser does not support the HTML5 canvas element.


Drag mouse to navigate.

Navigation





17.Aug.2010, Martin Wengenmayer