Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
OrganizationAdvent CalendarQiitadon (β)
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

iOS 9 Mobile Safari was enabled force touch event

More than 5 years have passed since last update.

iPhone 6s と force touch event

iPhone 6s から ForceTouchEvent が利用可能になりました。
機能を体感できる 簡単なお絵かきデモ を作成しました。 iPhone 6s の Safari でアクセスし、指で画面をなぞってみてください。

Demo Code


<!DOCTYPE html><html><head><title>ForceTouch Event demo</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
html, body, ul { margin: 0; padding: 0; }
canvas { margin: 2px; padding: 0; }
.touchable { outline: 1px outset gray; }
.pallet { list-style: none; }
.pallet li { display: inline }
.pallet li button { width: 40px; height: 40px; border-radius: 32px; }
<canvas class="touchable" width="370" height="480"></canvas>
<ul class="pallet">
  <li><button style="background-color:pink"  onclick="changePenColor(this)"></button></li>
  <li><button style="background-color:red"   onclick="changePenColor(this)"></button></li>
  <li><button style="background-color:blue"  onclick="changePenColor(this)"></button></li>
  <li><button style="background-color:green" onclick="changePenColor(this)"></button></li>
  <li><button style="background-color:white" onclick="changePenColor(this)"></button></li>
  <li><button style="background-color:black" onclick="changePenColor(this)"></button></li>

var ctx = null;
var pen = { x: 0, y: 0, color: "black" };

function changePenColor(target) {
  pen.color = window.getComputedStyle(target, null).backgroundColor;
  ctx.fillStyle = pen.color;
window.onload = function() {
  var node = document.querySelector("canvas");
  node.addEventListener("touchstart", handleEvent);
  node.addEventListener("touchmove", handleEvent);
  node.addEventListener("touchend", handleEvent);
  ctx = node.getContext("2d");

function handleEvent(event) {
  var type  = event.type;
  var touch = event.touches[0];
  var force = touch ? touch.force || 0.0 : 1.0;
  var x     = touch ? touch.clientX : pen.x;
  var y     = touch ? touch.clientY : pen.y;

  pen.x = x;
  pen.y = y;

  switch (type) {
  case "touchstart": drawCircle(ctx, x, y, force); break;
  case "touchmove":  drawCircle(ctx, x, y, force); break;
  case "touchend":   drawCircle(ctx, x, y, 0.0);   break;

function drawCircle(ctx, x, y, force) {
  var radius = force * 20 + 4;
  var alpha  = force * 0.4;
  alpha = alpha < 0.1 ? 0.1 : alpha;

  ctx.globalAlpha = alpha;
  ctx.arc(x, y, radius, 0, Math.PI * 2, false);



ForceTouch イベントは、touchstart/touchmove の event.touches[n].force から取得できます。force の値は 0.0〜1.0 です。

node.addEventListener("touchstart", handleEvent);
node.addEventListener("touchmove", handleEvent);

function handleEvent(event) {
  var touch = event.touches[0];
  if (touch) {
    touch.force // -> 0.0 〜 1.0

Chrome の DevTools 上でも、force と webkitForce の両方が取得できますので、iPhone 6s の実機がなくてもある程度の動作確認が可能です。
(感圧デバイスが無い場合は、force 値は常に1.0になります)


当初は、WWDC で発表された内容に従い、以下の新しいイベントを駆使してハンドリングしようとしましたが、全く動作せず…

  • webkitmouseforcecancelled
  • webkitmouseforcechanged
  • webkitmouseforceclick
  • webkitmouseforcedown
  • webkitmouseforceup
  • webkitmouseforcewillbegin

ドキュメントも色々とあたりましたが、「ルークよ… webkitmouseforcexxx を使うのだ…」といったドキュメントばかりです。謎が謎を生む展開です。

結局 WebKit のコードを確認して、正解にたどり着きました。
答えが分かってしまえばとっても簡単ですね! 参考になさってください。

(ε・ ワ ・)з May the Force be with you. (フォースと共にあらんことを)

Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away


No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
Help us understand the problem. What is going on with this article?