LINE

今日

友人

LINE風トーク画面メーカー

アイコン画像アップロード編集
→上部のアイコンをタップ

文章編集
→ふきだしをタップ

時間編集
→時間をタップ

スクショ画像ダウンロード
→画面外下のボタンをクリック

電話 不在着信

「LINE」とは

コミュニケーションアプリ「LINE」 は、無料で友だちや家族と、トーク(チャット)・音声通話・ビデオ通話を楽しめます。

LINE FONT

view source

JavaScript

document.title = 'LINE風トーク画面メーカー';


var getNNSS = function(){
  var date = new Date();
  var hh = ('00' + date.getHours()).slice(-2);
  var nn = ('00' + date.getMinutes()).slice(-2);
  var hhnn = hh + ':' + nn;
  var result = hhnn;
  return result;
}
var getMMDDWW = function(){
  var date = new Date();
  var mm = date.getMonth()+1;
  var dd = date.getDate();
  var w = date.getDay();
  var wText = '(' + '日月火水木金土'[w] + ')';
  var mmddww = mm + '/' + dd + ' ' + wText;
  var result = mmddww;
  return result;
}

$(function(){
  $input = $('input[type="text"]');
  $('time').text(getNNSS());

  function comment(t){
    if(!t){return false;}
    var target = $('input[name="target"]:checked').val();
    $input.val('');
    $talk = $('<div>').addClass('talk');
    $bal = $('<div>').addClass('baloon');

    $balTip = $('<img>',{src:'line-p.png'}).addClass('baloon-tip');
    $balIn = $('<div>').addClass('baloon-in');
    $p = $('<p>',{contentEditable:'true'}).text(t);
    if(t.match(/img:/)){
      src = t.replace(/img:/,'');
      $p = $('<img>',{src:src});
    }
    $time = $('<time>',{contentEditable:'true'}).text(getNNSS());
    $close = $('<i>').addClass('close');
    $talk.append($bal);
    $bal.append($balIn);
    $balIn.append($balTip);
    $balIn.append($p);
    $balIn.append($time);
    $balIn.append($close);
    if(target==='me'){
      $talk.addClass('me');
      $balTip.attr({src:'line-p-me.png'});
    } else {
      $img = $('img.icon').eq(0).clone();
      $bal.append($img);
    }
    console.log(t);
    $('.line').append($talk);
  }

  function addDate(t='今日'){
    $talk = $('<div>').addClass('talk').addClass('date');
    $p = $('<p>',{contentEditable:'true'}).text(t);
    $close = $('<i>').addClass('close');
    $talk.append($p);
    $talk.append($close);
    $('.line').append($talk);
  }

  $input.parent().on('submit', function(){
    var t = $input.val();
    comment(t);
    return false;
  });


  $('.mmddww').text(getMMDDWW());

  $('.line-head').on('dblclick', function(){
    $(this).remove();
    $('.line-head-title').remove();
  });
  $('#tel').on('click', function(){
    comment('tel');
  });
  $(document).on('click', '.close', function(){
    $(this).closest('.talk').remove()
  });
  $(document).on('dblclick', 'time', function(){
    var text = $(this).text();
    if(text.match(/既読/)){
      text = text.replace('既読','');
      $(this).text(text);
    } else {
      $(this).empty();
      $(this).append('既読');
      $(this).append('<br>');
      $(this).append(text);
    }
  });
  $(document).on('click', '.icons img', function(){
    var src = $(this).attr('src');
    $('.line img.icon').each(function(){
      $(this)[0].src = src;
    })
  });
  $(document).on('click', '.tel img', function(){
    var src = $(this).attr('src');
    comment('img:'+src);
  });
  $(document).on('click', '.addDate p', function(){
    var text = $(this).text();
    addDate(text);
  });
  $(document).on('click', '.toggleInvert', function(){
    $('.line').toggleClass('invert');
    invertImage($('.line-head')[0]);
  });
});



$(function(){
  $('.iconUpload').on('change', function(e){
    var event = e.originalEvent;
    console.log(event);
    var file = event.target.files[0];
    if (!file.type.match('image.*')){
        return;
    }
    console.log(file);
    var reader = new FileReader();
    reader.onload = function(){
      var dataURL = reader.result;
      console.log(dataURL);

      var newImage = new Image();
      newImage.src = dataURL;
      newImage.onload = function(){
        $('.line img.icon').each(function(){
          $(this)[0].src = newImage.src;
        })
      }
    }
    reader.readAsDataURL(file);
  });
});



$(function(){
  $('.bgUpload').on('change', function(e){
    var event = e.originalEvent;
    console.log(event);
    var file = event.target.files[0];
    if (!file.type.match('image.*')){
        return;
    }
    console.log(file);
    var reader = new FileReader();
    reader.onload = function(){
      var dataURL = reader.result;
      console.log(dataURL);

      var newImage = new Image();
      newImage.src = dataURL;
      newImage.onload = function(){
        var background = 'url(' + newImage.src + ')';
        $('.line').each(function(){
          $(this).css({backgroundImage:background});
        })
      }
    }
    reader.readAsDataURL(file);
  });
});


function invertImage(ele){
  var canvas = document.createElement('canvas');
  var ctx = canvas.getContext('2d');

  var img = new Image();
  img.src = ele.src;
  img.onload = function() {
    canvas.width = img.width;
    canvas.height = img.height;
    ctx.drawImage(img, 0, 0);
    var src = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var dst = ctx.createImageData(canvas.width, canvas.height);

    for (var i = 0; i < src.data.length; i=i+4) {
        dst.data[i]   = 255 - src.data[i];    //R
        dst.data[i+1] = 255 - src.data[i+1];  //G
        dst.data[i+2] = 255 - src.data[i+2];  //B
        dst.data[i+3] = src.data[i+3];        //A
    }

    ctx.putImageData(dst, 0, 0);
    const dataURL = canvas.toDataURL();
    const newImage = new Image();
    ele.src = dataURL;
    ele.onload = function(){
    }
  };
}


$(function(){

  function stampUpload(src){
    $talk = $('<div>').addClass('talk');
    $imgWrap = $('<div>').addClass('stampWrap');
    $img = $('<img>',{src:src}).addClass('stamp');
    $time = $('<time>',{contentEditable:'true'}).text(getNNSS());
    $close = $('<i>').addClass('close');
    $imgWrap.append($img);
    $imgWrap.append($time);
    $imgWrap.append($close);
    $talk.append($imgWrap);
    var target = $('input[name="target"]:checked').val();
    if(target==='me'){
      $talk.addClass('me');
    }
    $('.line').append($talk);
  }
  
  //$('.stampUpload')[0].addEventListener('change', function(event){
  $('.stampUpload').on('change', function(e){
    var event = e.originalEvent;
    var file = event.target.files[0];
    if (!file.type.match('image.*')){
        return;
    }
    console.log(file);
    var reader = new FileReader();
    reader.onload = function(){
      var dataURL = reader.result;
      console.log(dataURL);

      var newImage = new Image();
      newImage.src = dataURL;
      newImage.onload = function(){
        stampUpload(newImage.src);
      }
    }
    reader.readAsDataURL(file);
  });
});



$(function(){
  $('#toImg').on('click', function(){
    html2canvas(document.querySelector("#target")).then(canvas => {
      console.log(canvas);
      document.querySelector("#screenshot").textContent = '';
      document.querySelector("#screenshot").appendChild(canvas)
    });
  });
  $(document).on('click', '#screenshot canvas', function(){
    var canvas = $(this);
    var data = canvas[0].toDataURL('image/png');
    var name = $('<name>').eq(0).text();
    var a = $('<a>', {href:data,download:'line-talk-'+name});
    a[0].click();
  });
});

CSS

body{
}

@font-face {
	font-family: LINE;
	src: url(/fonts/LINESeedJP_OTF_Rg.woff);
}
#demo{
  position:relative;
  left:0;
  top:0;
  max-width:480px;
  width:100%;
  margin:0 auto;
	font-family: LINE;
}
#demo img{
}

.line{
  position:relative;
  left:0;
  top:0;
  background-color:#7D9DC7;
  /*padding-top:32px;*/
  padding-bottom:12px;
  background-image:url(line-bg.png);
  background-size:100%;
}
.line-head{
  width:100%;
}
.line-head-title{
  width:100%;
  position:absolute;
  left:64px;
  top:0;
  line-height:64px;
  font-weight:bold;
  font-size:18px;
}


.talk{
  position:relative;
  left:0;
  top:0;
  padding-top:8px;
  padding-left:64px;
}
.talk.me{
  text-align:right;
}

