javascript - SVG hover with multiple elements -


i've 2 svg elements on i've applied mouseover/mouseout event. goal increase radius of mask on mouseover size specified variable (maxmaskradius) , decrease on mouseout initial state (initialmaskradius).

i works 1 element. when i've 2 elements , hover 1 element another, animation previous elements aborts immediately. i'd have animate initial state. current code that's unfortunately not possible.

any suggestions on how proper?

demo

css:

.dday.highlight .overlay {     fill: rgba(247,99,62,0.8); }  .dday.normal {     width: 288px;     height: 288px; } 

html:

<svg class="dday highlight normal" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-image="car.jpg">      <image height="196" width="250" />      <a class="overlay" xlink:href="/svg/index.html" target="_top">         <rect x="0" y="0" width="288" height="288" style="mask: url(#mask1)" onmouseover="initanimation(evt)" onmouseout="initanimation(evt)" />     </a>      <mask id="mask1">         <rect x="0" y="0" width="288" height="288" fill="#fff" />         <circle cx="125" cy="125" r="25" />     </mask>  </svg>   <svg class="dday highlight normal" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-image="nokia.jpg">      <image height="196" width="250" />      <a class="overlay" xlink:href="/svg/index.html" target="_top">         <rect x="0" y="0" width="288" height="288" style="mask: url(#mask2)" onmouseover="initanimation(evt)" onmouseout="initanimation(evt)" />     </a>      <mask id="mask2">         <rect x="0" y="0" width="288" height="288" fill="#fff" />         <circle cx="125" cy="125" r="25" />     </mask>  </svg> 

js:

