次の単純な js/knockout コードがあるとします。
.js (ビューモデル):
var image = ko.observable('http://placehold.it/300x150');
見る:
<img data-bind={attr: {src: image}} />
画像のプロパティが変更されたときに単純なクロスフェードを実行する ko バインディング ハンドラーを作成するにはどうすればよいですか?
次の単純な js/knockout コードがあるとします。
.js (ビューモデル):
var image = ko.observable('http://placehold.it/300x150');
見る:
<img data-bind={attr: {src: image}} />
画像のプロパティが変更されたときに単純なクロスフェードを実行する ko バインディング ハンドラーを作成するにはどうすればよいですか?
最良の解決策は、別の画像を作成してフェードインすることだと思います。
以下は、ソース オブザーバブルが更新されるたびにバインドされた要素内に新しい画像 (この場合は背景画像を持つ div) を作成し、CSS3 アニメーションでそれにフェードする単純なバインディング ハンドラーです。
ko.bindingHandlers.transitionImage = {
init: function (element, valueAccessor) {
// create a holder for the images
var holder = document.createElement('div');
holder.style['position'] = 'relative';
holder.style['height'] = '100%';
holder.style['width'] = '100%';
element.appendChild(holder);
// create initial image
var url = ko.utils.unwrapObservable(valueAccessor());
var fore = document.createElement('div');
fore.style['background-image'] = 'url(' + url + ')';
fore.style['position'] = 'absolute';
fore.style['height'] = '100%';
fore.style['width'] = '100%';
fore.style['background-size'] = '100% 100%'
holder.appendChild(fore);
},
update: function (element, valueAccessor) {
var url = ko.utils.unwrapObservable(valueAccessor());
// retrieve the holder element
var holder = element.childNodes[0];
// create new image to transition to
var fore = document.createElement('div');
fore.className = 'transition';
fore.style['background-image'] = 'url(' + url + ')';
fore.style['position'] = 'absolute';
fore.style['height'] = '100%';
fore.style['width'] = '100%';
fore.style['background-size'] = '100% 100%'
fore.style['opacity'] = '0'; // ensure it is hidden
holder.appendChild(fore);
// CSS3 animate opacity
setTimeout(function () {
fore.style['opacity'] = '1';
}, 0);
// dispose of unnecessary hidden images eventually
setTimeout(function () {
var toRemove = holder.childNodes[0];
var removed = holder.removeChild(toRemove);
delete removed;
}, 10000);
}
};
不透明度をアニメーション化するには、いくつかの css が必要です。
div.transition {
-webkit-transition: opacity 0.5s linear;
-moz-transition: opacity 0.5s linear;
-o-transition: opacity 0.5s linear;
transition: opacity 0.5s linear;
}
使用するには、それを div コンテナーにバインドします。
<div data-bind="transitionImage: image" style="width: 100px; height: 100px"></div>
このアプローチの利点は、css をいじるだけでスライドなどのより複雑なアニメーションに簡単に置き換えることができることです。