.baloon{
  position:relative;
  left:0;
  top:0;
/*
//ふきだし口を背景にするとcanvas時に白い境界線が見える
  background-color:#7D9DC7;
  background-image:url(line-p.png);
  background-position:0 0px;
  background-repeat:no-repeat;
*/
  margin:4px;
}
.me .baloon{
/*
  background-image:url(line-p-me.png);
  background-position:100% 0px;
*/
}
.talk .baloon-tip{
  position:absolute;
  left:-8px;
  top:0;
}
.talk.me .baloon-tip{
  position:absolute;
  left:auto;
  right:-8px;
  top:0;
}
.talk .baloon-in{
  position:relative;
  left:0;
  top:0;
  display:inline-block;
  text-align:left;
  background-color:#ffffff;
  border-radius:24px;
  min-width:20px;
  padding:18px;
  margin:0 16px;
}
.talk .baloon-in p{
  font-size:18px;
}
.me .baloon-in{
  background-color:#9BE061;/*#84E34B*/
}

.talk img.icon{
  position:absolute;
  left:-64px;
  top:0px;
  width:64px;
  border-radius:50%;
}
.talk name{
  position:absolute;
  left:0px;
  top:-20px;
  color:#fff;
  font-size:14px;
  display:none;
}

.talk time{
  position:absolute;
  right:-48px;
  bottom:0;
  color:#fff;
  font-size:13px;
  font-weight:normal;
  line-height:1.4em;
  color:#000000;
  opacity:0.6;
}
.talk .close{
  position:absolute;
  right:-54px;
  bottom:30px;
  background-image:url(/img/svg/x.svg);
  width:5px;
  height:5px;
  cursor:pointer;
  display:none;
}

.me .close{
  right:0;
  left:-64px;
}

.talk:hover .close{
  display:block;
}

.talk .stampWrap{
  position:relative;
  left:0;
  top:0px;
  display:inline-block;
  margin:0 16px;
}

.talk img.stamp{
  max-width:240px;
  max-height:240px;
}

.me time{
  right:0;
  left:-48px;
  text-align:left;
}


.talk.date{
  padding:16px 0;
  line-height:16px;
  width:100%;
  text-align:center;
}

.talk.date p{
  display:inline-block;
  background-color:#7C90B4;
  color:#fff;
  padding:4px 16px;
  border-radius:16px;
  margin:0 auto;
  font-size:14px;
}
.talk.date .close{
  left:40%;
}

.line.invert time,
.line.invert .line-head-title{
  /*mix-blend-mode: difference;*/
  /*filer:Invert();*/
  color:#ffffff;
}


label{
  cursor:pointer;
}
input[type="text"]{
  display:block;
  width:100%;
  padding:12px;
  box-sizing:border-box;
}
input[type="file"]{
  display:none;
}
.btn{
  display:block;
  border:1px solid #000;
  border-radius:24px;
  padding:24px;
  margin:2px auto;
  text-align:center;
}

form,
#other{
  display:block;
  width:100%;
  max-width:480px;
  margin:0 auto;
  margin-top:20px;
  text-align:center;
}
#other label{
  display:block;
}

#screenshot{
  min-height:20vh;
  background-color:#000;
}
button{
  padding:24px;
  font-size:24px;
}
.tel,
.icons{
  display:flex;
}
.icons img{
  width:40px;
}


#code{
  display:none;
}

HTML

ページのソースを表示 : Ctrl+U , DevTools : F12

view-source:https://hi0a.com/demo/-js/js-talk-line/

ABOUT

hi0a.com 「ひまアプリ」は無料で遊べるミニゲームや便利ツールを公開しています。

プログラミング言語の動作デモやWEBデザイン、ソースコード、フロントエンド等の開発者のための技術を公開しています。

必要な機能の関数をコピペ利用したり勉強に活用できます。

プログラムの動作サンプル結果は画面上部に出力表示されています。

環境:最新のブラウザ GoogleChrome / Windows / Android / iPhone 等の端末で動作確認しています。

画像素材や音素材は半分自作でフリー素材配布サイトも利用しています。LINK参照。

動く便利なものが好きなだけで技術自体に興味はないのでコードは汚いです。

途中放置や実験状態、仕様変更、API廃止等で動かないページもあります。