var maximagewidth = 250,     maximageheight = 196,     ease = 50,     speed = 12,     maxmaskradius = 100,      svg = null,     svgwidth = null,     svgheight = null,     mask = null,     maskradius = null,     initialmaskradius = null,     imageobj = [],     imagesrcs = [],     imagewidth = null,     imageheight = null,     mouseevent = null;  init();  function init(el, index) {     $('.dday').each(function(index){         definecurrentelement(this, index);         positionmask();     }); }  function definecurrentelement(el, index) {     // redefine current element     svg = $(el).closest('.dday'),     svgwidth = svg.width(),     svgheight = svg.height(),     mask = svg.find('circle')[0];      // on page load there index provided load images each element     if(typeof index !== 'undefined'){         loadimage(index);     } }  function loadimage(index) {     // load images , scale them fit predefined area     imagesrcs[index] = svg.data('image');      imageobj[index] = new image(),     imageobj[index].image = $('image')[index];      imageobj[index].onload = function(){         scale_width = maximagewidth / this.width;         scale_height = maximageheight / this.height;          scale = math.min(scale_width, scale_height);          imagewidth = this.width * scale;         imageheight = this.height * scale;          var xcoordinate = (svgwidth - imagewidth) / 2,             ycoordinate = (svgheight - imageheight) / 2;          this.image.setattributens('http://www.w3.org/1999/xlink','href', imagesrcs[index]);         this.image.setattributens(null,'width', imagewidth);         this.image.setattributens(null,'height', imageheight);         this.image.setattributens(null,'x', xcoordinate);         this.image.setattributens(null,'y', ycoordinate);     };     imageobj[index].src = imagesrcs[index]; }  function initanimation(ev) {     // triggered on mouseover/-out     // change current element , init animation     definecurrentelement(ev.target);     mouseevent = ev.type;     requestanimationframe(animate); }  function animate() {     if(mouseevent == 'mouseover') {         // increase mask radius on mouseover , repeat until target state reached          maskradius += math.round(math.max(((maxmaskradius-maskradius)/ease) * speed, 0.5));          if(maskradius >= maxmaskradius) {             // target radius has been reached             maskradius = maxmaskradius;         } else {             // target radius hasn't been reached yet -> repeat animation             mask.setattributens(null,'r', maskradius);             requestanimationframe(animate);         }     } else {         // decrease mask radius on mouseover , repeat until initial state reached          maskradius -= math.max(((maskradius-initialmaskradius)/ease) * speed, 0.5);          if(maskradius <= initialmaskradius) {             // target radius has been reached             maskradius = initialmaskradius;         } else {             // target radius hasn't been reached yet -> repeat animation             mask.setattributens(null,'r', maskradius);             requestanimationframe(animate);         }     } }  function positionmask() {     // center mask inside element     maskradius = initialmaskradius = parseint(mask.getattributens(null, 'r'), 10);      var maskwidth = maskradius * 2,         xcoordinate = (svgwidth - maskwidth) / 2 + maskradius,         ycoordinate = (svgheight - maskwidth) / 2 + maskradius;      mask.setattributens(null,'cx', xcoordinate);     mask.setattributens(null,'cy', ycoordinate); } 

okke, fixed code, , not easy task work code. please declare variables use, , not use in function global variables own private variables, because can re-write existing global variable.

now fixed code:

  • css: no changes.
  • html: removed inline handlers (onmouseover , onmouseout)

  • javascript:

    • when document ready each svg element class dday initializing: downloading image svg if variable index exists (loading logic didn't changed almost), centering mask, declaring function animation, adding handler rect element in a element in initializing svg element.
    • all settings has been exported variable settings
    • all private variables svg stored in {svgelement}.svgdata object.

demo: jsfiddle

p.s. way, code not enougt, need more time clean code, code works.

html:

<svg class="dday sector-sports normal" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-image="http://img1.wikia.nocookie.net/__cb20130511205806/epicrapbattlesofhistory/images/9/94/vaderrotj.jpg">      <image height="196" width="250" />      <a class="overlay" xlink:href="/svg/index.html" target="_top">         <rect x="0" y="0" width="288" height="288" style="mask: url(#mask1)" />     </a>      <mask id="mask1">         <rect x="0" y="0" width="288" height="288" fill="#fff" />         <circle cx="125" cy="125" r="25" />     </mask>  </svg>   <svg class="dday sector-sports normal" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" data-image="http://static.comicvine.com/uploads/original/11111/111116692/3213841-7948839370-yoda..jpg">      <image height="196" width="250" />      <a class="overlay" xlink:href="/svg/index.html" target="_top">         <rect x="0" y="0" width="288" height="288" style="mask: url(#mask2)" />     </a>      <mask id="mask2">         <rect x="0" y="0" width="288" height="288" fill="#fff" />         <circle cx="125" cy="125" r="25" />     </mask>  </svg> 

javascript: (used jquery 1.11 library)

$(document).ready(function () {     var settings = {         imagewidthmax: 250,         imageheightmax: 196,         ease: 50,         speed: 12,         maskradiusmax: 100     };     var maskelements = [];      $('svg.dday').each(function (index) {          if (maskelements.indexof(this) < 0) {             maskelements.push(this);             var sd = {};             this.svgdata = sd;              sd.svg = $(this);             sd.svgwidth = sd.svg.width();             sd.svgheight = sd.svg.height();             sd.mask = sd.svg.find('circle')[0];              // on page load there index provided load images each element             if (typeof index !== 'undefined') {                  var img = new image();                  img.image = $('image')[index];                 img.onload = function () {                     var m_scale_width = settings.imagewidthmax / this.width;                     var m_scale_height = settings.imageheightmax / this.height;                     var m_scale = math.min(m_scale_width, m_scale_height);                      sd.imgwidth = this.width * m_scale;                     sd.imgheight = this.height * m_scale;                      var m_x = (sd.svgwidth - sd.imgwidth) / 2;                     var m_y = (sd.svgheight - sd.imgheight) / 2;                      this.image.setattributens('http://www.w3.org/1999/xlink', 'href', sd.svg.data('image'));                     this.image.setattributens(null, 'width', sd.imgwidth);                     this.image.setattributens(null, 'height', sd.imgheight);                     this.image.setattributens(null, 'x', m_x);                     this.image.setattributens(null, 'y', m_y);                 };                 img.src = sd.svg.data('image');              }              //center mask inside element             sd.maskradiusinit = parseint(sd.mask.getattributens(null, 'r'), 10);             sd.maskradius = sd.maskradiusinit;              sd.maskwidth = sd.maskradius * 2;             sd.maskx = (sd.svgwidth - sd.maskwidth) / 2 + sd.maskradius;             sd.masky = (sd.svgheight - sd.maskwidth) / 2 + sd.maskradius;              sd.mask.setattributens(null, 'cx', sd.maskx);             sd.mask.setattributens(null, 'cy', sd.masky);              var animate = function () {                 var m_addtoradius = math.round(math.max(((settings.maskradiusmax - sd.maskradius) / settings.ease) * settings.speed, 0.5));                 if (sd.eventtype === 'mouseover') {                     sd.maskradius += m_addtoradius;                      if (sd.maskradius > settings.maskradiusmax) {                         sd.maskradius = settings.maskradiusmax;                         sd.mask.setattributens(null, 'r', sd.maskradius);                     } else {                         sd.mask.setattributens(null, 'r', sd.maskradius);                         requestanimationframe(animate);                     }                 } else {                     sd.maskradius -= math.round(math.max(m_addtoradius, 0.5));                      if (sd.maskradius <= sd.maskradiusinit) {                         sd.maskradius = sd.maskradiusinit;                         sd.mask.setattributens(null, 'r', sd.maskradius);                     } else {                         sd.mask.setattributens(null, 'r', sd.maskradius);                         requestanimationframe(animate);                     }                 }             };              $('a>rect', this).on('mouseover mouseleave', function (evt) {                 sd.eventtype = evt.type;                 requestanimationframe(animate);             });         }     }); }); 

demo: jsfiddle


Comments

Popular posts from this blog

apache - Remove .php and add trailing slash in url using htaccess not loading css -

javascript - jQuery show full size image on click -