前に好きな場所に吹き出しを表示できる JavaScript というのを書いた。でも、あまり使いやすい感じではなかったので、少し改良してみた。
改良というか、似たようなものをまた書き直してみた感じです。かえっておかしなところも多い気もします。吹き出しが消せなくなっていたりとか。
前のは表示する位置を X値、Y値で指定していましたが、今度のは表示させたいエレメントでできるようにしてみました。その代わり、表示する位置の指定はそのエレメントの左上、真ん中上、右上だけになりました。
画像に id をつけておけば比較的簡単にその上に吹き出しを貼り付けることができると思います。
Sample
var elm = document.getElementById("sampleImage");
var balloon = new SpeechBalloon(elm);
balloon.paste("こんにちは", "left");
実際の吹き出しはこんな感じになります。文章を入れて、貼付けを押すと下の写真の上に吹き出しが出ます。
文字数制限は 32文字までとなっています。
ソースを一応公開してみます。変なことになっているような気もするので、また変更するかも知れません。
function SpeechBalloon(elm, id) {
this.elm = elm;
// 最大文字数
this.max = 32;
this.id = id || "SpeechBalloon";
var imgDir = "https://ablog.up.seesaa.net/balloon/";
this.balloonImage = {
"top": {
"url": imgDir + "balloon_top.gif",
"width": 164,
"height": 12
},
"middle": {
"url": imgDir + "balloon_middle.gif",
"width": 164,
"height": 4
},
"bottom": {
"url": imgDir + "balloon_bottom.gif",
"width": 164,
"height": 38
}
};
this.balloonStyle = {
"backgroundImage": "url(" + this.balloonImage.bottom.url + ")",
"backgroundRepeat": "no-repeat",
"backgroundPosition": "left bottom",
"margin": 0,
"padding": 0,
"lineHeight": "1",
"width": this.balloonImage.bottom.width + "px",
"position": "absolute"
};
this.balloonTextStyle = {
"fontSize": "12px",
"padding": "2px 10px 2px 8px",
"textAlign": "center",
"lineHeight": "1.1",
"backgroundImage": "url(" + this.balloonImage.middle.url + ")",
"backgroundRepeat": "repeat-y",
"marginBottom": this.balloonImage.bottom.height + "px"
}
}
SpeechBalloon.prototype.paste = function(text, align) {
this.setPosition(align || "left");
this.text = text.slice(0, this.max);
if (text.length > this.max) this.text += "...";
this.text = this.text.replace(/([<>&\"]|\n)/g, function ($0, $1) {
return {'<': '<', '>': '>', '&': '&', '"': '"',
'\n': '<br \/>'}[$1];
});
if (document.getElementById(this.id)) {
document.getElementById(this.id + "Text").innerHTML = this.text;
} else {
document.getElementsByTagName('body')[0].appendChild(this._makeBalloon());
}
$(this.id).style.left = this.x + "px";
$(this.id).style.top = this.y + "px";
};
/* 吹き出し */
SpeechBalloon.prototype._makeBalloon = function() {
var div = document.createElement("div");
div.setAttribute("id", this.id);
var img = document.createElement("img");
img.src = this.balloonImage.top.url;
img.width = this.balloonImage.top.width;
img.height = this.balloonImage.top.height;
img.alt = "";
div.appendChild(img);
div.appendChild(this._makeText());
var style = div.style;
for (var k in this.balloonStyle) {
style[k] = this.balloonStyle[k];
}
return div;
}
/* 吹き出しのコメント */
SpeechBalloon.prototype._makeText = function() {
var div = document.createElement("div");
div.setAttribute("id", this.id + "Text");
div.innerHTML = this.text;
var style = div.style;
for (var k in this.balloonTextStyle) {
style[k] = this.balloonTextStyle[k];
}
return div;
}
SpeechBalloon.prototype.setPosition = function(align) {
this.x = 0;
this.y = 0;
// elm の左上のX値、Y値を取得
var node = this.elm;
while (node) {
this.x += node.offsetLeft;
this.y += node.offsetTop;
node = node.offsetParent;
}
var width = this.elm.offsetWidth;
var balloonWidth = this.balloonImage.top.width;
var x = 0;
var y = 5;
({
"left": function() {
x = 5;
},
"center": function() {
x = width / 2 - balloonWidth / 2;
},
"right": function() {
x = width - balloonWidth - 5;
}
})[align]();
this.x += x;
this.y += y;
}