Advertisement
fruffl

cinematic bg img

Jul 1st, 2012
56
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 17.15 KB | None | 0 0
  1. cinematic : function(__SELF, SETTINGS)
  2. {
  3.     var regName = 'app-cinematic';
  4.  
  5.     /*
  6.     based on .w_10
  7.     */
  8.     var __settings = jQuery.extend
  9.     (
  10.         true,
  11.         {
  12.             bioscoop : null, // id of target
  13.             autoplay :
  14.             {
  15.                 enabled : false,
  16.                 interval : 10,
  17.                 showNext : true,
  18.                 showPlay : true,
  19.                 showPrev : true,
  20.                 showTimer : true,
  21.             },
  22.             thumbs :
  23.             {
  24.                 preloadAllBeforeShow : false,
  25.                 callBackAfterShow : function() {},
  26.                 asCssBackgroundImage : true // otherwise img-tag
  27.             },
  28.             loader :
  29.             {
  30.                 lines           : 16,
  31.                 length          : 50,
  32.                 width           : 1,
  33.                 radius          : 40,
  34.                 rotate          : 0,
  35.                 color           : '#00FF1A',
  36.                 speed           : 1.9,
  37.                 trail           : 100,
  38.                 shadow          : false,
  39.                 hwaccel         : true,
  40.                 className       : 'ddlsl',
  41.                 zIndex          : -1,//2e9,
  42.                 top             : 0,
  43.                 left            : 'auto'
  44.             }
  45.         },
  46.         SETTINGS
  47.     );
  48.  
  49.     var log =
  50.     {
  51.         n : function(t, l)
  52.         {
  53.             $.tri4m.log('tri4m.app.cinematic: ' + t, l);
  54.         },
  55.         t : function(t, l)
  56.         {
  57.             log.n('trigger: ' + t, l);
  58.         },
  59.         t107 : function(t, l)
  60.         {
  61.             log.t('preload-cinematic-thumb: ' + t, l);
  62.         },
  63.         t108 : function(t, l)
  64.         {
  65.             log.t('preload-cinematic-image: ' + t, l);
  66.         }
  67.     };
  68.  
  69.     var __instance = function(element)
  70.     {
  71.         var _queue = [],
  72.         _element = element,
  73.         _isset = $.tri4m.global.__INSTANCE_REGISTRY__.isset(element, regName),
  74.         _init, _dom, _reg = {}, _bnd = {}, _update,
  75.         _ctrl =
  76.         {
  77.             onActivation : function(scrollrollerItem)
  78.             {
  79.                 scrollrollerItem.parent().data('tri4m.ui.scrollroller.listitem.state', {ai : scrollrollerItem});
  80.                 scrollrollerItem.find('a').trigger('tri4m.app.cinematic.reslink.preloadImage');
  81.             },
  82.             pause : function()
  83.             {
  84.             },
  85.             play : function()
  86.             {
  87.             },
  88.             next : function(scrollroller)
  89.             {
  90.                 scrollroller.trigger('tri4m.ui.scrollroller.container.activateNextOrFirst', [_ctrl.onActivation]);
  91.             },
  92.             prev : function(scrollroller)
  93.             {
  94.                 scrollroller.trigger('tri4m.ui.scrollroller.container.activateNextOrFirst', [_ctrl.onActivation]);
  95.             }
  96.         };
  97.  
  98.         _c =
  99.         {
  100.             o : function(t)
  101.             {
  102.                 var p = {width: 0, height: 0};
  103.                
  104.                 if(t.innerWidth() > 0)
  105.                 {
  106.                     p.width = t.innerWidth();
  107.                 }
  108.                 else
  109.                 if(t.innerWidth() === 0 && t.parent().innerWidth() > 0)
  110.                 {
  111.                     p.width = t.parent().innerWidth();
  112.                 }
  113.                 else
  114.                 {
  115.                     p.width = $(window).width();
  116.                 }
  117.                    
  118.                
  119.                 if(t.innerHeight() > 0)
  120.                 {
  121.                     p.height = t.innerHeight();
  122.                 }
  123.                 else
  124.                 if(t.innerHeight() === 0 && t.parent().innerHeight() > 0)
  125.                 {
  126.                     p.height = t.parent().innerHeight();
  127.                 }
  128.                 else
  129.                 {
  130.                     p.height = $(window).height();
  131.                 }
  132.                    
  133.                 //p.width = (typeof t === 'undefined' || t.innerWidth() === 0) ? $(window).width() : t.innerWidth();
  134.                 //p.height = (typeof t === 'undefined' || t.innerHeight() === 0) ? $(window).height() : t.innerHeight();
  135.                 return p;
  136.             },
  137.             i : function(image, target)
  138.             {
  139.                 //alert(target.attr('class'));
  140.                 var p = {width: 0, height: 0, left: 0, top: 0};
  141.  
  142.                 if(typeof image !== 'object'
  143.                 || typeof image.width === 'undefined'
  144.                 || typeof image.height === 'undefined') return p;
  145.  
  146.                 var iw = image.width;
  147.                 var ih = image.height;
  148.                 var ir = ih / iw;
  149.  
  150.                 var w = _c.o(target);
  151.                 var ww = w.width;
  152.                 var wh = w.height;
  153.                 var wr = wh / ww;
  154.  
  155.                 switch(true)
  156.                 {
  157.                     case (wr > ir):
  158.                         p.width  = Math.round(wh/ir);
  159.                         p.height = wh;
  160.                         break;
  161.                     case (typeof $('body.fit-images').size() !== 'undefined'):
  162.                         p.width  = ww;
  163.                         p.height = wh;
  164.                         break;
  165.                     case (ir > 1 || ir === 1):
  166.                         var j = wh / ih;
  167.                         p.width  = Math.round(iw * j);
  168.                         p.height = wh;
  169.                         break;
  170.                     default:
  171.                         p.width  = ww;
  172.                         p.height = Math.round(ww * ir);
  173.                         break;
  174.                 }
  175.  
  176.                 p.left = Math.round((ww - p.width)  / 2);
  177.                 p.top  = Math.round((wh - p.height) / 2);
  178.  
  179.                 return p;
  180.             }
  181.         };
  182.  
  183.         _j =
  184.         {
  185.             isw : false,
  186.             window : function()
  187.             {
  188.                 var d = _reg.j.get('d');
  189.                 var wait = setInterval(function()
  190.                 {
  191.                     clearInterval(wait);
  192.                     _j.isw = false;
  193.                     d.find('img:visible')
  194.                     .each(function()
  195.                     {
  196.                         $(this).animate(_c.i({width : $(this).width(), height : $(this).height()}, d), 500, 'easeOutCubic');
  197.                     });
  198.                 }, 600);
  199.  
  200.                 if(true === _j.isw)
  201.                     clearInterval(wait);
  202.  
  203.                 _j.isw = true;
  204.             }
  205.         }
  206. /*
  207.  
  208. */
  209.         _update = function()
  210.         {
  211.             var j = _reg.j, __i = 'li', __a = 'a',
  212.                 ba = _bnd.a.toValueObject(), bi = _bnd.i.toValueObject(), bt = _bnd.t.toValueObject();
  213.  
  214.             j.register('a', $(__a, j.get('l')), false);
  215.             j.register('i', $(__i, j.get('l')), false);
  216.             j.get('a').addClass('tri4m-app-cinematic-resourcelink').hide();
  217.             j.get('i').addClass('tri4m-app-cinematic-resourceitem');
  218.  
  219.             var a = j.get('a'), i = j.get('i'), _a = '<a />';
  220.  
  221.             i.each(function(index)
  222.             {
  223.                 for(var i in bi) $(this).unbind(i).bind(i, bi[i]);
  224.                 var it = $(this).find(__a + '.tri4m-app-cinematic-resourcethumb').eq(0);
  225.                 if(it.length === 0)
  226.                     $(this).append($(_a).addClass('tri4m-app-cinematic-resourcethumb').hide());
  227.                    
  228.                 $(this).addClass('j.i');
  229.  
  230.             });
  231.  
  232.             j.register('t', $(__a + '.tri4m-app-cinematic-resourcethumb', j.get('i')), false);
  233.             var t = j.get('t');
  234.  
  235.             a.each(function(index)
  236.             {
  237.                 for(var i in ba) $(this).unbind(i).bind(i, ba[i]);
  238.                
  239.                 $(this).addClass('j.a');
  240.             });
  241.  
  242.             t.each(function(index)
  243.             {
  244.                 for(var i in bt) $(this).unbind(i).bind(i, bt[i]);
  245.  
  246.                 var ds = $(this).data(_reg.n.get('dts'));
  247.                 var dv = { i : index };
  248.                 if(!ds)
  249.                 {
  250.                     dv.created = false;
  251.                     $(this).data(_reg.n.get('dts'), dv).trigger('tri4m.app.cinematic.thumblink.preloadImage');
  252.                 }
  253.                 else
  254.                 {
  255.                     $(this).data(_reg.n.get('dts'), dv);
  256.                 }
  257.                
  258.                 $(this).addClass('j.t');
  259.  
  260.             });
  261.            
  262.             j.get('l').addClass('j.l');
  263.  
  264.         };
  265.  
  266.         _dom = function()
  267.         {
  268.             var j = _reg.j, _d = '<div />', _l = '<ul />', __d = 'div', __i = 'li', __a = 'a', _a = '<a />', __l = 'ul';
  269.             var d = $('#' + __settings.bioscoop).find(__d).eq(0);
  270.             var l = _element.find(__l).eq(0); // 0: cur is ul
  271.  
  272.             j.register('b', $('#' + __settings.bioscoop), true);
  273.            
  274.             j.register('d', ((d.length === 0) ? $(_d).appendTo(j.get('b')) : d), true);
  275.             j.register('l', ((l.length === 0) ? $(_element).wrap(_d) : l), true);
  276.             j.register('c', j.get('l').parent());
  277.  
  278.             j.get('l').addClass('tri4m-app-cinematic-list');
  279.             j.get('b').addClass('tri4m-app-cinematic-bioscoop');
  280.             j.get('d').addClass('tri4m-app-cinematic-decorontwerp')
  281.                 .css({overflow: 'hidden'})
  282.                 .data(_reg.n.get('dcs'), { initialized : false });
  283.             j.get('c').addClass('tri4m-ui-scrollroller-x tri4m-app-gallery-thumbs tri4m-app-cinematics')
  284.             //j.get('c').addClass('tri4m-ui-scrollroller-x tri4m-app-cinematics')
  285.                 .tri4m().proto().ui().scrollroller
  286.                 ({
  287.                     sensitive: true,
  288.                     easing :
  289.                     {
  290.                         duration : 400,
  291.                         callback :
  292.                         {
  293.                             item :
  294.                             {
  295.                                 deactivate : function(e)
  296.                                 {
  297.                                     $(this).trigger('tri4m.ui.scrollroller.container.activateFirst');
  298.                                 }
  299.                             }
  300.                         }
  301.                     }
  302.                 });
  303.  
  304.         };
  305.  
  306.         (function()
  307.         {
  308.             if(true === _isset) return;
  309.             _reg.j = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  310.             _reg.n = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  311.             _bnd.a = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  312.             _bnd.t = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  313.             _bnd.i = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  314.             _bnd.l = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  315.             _bnd.r = new $.tri4m.global.__CLASS__.__VARIABLE__.__REGISTRY__();
  316.  
  317.             _reg.n.register('dcs', 'tri4m.app.cinematic.state');
  318.             _reg.n.register('dts', 'tri4m.app.cinematic.thumbstate');
  319.  
  320.             _bnd.i.register('click', function()
  321.             {
  322.                 $(this).trigger('tri4m.ui.scrollroller.listitem.activate', [_ctrl.onActivation]);
  323.             });
  324.            
  325.             _bnd.l.register('tri4m.app.cinematic.container.insertItemAfter', function(e, i, c)
  326.             {
  327.             }, true)
  328.             .register('tri4m.app.cinematic.insertItemBefore', function(e, i, c)
  329.             {
  330.             }, true)
  331.             .register('tri4m.app.cinematic.appendItem', function(e, i, item, c)
  332.             {
  333.                 alert('insert cinematic');
  334.             }, true)
  335.             .register('tri4m.app.cinematic.appendItems', function(e, i, itemArray, c)
  336.             {
  337.             }, true)
  338.             .register('tri4m.app.cinematic.prependItem', function(e, i, item, c)
  339.             {
  340.             }, true)
  341.             .register('tri4m.app.cinematic.prependItems', function(e, i, itemArray, c)
  342.             {
  343.             }, true);
  344.  
  345.             _bnd.t.register('tri4m.app.cinematic.thumblink.preloadImage', function(e)
  346.             {
  347.                 if(typeof ILLI === 'undefined')
  348.                 {
  349.                     $(this).parent().prepend('<span>where is ILLI?</span>');
  350.                     log.t107('ILLI is undefined (required for thumb-url)', 2);
  351.                     return;
  352.                 }
  353.  
  354.  
  355.                 var t = $(this), p = t.parent().css({opacity : 0}),
  356.                     i = t.data(_reg.n.get('dts')).i, href = $('a.tri4m-app-cinematic-resourcelink', p).attr('href');
  357.  
  358.                 log.t107('init ' + i);
  359.  
  360.                 if(typeof _queue[i] !== 'undefined' && _queue[i].status === true)
  361.                 {
  362.                     log.t107('-- nothing to do ' + i);
  363.                     return;
  364.                 }
  365.  
  366.                 log.t107('push to queue ' + i);
  367.  
  368.                 _queue[i] =
  369.                 {
  370.                     status    : false,
  371.                     error     : false,
  372.                     append    : false,
  373.                     kicked    : false,
  374.                     lookup    : null,
  375.                     islooking : false,
  376.                     attempt   : 0,
  377.                     thumb     : t,
  378.                     parent    : p,
  379.                     src       : null,
  380.                     image     : $('<img />').addClass('tri4m-app-cinematic-thumbnail').css({opacity : 0})
  381.                 };
  382.  
  383.                 var islast = (_queue.length === _reg.j.get('t').length);
  384.  
  385.                 if(true === islast) log.t107('is last ' + i);
  386.  
  387.                 var dequeue = function()
  388.                 {
  389.                     log.t107('try dequeue: caller is ' + i);
  390.                     if(true === __settings.thumbs.preloadAllBeforeShow)
  391.                     {
  392.                         if(false === islast)
  393.                             return;
  394.  
  395.                         log.t107('try dequeue: preloadAllBeforeShow = true');
  396.  
  397.                         var success = true;
  398.                         for(var idx in _queue)
  399.                             if(_queue[idx].status === false)
  400.                                 success = false;
  401.  
  402.                         if(false === success)
  403.                         {
  404.                             log.t107('try dequeue: success = false');
  405.                             var refetch = setInterval(function()
  406.                             {
  407.                                 clearInterval(refetch);
  408.  
  409.                                 log.t107('try again');
  410.                                 dequeue();
  411.                             }, 50);
  412.  
  413.                             return;
  414.                         }
  415.                     }
  416.  
  417.                     log.t107('try dequeue: start iteration');
  418.                     for(var idx in _queue)
  419.                     {
  420.                         if(true === _queue[idx].error)
  421.                         {
  422.                             log.t107('try dequeue: error: ' + src, 3);
  423.                             log.t107('try dequeue: --continue');
  424.                             continue;
  425.                         }
  426.  
  427.                         (function(curIndex, caller)
  428.                         {
  429.                             var islast = (_queue.length === _queue[curIndex + 1]);
  430.                            
  431.                             if(null !== _queue[curIndex].lookup)
  432.                                 return;
  433.                            
  434.                             _queue[curIndex].lookup = setInterval(function()
  435.                             {
  436.                                 //log.t107('try dequeue: auto-init ' + x);
  437.                                
  438.                                 if(true === _queue[curIndex].kicked)
  439.                                 {
  440.                                     log.t107('try dequeue: waiting: -- -- index ' + curIndex + ' already kicked');
  441.                                     clearInterval(_queue[curIndex].lookup);
  442.                                     return;
  443.                                 }
  444.                                
  445.                                 if(false === __settings.thumbs.preloadAllBeforeShow
  446.                                 && _queue[curIndex].status === false)
  447.                                 {
  448.                                     log.t107('try dequeue: waiting: preloadAllBeforeShow = false, status = '+ _queue[curIndex].status +', try = ' + _queue[curIndex].attempt + ' of ' + _queue.length + ', index = ' + curIndex + ', caller = ' + caller);
  449.  
  450.                                     if(_queue[curIndex].attempt > _queue.length || _queue[curIndex].attempt === _queue.length)
  451.                                     {
  452.                                         log.t107('try dequeue: waiting: -- preloadAllBeforeShow = false, status = '+ _queue[curIndex].status +', max.attempts = '+_queue.length+', index = ' + curIndex + ', caller = ' + caller);
  453.                                         log.t107('try dequeue: waiting: -- index ' + curIndex + ' was kicked from #list (idle flood), caller = ' + caller + ' in try = ' + _queue[curIndex].attempt + ' of ' + _queue.length);
  454.                                         _queue[curIndex].kicked = true;
  455.                                         clearInterval(_queue[curIndex].lookup);
  456.                                     }
  457.                                     _queue[curIndex].attempt++;
  458.  
  459.                                     return;
  460.                                 }
  461.  
  462.                                 clearInterval(_queue[curIndex].lookup);
  463.                                
  464.                                 if(true === _queue[curIndex].append)
  465.                                     return;
  466.  
  467.                                 if(true === __settings.thumbs.asCssBackgroundImage)
  468.                                 {
  469.                                     log.t107('try dequeue: asCssBackgroundImage = true ' + curIndex);
  470.                                     _queue[curIndex].parent.css({'background-image' : 'url("' + _queue[curIndex].src + '")'});
  471.                                     _queue[curIndex].parent.animate({opacity : 1}, 500);
  472.                                 }
  473.                                 else
  474.                                 {
  475.                                     log.t107('try dequeue: asCssBackgroundImage = false ' + curIndex);
  476.                                     _queue[curIndex].parent.prepend(_queue[curIndex].image);
  477.                                     _queue[curIndex].image.animate({opacity : 1}, 500);
  478.                                 }
  479.                                
  480.                                 _queue[curIndex].append = true;
  481.  
  482.  
  483.                                 //if(islast === true) __settings.thumbs.callBackAfterShow();
  484.  
  485.                             }, curIndex * 500); // every thumber will check every 500ms the full thumb queue!
  486.                         })(idx, i);
  487.                     }
  488.                 }
  489.  
  490.                 var load = function(src)
  491.                 {
  492.                     log.t107('try load: ' + src);
  493.                     var IMG = new Image();
  494.                     $(IMG)
  495.                     .addClass('dummy')
  496.                     .hide()
  497.                     .load(function()
  498.                     {
  499.                         log.t107('try load: complete: ' + src);
  500.                         $(IMG).remove();
  501.                         t.wait = setInterval(function()
  502.                         {
  503.                             clearInterval(t.wait);
  504.                             log.t107('try load: append: ' + src);
  505.                             _queue[i].image.attr('src', src);
  506.                             _queue[i].src = src;
  507.                             _queue[i].status = true;
  508.                             dequeue();
  509.  
  510.                         }, 100);
  511.  
  512.                         IMG.onload = function(){};
  513.                     })
  514.                     .error(function()
  515.                     {
  516.                         log.t107('try load: error: ' + src, 3);
  517.                         _queue[i].image.attr('src', src);
  518.                         _queue[i].src = src;
  519.                         _queue[i].status = true;
  520.                         _queue[i].error = true;
  521.                         dequeue();
  522.                         IMG.onerror = function(){};
  523.                     });
  524.  
  525.                     $(IMG).attr('src', src);
  526.                     t.append(IMG);
  527.                 };
  528.  
  529.                 t.idle = setInterval(function()
  530.                 {
  531.                     clearInterval(t.idle);
  532.                     log.t107('try get thumb for ' + i + ': ' + href);
  533.                     // create thumb url from img-a-href
  534.                    
  535.                     ILLI.router.create.thumb(href, p.height(), p.width(), function(url)
  536.                     {
  537.                         log.t107('thumb for ' + i + ' is ' + url);
  538.                         t.attr('href', url);
  539.                         load(url);
  540.  
  541.                     });
  542.                 }, 50);
  543.             });
  544.  
  545.             _bnd.a.register('tri4m.app.cinematic.reslink.preloadImage', function()
  546.             {
  547.                 var src  = $(this).attr('href');
  548.                 log.t108('init ' + src);
  549.                 /*
  550.                 if(_reg.j.get('d').children('div.hidden').length === 0)
  551.                 {
  552.                     var hidden = $('<div />').hide().addClass('hidden');
  553.                     _reg.j.get('d').prepend(hidden);
  554.                 }
  555.                 */
  556.                 var load = function()
  557.                 {
  558.                     log.t108('try load: ' + src);
  559.                     if(_reg.j.get('d').children('img' + "[src='" + src + "']").length === 0)
  560.                     {
  561.                         log.t108('try load: unknown source ' + src);
  562.                         var img = $('<img />').css({position: 'absolute'}).addClass('tri4m-app-cinematic-image').css('position', 'absolute');
  563.  
  564.                         var IMG = new Image();
  565.                         $(IMG)
  566.                         .hide()
  567.                         .load(function()
  568.                         {
  569.                             log.t108('try load: complete: ' + src);
  570.                             var css = _c.i(IMG, _reg.j.get('d'));
  571.                             $(IMG).remove();
  572.                             var wait = setInterval(function()
  573.                             {
  574.                                 clearInterval(wait);
  575.                                 log.t108('try load: append: ' + src);
  576.                                 _reg.j.get('d').prepend(img.attr('src', src).css(css));
  577.                                 _reg.j.get('d').animate({opacity : 1}, 500);
  578.                             }, 100);
  579.  
  580.                             IMG.onload = function(){};
  581.                         })
  582.                         .error(function()
  583.                         {
  584.                             log.t108('try load: error: ' + src, 3);
  585.                             IMG.onerror = function(){};
  586.                         });
  587.  
  588.                         $(IMG).attr('src', src);
  589.                         _reg.j.get('d').html(IMG);
  590.  
  591.                     }
  592.                     else
  593.                     {
  594.                         log.t108('try load: known source ' + src);
  595.                         var img = _reg.j.get('d').children('img' + "[src='" + src + "']");
  596.                         img.show();
  597.                         _reg.j.get('d').animate({opacity : 1}, 500);
  598.                     }
  599.                 };
  600.  
  601.                 if(_reg.j.get('d').children('img').length === 0)
  602.                 {
  603.                     log.t108('try load: bioscoop has no images -- construct squence');
  604.                     _reg.j.get('d').css({opacity : 0});
  605.                     load();
  606.                 }
  607.                 else
  608.                 {
  609.                     log.t108('try load: bioscoop has images -- destruct-construct squence');
  610.                     _reg.j.get('d').stop().animate({opacity : 0}, 500, function()
  611.                     {
  612.                         $('img', _reg.j.get('d')).remove();
  613.                         load();
  614.                     });
  615.                 }
  616.  
  617.  
  618.             }, true);
  619.  
  620.             _bnd.r.register('resize.resolutionchange', _j.window, true);
  621.            
  622.             var foo = false;
  623.             __settings.thumbs.callBackAfterShow = function()
  624.             {
  625.                 if(true === foo) return;
  626.                 foo = true;
  627.                 _update();
  628.             };
  629.             _dom();
  630.             _update();
  631.  
  632.             var br = _bnd.r.toValueObject(), bl = _bnd.l.toValueObject();
  633.             for(var i in br) { $(window).bind(i, br[i]); }
  634.             for(var i in bl) { _reg.j.get('l').unbind(i).bind(i, bl[i]); }
  635.            
  636.             _reg.j.get('l').trigger('insert-item');
  637.            
  638.             if(__settings.bioscoop === null)
  639.             {
  640.                 __settings.bioscoop = 'target';
  641.                 $('body').prepend('<div id="'+ __settings.bioscoop +'"/>');
  642.             }
  643.             _update();
  644.         })();
  645.     };
  646.  
  647.     $.tri4m.log('initialize tri4m.app.cinematic: tri4m LABS', 1);
  648.     var instance = new __instance(__SELF);
  649.     $.tri4m.global.__INSTANCE_REGISTRY__.register(__SELF, regName, instance);
  650. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement