Skip to content

Instantly share code, notes, and snippets.

@mach3
Created August 10, 2013 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mach3/6201442 to your computer and use it in GitHub Desktop.
Save mach3/6201442 to your computer and use it in GitHub Desktop.
IMG要素を元にVMLで画像表示するだけ。属性・スタイル変更やイベントにも対応。
(function($, doc){
/**
* vmlImage
* --------
*/
var vmlImage = {
/**
* Attributes:
* - init:Boolean = Namespace has been initialized or not
* - className:String = CSS class name to render VML
* - props:Object = Style property names to be applied to vml element
* - handlers:Object = Event names to be applied to vml element
* - ignores:Object = Property name to be ignored on propertychange event
*/
attrs: {
init: false,
className: "vml-element",
props: ["position", "margin", "left", "top", "right", "bottom"],
handlers: ["mouseenter", "mouseleave", "mouseover", "mouseout", "click"],
ignores: ["style.zoom", "style.display"]
},
/**
* Getter for attrs
* @param String key
* @return Mixed
*/
get: function(key){
return this.attrs[key];
},
/**
* Setter for attrs
* @param String key
* @param Mixed value
*/
set: function(key, value){
this.attrs[key] = value;
},
/**
* Initialize vml element by HTMLImageElement
* @param HTMLImageElement ele
* @param jQueryObject vml
*/
init: function(ele){
var my, node, vml, styles;
this.initDocument();
my = this;
node = $(ele);
styles = {};
// styles
$.each(this.get("props"), function(i, name){
styles[name] = node.css(name);
});
// create vml node
vml = this.createImage(
node.prop("src"),
node.width(),
node.height(),
styles
).insertBefore(node.hide());
// set data
vml.data("origin", node);
node.data("vml", vml);
// events
$.each(this.get("handlers"), function(i, name){
vml.on(name, my.onEvents);
});
ele.attachEvent("onpropertychange", $.proxy(this.onPropertyChange, this));
return vml;
},
/**
* Create image element with vml
* @param String src
* @param Integer width
* @param Integer height
* @param Object styles
*/
createImage: function(src, width, height, styles){
var rect, fill;
rect = this.createNode("rect")
.css({
width: width,
height: height
})
.attr("stroked", false);
$.each(styles, function(key, value){
rect.css(key, value);
});
fill = this.createNode("fill")
.attr({
src: src,
type: "frame"
})
.appendTo(rect);
return rect;
},
/**
* Add vml namespace on document if not initialized
*/
initDocument: function(){
if(! this.get("init")){
doc.namespaces.add("vml", "urn:schemas-microsoft-com:vml");
doc.createStyleSheet().cssText = "." + this.get("className")
+ "{ behavior: url(#default#VML); display: inline-block; }";
this.set("init", true);
}
},
/**
* Create vml node by name
* @param String name
*/
createNode: function(name){
return $(doc.createElement("vml:" + name))
.addClass(this.get("className"));
},
/**
* Event handler for vml element
* This trigger origin image element's event
*/
onEvents: function(e){
$(this).data("origin").trigger(e.type);
},
/**
* Handler for propertychange for origin image element
* This applies changes to vml element
*/
onPropertyChange: function(e){
var origin, vml, name, value;
origin = $(e.srcElement);
vml = origin.data("vml");
name = e.propertyName;
if($.inArray(name, this.get("ignores")) < 0){
if(name === "src"){
vml.find("fill").prop("src", origin.prop("src"));
return;
}
if(/^style\./.test(name)){
name = name.split(".")[1];
value = origin.css(name);
if(/opacity/.test(value)){
value = parseInt(value.match(/\d+/)[0], 10) / 100;
vml.css("opacity", value);
} else {
vml.css(name, value);
}
}
}
}
};
/**
* Interface to initialize vmlImage
*/
$.fn.vmlImage = function(){
if(! $.support.opacity){
this.each(function(){
if(this.nodeName === "IMG"){
vmlImage.init(this);
}
});
}
return this;
};
}(jQuery, document));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment