1
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

posted at

updated at

予言通りにカードを当てるマジックアプリ

クソアプリAdvent Calendarの13日目です。

Webサイトでカードマジックをする

筆者は趣味でよくカードマジックをやります。
トランプの技法を練習して、難しかったトリックができたときなんかは、
すごく達成感を感じます。

一言にカードマジックといっても、
技法を多用するものから、「セルフワーキング」といって「この通りにカードを配ると自動的にそういう現象が起こる」というものもあります。つまり、技術がなくても実施できるマジックはたくさんあるのです。

今日は、そんな技術のいらないカードマジックをわざわざWebの技術を使って再現してみました。

You Will Take a Red Card

先にプレイしたい方はここからどうぞ
デモサイト

capture 2020-12-13 19.45.39.png

あなたは、1〜6のうち好きな数字を選びます。
すると、予言どおりにあなたの選んだ数字が赤いカードを導き出します。

結論から先にいうと、提示された数字のうちどれを選んでも、
あなたは赤いカードを選んでしまうというものです。

そんなばかな・・・

と思ってやってみるとあら不思議。
必ずあなたは赤いカードを選んでしまいます。

種明かし

これは、かの有名なマジシャン「ダイ・バーノン」が考案した
「You Will Take a Red Card」(あなたは赤いカードを選ぶ)
というマジックです。

何度かプレイをしているとさすがに気づくと思うのですが、
これは選んだ数字の意味がマジシャン側(=アプリ側)によって変えられる側面を持っています。

なんの数字を選んでも「裏地が赤のカード」か「ダイヤの6」を選ばされるようになっています。

ちゃんちゃん

技術的なこと

ソースコードはここに→ Github

筆者は古き技術しか知らないエンジニアであり、最近のReactJSとかはてんでわかりません。
そのため、古代の技術「jQuery」を使って構築をしました。

CSSのアニメーション機能を使って、ひっくり返すエフェクトを使っています。

ちなみに画像の名前についている face というのは数字が書いてある方で、
back というのは裏の柄が描かれている方を指します。

    <div class="card-box">
        <div class="wrapper">
            <img src="images/back-1.png" id="no1-back" class="card active">
            <img src="images/face-4.png" id="no1-face"  class="card">
        </div>
        <div class="wrapper">
            <img src="images/face-a.png" class="card active" id="no2-back">
            <img src="images/back-2.png" class="card" id="no2-face">
        </div>
        <div class="wrapper" id="w3">
            <img src="images/back-1.png" class="card active" id="no3-back">
            <img src="images/face-6.png" class="card" id="no3-face">
        </div>
        <div class="wrapper">
            <img src="images/face-5.png" class="card active" id="no4-back">
            <img src="images/back-1.png" class="card" id="no4-face">
        </div>
        <div class="wrapper">
            <img src="images/back-1.png" class="card active" id="no5-back">
            <img src="images/face-3.png" class="card" id="no5-face">
        </div>
        <div class="wrapper">
            <img src="images/face-2.png" class="card active" id="no6-back">
            <img src="images/back-1.png" class="card" id="no6-face">
        </div>
    </div>

表のカードと裏のカードがそれぞれ card というクラスに属しており、
またその2つのカードを wrapper というdivタグで囲み、
その中でアニメーションと一緒にz-indexを入れ替えています。

base.css
.wrapper {
    display: inline-block;
    width: 200px;
    position: relative;
    -webkit-transform: rotateY(0deg);
    -ms-transform: rotateY(0deg);
    transform: rotateY(0deg);
}
.wrapper.animate {
    -webkit-transition: 0.5s linear;
    -ms-transition: 0.5s linear;
    transition: 0.5s linear;
    -webkit-transform: rotateY(90deg);
    -ms-transform: rotateY(90deg);
    transform: rotateY(90deg);
}
.wrapper.animateEnd {
    -webkit-transition: 0.5s linear;
    -ms-transition: 0.5s linear;
    transition: 0.5s linear;
    -webkit-transform: rotateY(180deg);
    -ms-transform: rotateY(180deg);
    transform: rotateY(180deg);
}
.card {
    position: absolute;
    display: inline-block;
    width: 200px;
    visibility: hidden;
    z-index: 1;
}
.card.animate {
    visibility: visible;
    z-index: 1;
}
.card.active {
    visibility: visible;
    z-index: 2;
}
.wrapper.animateEnd .card.active {
    -webkit-transform: scale(-1, 1);
    -ms-transform: scale(-1, 1);
    transform: scale(-1, 1);
}

Javascript(jQuery)の処理で、この animate のクラスを付け替えることにより、
ひっくり返るアニメーションを実現しています。
(下記の参考サイトからまんま利用させてもらっています。ありがとうございます。)

main.js
var flipCard = function(target){
    var $currentElm = $('#no' + target + '-back');
    var $targetElm = $('#no' + target + '-face');
    var parent = $currentElm.parent();

    parent.addClass("animate");
    $targetElm.addClass("animate");
    var timer = setTimeout(function() {
        $currentElm.removeClass("active").addClass("animate");
        $targetElm.removeClass("animate").addClass("active");
        parent.removeClass("animate").addClass("animateEnd");
        var timer = setTimeout(function() {
            parent.removeClass("animateEnd");
            $currentElm.removeClass("animate");
            parent.removeClass("animate");
        }, 500);
    }, 500);
    return false;
};

結論

このマジックはトランプを使ってやるから、面白いのであり、
また
【予言の書を予め封筒に入れておくなどして、相手が選んだあとに見せるから効果がある】
というのが一番見せ所であります。
オンラインのWebサイトでやったところで、なんの面白みもないですね。

トランプの画像をIllustratorで作ってるのに一番時間を費やした気がします。
この記事を見たみなさんは、ぜひ 実際のトランプで お子さんなどに実演してあげてください。

あとがき

スマホで見た時にレイアウトが崩れるので、後ほど修正します。

参考サイト

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
Sign upLogin
1
Help us understand the problem. What are the problem?