[JavaScript] [作品] 读心术系列之卡片读心术原理及Web实现 6张卡片 卡片读心术小程序
卡片读心术小程序重磅推出!支持自定义卡片并生成图片保存,向你的朋友表演!微信扫描下方小程序码立即体验!
微信小程序 QQ小程序
首先来玩一遍卡片读心术:
https://www.qwqoffice.com/thought-reader-card/
小时候在肯德基买儿童套餐的时候发现一种玩具,里面是6张写着很多数字的卡片,先让观众心里默想一个1~50的数字,然后拿着每张卡片去让测试的人回答卡片上是否有所想的数字。当6张卡片问完之后,表演者就能知道观众所想的数字。
当我知道这个玩具的神奇之处之后,我就拿着它向班里面的每个同学表演,同学们都觉得很神奇,但是并不知道其中的原理。
直到有一天,卡片找不到了,于是我想着靠自己的记忆把这套卡片复原。还好我记得表演的方法,是把观众回答“有”的卡片所代表的数字全部加起来,就是所想的数字。
首先是卡片所代表的数字。因为最后是要把卡片所代表的数字加起来,所以这些数字必须是能组合成1~50之间所有数字的一组数。组成1需要数字1,组成2需要数字2,组成3需要数字1和2,4需要4,5需要1和4,6需要2和4。以此类推,这组数字是【1、2、4、8、16、32】,6个数字刚好对应6张卡片。其实这个和Linux下文件的权限是一样的,文件权限有执行,写入,读取3种,对应数字1,2,4。如果将来还有一个新的权限,那肯定是8。以下是1到20组合所需的数字。
然后是上面这些代表数字,所有需要这些代表数的数字,比如需要1的数字有1、3、5、7、9...,需要2的数字有2、3、6、7、10、11...,假设代表数是n,不难发现,数字的规律是先从n本身开始连续n个数,然后跳过n个数,再连续n个数。如下图:
把这些数字,分别放到6张卡片当中,卡片的原理复原算是完成了,如下图。卡片中最小的数字即代表数。
接下来是Web实现。使用HTML + CSS + jQuery。
代表数,数字范围和结果的变量定义。及卡片颜色和一些用于响应式的变量定义。
JavaScript
var need = [1, 2, 4, 8, 16, 32].sort(randomsort); //组合所需数字 var total = 60; //数字范围 var result = 0; //结果 var colors = ['#009e96', '#22ac38', '#eb6100', '#eb6877', '#8957a1', '#b7aa00'].sort(randomsort); //卡片颜色 var transform, cardMargin, clickCount = 0; var cardHeight;
构造每个卡片上的数字
JavaScript
function get_nums_obj(){ var obj = []; for( i = 0; i < need.length; i++ ){ var numbers = []; var pointer = need[i]; for( j = need[i]; j <= total; j++ ){ numbers.push(j.toString()); //如果连续need[i]个数字 if( j - pointer === need[i] - 1 ){ pointer = j + need[i] + 1; //跳过need[i]个数字 j = pointer - 1; //j在下轮循环自动增长,故-1 } } obj['N'+need[i]] = numbers.sort(randomsort); } return obj; }
数组的随机排序
JavaScript
function randomsort(a, b){ //用Math.random()函数生成0~1之间的随机数与0.5比较,返回-1或1 return Math.random()>.5 ? -1 : 1; }
卡片视图的生成
JavaScript
function generate_view(){ var obj = get_nums_obj(); var count = 0; for( var item in obj ){ var index = item.substring(1); //$('#card-content .card-inner .card-inner-step').append('<div class="step card" style="background-color:'+colors[count]+';" data-num="'+index+'"></div>'); $('#card-content .card-inner .card-inner-step').append('<div class="step card" style="background-color:'+colors[count]+';"></div>'); $.each(obj[item], function(index, num){ $('#card-content .card-inner .card:last').append('<span class="card-num">'+num+'</span>'); }); count++; } }
卡片滚动动画
JavaScript
function scrollCard(){ if( clickCount >= $('#card-content .step').length - 1 ) return; $('#card-content .card-inner').css('transform', 'translateY(-'+transform+'px)'); transform += cardHeight; clickCount++; }
重置
JavaScript
function resetCard(){ clickCount = 0; result = 0; need = need.sort(randomsort); colors = colors.sort(randomsort); transform = cardHeight; $('#card-content .card-inner .card-inner-step').html(''); generate_view(); $('#card-content .card-inner').css('transform', 'translateY(0px)'); $('.action-reset').fadeOut(100, function(){ $('.action-start').fadeIn(100); }); }
卡片高度适应
JavaScript
function resizeStep(){ $('.card-wapper .step').height($('.card-wapper .card:first').height()); $('.card-wapper').height($('.card-wapper .step:first').outerHeight() + cardMargin * 2); }
初始化
JavaScript
function init(){ generate_view(); cardMargin = parseInt($('.card-wapper .card:first').css('margin-bottom').replace('px', '')); cardHeight = $('.card-wapper .card:first').outerHeight() + cardMargin * 2; transform = cardHeight; resizeStep(); $(window).resize(function(){ resizeStep(); }); //“是”“否”按钮点击 $('.action-ask button').click(function(){ //加上当前卡片数字 if( $(this).hasClass('yes') ){ //result += parseInt($('.card-inner-step .card:eq('+(clickCount-1)+')').data('num')); result += need[ clickCount-1 ]; } scrollCard(); if( clickCount >= $('#card-content .step').length - 1 ){ $('#result-num').text(result); $('.action-ask').fadeOut(100, function(){ $('.action-reset').fadeIn(100); }); } }); //开始按钮点击 $('.action-start #start').click(function(){ scrollCard(); $('.action-start').fadeOut(100, function(){ $('.action-ask').fadeIn(100); }); }); //重置按钮点击 $('.action-reset #reset').click(function(){ resetCard(); }); }
不过这种程序生成的卡片没有实体卡片的效果好,因为当用户点击“是”或“否”的时候,用程序很轻松地就能把一张卡片上的数字全部排除,容易让别人误以为是用了排除法;而实体卡片要用排除法却很难,况且在表演过程中排除数字非常容易让观众看出来。
源码下载:ThoughtReader-Card-20170527.zip
本文链接:https://www.qwqoffice.com/article.php?mod=view&tid=28