4 080 Codepen

SVG маска для фонового изображения

SVG маска для изображения. Удерживая левую кнопку мышки область маски будет расти и изображение вернется к своему исходному состоянию. Перемещая курсор мыши, область под ним будет отображать исходную картинку без маски.

HTML

<svg id="demo" xmlns="http://www.w3.org/2000/svg" x="0" y="0" width="1600" height="900" viewBox="0 0 1600 900">
  <defs>
  <radialGradient id="maskGradient">
    <stop offset="50%" stop-color="#fff"/>
    <stop offset="100%" stop-color="#000"/>
  </radialGradient>
  <mask id="theMask">
   <circle id="masker" r="150" fill="url(#maskGradient)" cx="800" cy="450" />
  </mask>
  </defs> 
    <image id="lines" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/roomSketch.jpg" x="0" y="0" width="1600" height="900" />
    <g id="maskReveal" mask="url(#theMask)" > 
      <image id="regular" xlink:href="https://s3-us-west-2.amazonaws.com/s.cdpn.io/314556/roomColor.jpg" x="0" y="0" width="1600" height="900" />
    </g>
    <circle id="ring" r="20" fill="none" stroke="#dc143c" stroke-width="2" cx="800" cy="450" />
    <circle id="dot" r="4" fill="#dc143c" cx="800" cy="450" />
</svg>

<div id="instructions">
  <svg id="dial" xmlns="http://www.w3.org/2000/svg" width="100" height="100" viewBox="0 0 100 100">
  <path id="progressRing" d="M50,10A40,40,0,1,1,10,50,40,40,0,0,1,50,10Z" fill="none" stroke="#fff" stroke-miterlimit="10" stroke-width="6"/>
  <circle r="43" fill="none" stroke="#fff" cx="50" cy="50" stroke-width="2" opacity="0.5" />
   <circle r="37" fill="none" stroke="#fff" cx="50" cy="50" stroke-width="2" opacity="0.5"/>
   <text transform="translate(55 56)" text-anchor="start" font-size="20" fill="#fff">%</text>
   <text id="counter" transform="translate(55 56)" text-anchor="end" font-size="20" fill="#fff">0</text>
  </svg>
  <p>Hover mouse to move mask around.</p>
  <p>Hold &amp; release mouse button to expand &amp; contract mask.</p>
</div>

CSS

body {
  padding: 0;
  margin: 0;
  font-family: "Signika", sans-serif;
  background: #262626;
  height: 100vh;
  width: 100%;
  overflow: hidden;
  color: white;
}

p {
  margin: 0;
  text-align: center;
  white-space: nowrap;
}

* {
  box-sizing: border-box;
}

#demo {
  cursor: none;
  position: absolute;
}

#instructions {
  position: absolute;
  padding: 12px;
  bottom: 20px;
  background: rgba(0, 0, 0, 0.75);
  left: 50%;
  cursor: none;
  padding-top: 100px;
  user-select: none;
  border-radius: 4px;
}

#dial {
  position: absolute;
  top: 0;
  left: 50%;
}

JS

Дополнительно нужны две библиотеки:
https://cdnjs.cloudflare.com/ajax/libs/gsap/1.20.4/TweenMax.min.js
https://s3-us-west-2.amazonaws.com/s.cdpn.io/16327/DrawSVGPlugin.min.js
Скрипт:
console.clear();
var svg = document.querySelector("#demo");
var tl = new TimelineMax({onUpdate:onUpdate});
var pt = svg.createSVGPoint();
var data = document.querySelector(".tlProgress");
var counter = document.querySelector("#counter");
var ratio = 0.5625;

TweenMax.set("#instructions, #dial", {xPercent: -50});
TweenMax.set("#progressRing", {drawSVG:0});

tl.to("#masker", 2, {attr:{r:2400}, ease:Power2.easeIn});
tl.reversed(true);

function mouseHandler() {
  tl.reversed(!tl.reversed());
}

function getPoint(evt){
  pt.x = evt.clientX; 
  pt.y = evt.clientY;
  return pt.matrixTransform(svg.getScreenCTM().inverse());
}

function mouseMove(evt) {
  var newPoint = getPoint(evt);
  TweenMax.set("#dot", {attr:{cx:newPoint.x, cy:newPoint.y}});
  TweenMax.to("#ring, #masker", 0.88, {attr:{cx:newPoint.x, cy:newPoint.y}, ease:Power2.easeOut});
 }

function onUpdate() {
  var prog = (tl.progress() * 100);
  TweenMax.set("#progressRing", {drawSVG:prog + "%"});
  counter.textContent = prog.toFixed();
}

function newSize() {
  var w = window.innerWidth ;
  var h = window.innerHeight;
  if (w > h * (16/9) ) {
    TweenMax.set("#demo", { attr: { width: w, height: w * ratio } });
  } else {
    TweenMax.set("#demo", { attr: { width: h / ratio, height: h } });
  }
  var data = svg.getBoundingClientRect();
  TweenMax.set("#demo", {x:w/2 - data.width/2});
  TweenMax.set("#demo", {y:h/2 - data.height/2});
}

window.addEventListener("mousedown", mouseHandler);
window.addEventListener("mouseup", mouseHandler);
window.addEventListener("mousemove", mouseMove);

newSize();
window.addEventListener("resize", newSize);

Комментарии

  • Facebook
  • Вконтакте

Похожие статьи