ã泚æ 翻蚳è ããïŒIEãä¿é²ããããã€ãã®ææ¡ãšãæããã«æãããªãã®ãèšäºããåé€ãããŸããã ç§èªèº«ã¯IEãã©ãŠã¶ã®ãµããŒã¿ãŒã§ã¯ãããŸããããŸãã以äžã§èª¬æãããã¹ãŠã®æ¹æ³ãçæ³çãšããããã§ã¯ãããŸããã ããããHTML5ã®æ©èœã®æŠèŠãšCanvasã®æ°ããã¢ããªã±ãŒã·ã§ã³ã®è©Šã¿ãšããŠããã®èšäºã¯éåžžã«èå³æ·±ããã®ã§ãã
ã³ãŒããããžã§ã¯ãã«é¢ããèšäºãžã®ãªã³ã¯
ãªãªãžãã«ãžã®ãªã³ã¯
ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®ãã¡ã³ãšããŠãHTML5 Canvasã§äœããéçºããæ©äŒãéãããšã¯ã§ããŸããã§ããã ãã®ããŒã«ã¯ãWebäžã§ç»åãããŒã¿ã衚瀺ããããã®éåžžã«å€ãã®æ°ããæ¹æ³ãæäŸããŸãã ãã®èšäºã§ã¯ããã®ãã¡ã®1ã€ã«ã€ããŠèª¬æããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®æŠèŠ
- ããŒã«
- HTML5ããŒãž
- ããŒã¿æ€çŽ¢
- å°å³ã®èªã¿èŸŒã¿ãšãã£ãã·ã¥ã®åŠç
- å°å³è¡šç€º
- ããŠã¹å¶åŸ¡
- ç¶æ ä¿å
- ã¢ãã¡ãŒã·ã§ã³
- ããŸããŸãªããã€ã¹ã§äœæ¥ãã
- ãããã«
ã¢ããªã±ãŒã·ã§ã³ã®æŠèŠ
Magic the Gathering©ãããã³ã¬ã¯ã·ã§ã³ã衚瀺ã§ããã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã ããŠã¹ã䜿çšãããšããŠãŒã¶ãŒã¯ã¹ã¯ããŒã«ãšãºãŒã ã䜿çšã§ããŸãïŒããšãã°ãBing Mapsã®å ŽåïŒã
å®æããã¢ããªã±ãŒã·ã§ã³ã¯ã bolaslenses.catuhe.comã§èŠãããšãã§ããŸãã
ãœãŒã¹ã¯ããããããŠã³ããŒãã§ããŸãïŒ www.catuhe.com/msdn/bolaslenses.zip
ãããã¯Windows Azureã¹ãã¬ãŒãžã«ä¿åãããAzure Content Distribution NetworkïŒ CDN ïŒãšã³ããŠãŒã¶ãŒã«ããŒã¿ãæäŸ/å±éãããµãŒãã¹ïŒã䜿çšããŠæ倧ã®ããã©ãŒãã³ã¹ãå®çŸããŸãã ASP.NETãµãŒãã¹ã¯ããããã®ãªã¹ããè¿ãããã«äœ¿çšãããŸãïŒ JSON圢åŒã䜿çšïŒã
ããŒã«
ã¢ããªã±ãŒã·ã§ã³ãäœæããã«ã¯ãVisual Studio 2010 SP1ãšWeb Standards Updateã䜿çšããŸã ã ãã®æ¡åŒµæ©èœã¯ãHTML5ããŒãžã®IntelliSenseãµããŒããè¿œå ããŸãïŒããã¯éåžžã«éèŠã§ãïŒã
ãœãªã¥ãŒã·ã§ã³ã«ã¯ã.jsãã¡ã€ã«ãšãšãã«HTML5ããŒãžãå«ãŸããŸãã ãããã°ã«ã€ããŠïŒVisual Studioã䜿çšãããšããã¬ãŒã¯ãã€ã³ããèšå®ããç°å¢ã§çŽæ¥æäœã§ããŸãã
Visual Studio 2010ã§ã®ãããã°
ãããã£ãŠãIntelliSenseãšãããã°ãµããŒããåããææ°ã®éçºç°å¢ããããŸãã ãããã£ãŠãéå§ããæºåãã§ããŠãããæåã«HTML5ããŒãžãäœæããŸãã
HTML5ããŒãž
ããŒãžã¯HTML5ãã£ã³ãã¹ãäžå¿ã«æ§ç¯ãããããããæç»ããããã«äœ¿çšããŸãïŒ ã³ãŒã
ããŒãžãèŠããšã2ã€ã®éšåã«åãããŠããããšãããããŸãã
- ã¿ã€ãã«ãããŽãç¹å¥ãªãªã³ã¯ã®ããèŠåºã
- ã¢ããªã±ãŒã·ã§ã³ã®ã¹ããŒã¿ã¹ã衚瀺ãããã£ã³ãã¹èŠçŽ ãšããŒã«ããããå«ãäž»èŠéšåã ãããŠããŸã ããŒããããŠããªããããã®ãœãŒã¹ãšããŠäœ¿çšãããé衚瀺ç»åïŒbackImageïŒã
ãŸããã¹ã¿ã€ã«ã·ãŒãfull.css ïŒ stylesheetãè¿œå ããŸããã ãããã£ãŠã次ã®ããŒãžãåŸãããŸããã
ã¹ã¿ã€ã«ã¯ãç¡éã®æ°ã®ãããã³ã°ãäœæã§ãã匷åãªããŒã«ã§ãã
ããã§ã€ã³ã¿ãŒãã§ã€ã¹ã®æºåãæŽãã衚瀺çšã®ãããããŒã¿ãååŸããæ¹æ³ã確èªã§ããŸãã
ããŒã¿æ€çŽ¢
ãµãŒããŒã¯ã次ã®ãªã³ã¯ã§JSON圢åŒã䜿çšããŠãããã®ãªã¹ããæäŸããŸãã
bolaslenses.catuhe.com/Home/ListOfCards/?colorString=0
URLã¯ã1ã€ã®ãã©ã¡ãŒã¿ãŒïŒcolorStringïŒã䜿çšããŠãç®çã®è²ãéžæããŸãïŒ0 =ãã¹ãŠïŒã
JavaScriptã䜿çšããŠéçºããå Žåãä»æ¥ãã§ã«ãããã®ãèŠããšããã§ãããïŒããã¯ä»ã®ããã°ã©ãã³ã°èšèªã«ãåœãŠã¯ãŸããŸãããJavaScriptã«ã¯éåžžã«éèŠã§ãïŒãæ¢åã®ãã¬ãŒã ã¯ãŒã¯ã§ãã§ã«äœæãããŠããŸããïŒ
å®éãäžçã«ã¯å€ãã®ãªãŒãã³ãœãŒã¹JavaScriptãããžã§ã¯ãããããŸãã ãã®1ã€ãjQuery㧠ãããã¯è±å¯ãªäŸ¿å©ãªæ©èœãæäŸããŸãã
ãããã£ãŠããã®å ŽåããµãŒããŒã®URLã«æ¥ç¶ããŠãããã®ãªã¹ããååŸããã«ã¯ã XmlHttpRequestã䜿çšããŠãè¿ãããJSONã®è§£æã楜ããã§ãã ããã ãŸãã¯ãjQueryã䜿çšã§ããŸãã
getJSONé¢æ°ã䜿çšããŸãããã®é¢æ°ã¯ãã¹ãŠãåŠçããŸãã
function getListOfCards() { var url = "http://bolaslenses.catuhe.com/Home/ListOfCards/?jsoncallback=?"; $.getJSON(url, { colorString: "0" }, function (data) { listOfCards = data; $("#cardsCount").text(listOfCards.length + " cards displayed"); $("#waitText").slideToggle("fast"); }); }
ã芧ã®ãšããããã®é¢æ°ã¯å€æ°listOfCardsã«ãããã®ãªã¹ããä¿åãã2ã€ã®jQueryé¢æ°ãåŒã³åºããŸãã
- text-ã¿ã°ã®ããã¹ããå€æŽããŸã
- slideToggle-é«ããã¢ãã¡ãŒã·ã§ã³åããŠã¿ã°ãé衚瀺/衚瀺ããŸã
listOfCardsãªã¹ãã«ã¯ã次ã®åœ¢åŒã®ãªããžã§ã¯ããå«ãŸããŸãã
- ID ïŒã«ãŒãID
- ãã¹ ïŒçžå¯Ÿããããã¹ïŒæ¡åŒµåãªãïŒ
ãµãŒããŒURLã¯ãïŒJsoncallback =ïŒããµãã£ãã¯ã¹ã§åŒã³åºãããããšã«æ³šæããŠãã ããã AjaxåŒã³åºãã¯ãåŒã³åºãããã¹ã¯ãªãããšåãã¢ãã¬ã¹ã«æ¥ç¶ããã»ãã¥ãªãã£ã«ãã£ãŠå¶éãããŸãã ãã ãããµãŒããŒãžã®å ±ååŒã³åºããå¯èœã«ããJSONPãšåŒã°ãããœãªã¥ãŒã·ã§ã³ããããŸãã ãããŠå¹žããªããšã«ãjQueryã¯ãã¹ãŠãåç¬ã§åŠçã§ããŸããæ£ãããµãã£ãã¯ã¹ãè¿œå ããã ãã§ãã
ã«ãŒãã®ãªã¹ããååŸãããšããã«ãç»åã®èªã¿èŸŒã¿ãšãã£ãã·ã¥ãæ§æã§ããŸãã
å°å³ã®èªã¿èŸŒã¿ãšãã£ãã·ã¥ã®åŠç
ç»é¢ã«è¡šç€ºãããŠããã«ãŒãã®ã¿ãæç»ããã¢ããªã±ãŒã·ã§ã³ã®äž»ãªããªãã¯ã 衚瀺ãŠã£ã³ããŠã¯ããºãŒã ã¬ãã«ãšã·ã¹ãã å šäœã®ã€ã³ãã³ãïŒxãyïŒã«ãã£ãŠæ±ºãŸããŸãã
var visuControl = { zoom : 0.25, offsetX : 0, offsetY : 0 };
ã·ã¹ãã å šäœã¯14,819æã®ã«ãŒãã§å®çŸ©ããã 200åãš75è¡ä»¥äžã«åæ£ãããŠããŸãã
ãŸããåã«ãŒãã«ã¯3ã€ã®ããŒãžã§ã³ãçšæãããŠããããšãç¥ã£ãŠããå¿ èŠããããŸãã
- é«è§£å床ïŒå§çž®ãªãã®480x680 ïŒæ¡åŒµå.jpgïŒ
- äžè§£å床ïŒæšæºå§çž®ã§240x340ïŒ.50.jpgãµãã£ãã¯ã¹ïŒ
- äœè§£ååºŠïŒ 120x170 ã匷åãªå§çž®ïŒ.25.jpgãµãã£ãã¯ã¹ïŒ
ãããã£ãŠããºãŒã ã¬ãã«ã«å¿ããŠããããã¯ãŒã¯ãæé©åããããã«å¿ èŠãªããŒãžã§ã³ãããŠã³ããŒãããŸãã
ãããè¡ãã«ã¯ãã«ãŒãã«å¿ èŠãªç»åãæäŸããæ©èœãéçºããŸãã ããã«ãç®çã®ã¬ãã«ã®ã«ãŒãããŸã ãµãŒããŒã«ã¢ããããŒããããŠããªãå Žåãé¢æ°ã¯ä»¥äžã®å質ã®ç»åãåç §ããŸãã
function imageCache(substr, replacementCache) { var extension = substr; var backImage = document.getElementById("backImage"); this.load = function (card) { var localCache = this; if (this[card.ID] != undefined) return; var img = new Image(); localCache[card.ID] = { image: img, isLoaded: false }; currentDownloads++; img.onload = function () { localCache[card.ID].isLoaded = true; currentDownloads--; }; img.onerror = function() { currentDownloads--; }; img.src = "http://az30809.vo.msecnd.net/" + card.Path + extension; }; this.getReplacementFromLowerCache = function (card) { if (replacementCache == undefined) return backImage; return replacementCache.getImageForCard(card); }; this.getImageForCard = function(card) { var img; if (this[card.ID] == undefined) { this.load(card); img = this.getReplacementFromLowerCache(card); } else { if (this[card.ID].isLoaded) img = this[card.ID].image; else img = this.getReplacementFromLowerCache(card); } return img; }; }
ImageCacheã¯ããµãã£ãã¯ã¹ãšç®çã®ãã£ãã·ã¥ãæäŸããŸãã
以äžã«2ã€ã®éèŠãªæ©èœã瀺ããŸãã
- load ïŒãã®é¢æ°ã¯ãç®çã®ã€ã¡ãŒãžãããŒãããŠãã£ãã·ã¥ã«ä¿åããŸãïŒ msecnd.net urlã¯Azure CDNã®ãããã®ã¢ãã¬ã¹ã§ãïŒ
- getImageForCard ïŒãã®é¢æ°ã¯ãæ¢ã«ããŠã³ããŒããããŠããããæ°ãããã®ã«ããŒããããŠããå Žåããã£ãã·ã¥ããç»åãè¿ãããã£ãã·ã¥ã«å ¥ããŸã
3ã€ã®ãã£ãã·ã¥ã¬ãã«ãåŠçããã«ã¯ã3ã€ã®å€æ°ã宣èšããŸãã
var imagesCache25 = new imageCache(".25.jpg"); var imagesCache50 = new imageCache(".50.jpg", imagesCache25); var imagesCacheFull = new imageCache(".jpg", imagesCache50);
é©åãªãã£ãã·ã¥ã®éžæã¯ããºãŒã ã«ãã£ãŠç°ãªããŸãã
function getCorrectImageCache() { if (visuControl.zoom <= 0.25) return imagesCache25; if (visuControl.zoom <= 0.8) return imagesCache50; return imagesCacheFull; }
ãŠãŒã¶ãŒããã®ãã£ãŒãããã¯ã®ããã«ãæ¢ã«èªã¿èŸŒãŸããŠããåçã®æ°ã衚瀺ããããŒã«ããããå¶åŸ¡ããã¿ã€ããŒãè¿œå ããŸãã
function updateStats() { var stats = $("#stats"); stats.html(currentDownloads + " card(s) currently downloaded."); if (currentDownloads == 0 && statsVisible) { statsVisible = false; stats.slideToggle("fast"); } else if (currentDownloads > 1 && !statsVisible) { statsVisible = true; stats.slideToggle("fast"); } } setInterval(updateStats, 200);
泚ïŒjQueryã䜿çšããŠã¢ãã¡ãŒã·ã§ã³ãç°¡çŽ åããããšããå§ãããŸãã
ããã§ã¯ãå°å³è¡šç€ºã«ç§»ããŸãããã
å°å³è¡šç€º
ããããæç»ããã«ã¯ã2Dã³ã³ããã¹ãïŒãã©ãŠã¶ãŒãHTML5ãã£ã³ãã¹ããµããŒãããŠããå Žåã«ã®ã¿ååšããŸãïŒã䜿çšããŠãã£ã³ãã¹èŠçŽ ãå¡ãã€ã¶ãå¿ èŠããããŸãã
var mainCanvas = document.getElementById("mainCanvas"); var drawingContext = mainCanvas.getContext('2d');
æç»ã¯ã processListOfCardsé¢æ°ã«ãã£ãŠå®è¡ãããŸãïŒ1ç§éã«60ååŒã³åºãããŸãïŒã
function processListOfCards() { if (listOfCards == undefined) { drawWaitMessage(); return; } mainCanvas.width = document.getElementById("center").clientWidth; mainCanvas.height = document.getElementById("center").clientHeight; totalCards = listOfCards.length; var localCardWidth = cardWidth * visuControl.zoom; var localCardHeight = cardHeight * visuControl.zoom; var effectiveTotalCardsInWidth = colsCount * localCardWidth; var rowsCount = Math.ceil(totalCards / colsCount); var effectiveTotalCardsInHeight = rowsCount * localCardHeight; initialX = (mainCanvas.width - effectiveTotalCardsInWidth) / 2.0 - localCardWidth / 2.0; initialY = (mainCanvas.height - effectiveTotalCardsInHeight) / 2.0 - localCardHeight / 2.0; // Clear clearCanvas(); // Computing of the viewing area var initialOffsetX = initialX + visuControl.offsetX * visuControl.zoom; var initialOffsetY = initialY + visuControl.offsetY * visuControl.zoom; var startX = Math.max(Math.floor(-initialOffsetX / localCardWidth) - 1, 0); var startY = Math.max(Math.floor(-initialOffsetY / localCardHeight) - 1, 0); var endX = Math.min(startX + Math.floor((mainCanvas.width - initialOffsetX - startX * localCardWidth) / localCardWidth) + 1, colsCount); var endY = Math.min(startY + Math.floor((mainCanvas.height - initialOffsetY - startY * localCardHeight) / localCardHeight) + 1, rowsCount); // Getting current cache var imageCache = getCorrectImageCache(); // Render for (var y = startY; y < endY; y++) { for (var x = startX; x < endX; x++) { var localX = x * localCardWidth + initialOffsetX; var localY = y * localCardHeight + initialOffsetY; // Clip if (localX > mainCanvas.width) continue; if (localY > mainCanvas.height) continue; if (localX + localCardWidth < 0) continue; if (localY + localCardHeight < 0) continue; var card = listOfCards[x + y * colsCount]; if (card == undefined) continue; // Get from cache var img = imageCache.getImageForCard(card); // Render try { if (img != undefined) drawingContext.drawImage(img, localX, localY, localCardWidth, localCardHeight); } catch (e) { $.grep(listOfCards, function (item) { return item.image != img; }); } } }; // Scroll bars drawScrollBars(effectiveTotalCardsInWidth, effectiveTotalCardsInHeight, initialOffsetX, initialOffsetY); // FPS computeFPS(); }
ãã®æ©èœã¯ãããã€ãã®éèŠãªãã€ã³ããäžå¿ã«æ§ç¯ãããŠããŸãã
- ãããã®ãªã¹ãããŸã ããŒããããŠããªãå ŽåãããŒãããŸã é²è¡äžã§ããããšã瀺ããã³ãã衚瀺ããŸãã
var pointCount = 0; function drawWaitMessage() { pointCount++; if (pointCount > 200) pointCount = 0; var points = ""; for (var index = 0; index < pointCount / 10; index++) points += "."; $("#waitText").html("Loading...Please wait<br>" + points); }
- ç¶ããŠã衚瀺ãŠã£ã³ããŠã®äœçœ®ãïŒããããšåº§æšã®èŠ³ç¹ããïŒæ±ºå®ãããã£ã³ãã¹ãã¯ãªã¢ããŸãã
function clearCanvas() { mainCanvas.width = document.body.clientWidth - 50; mainCanvas.height = document.body.clientHeight - 140; drawingContext.fillStyle = "rgb(0, 0, 0)"; drawingContext.fillRect(0, 0, mainCanvas.width, mainCanvas.height); }
- 次ã«ããããã®ãªã¹ãã衚瀺ããdrawImageã³ã³ããã¹ãã®canvasé¢æ°ãåŒã³åºããŸãã ç¹å®ã®ç»åã¯ã¢ã¯ãã£ããã£ãã·ã¥ã«ãã£ãŠæäŸãããŸãïŒãºãŒã ã«äŸåïŒïŒ
// Get from cache var img = imageCache.getImageForCard(card); // Render try { if (img != undefined) drawingContext.drawImage(img, localX, localY, localCardWidth, localCardHeight); } catch (e) { $.grep(listOfCards, function (item) { return item.image != img; });
- ãŸãã2次æ²ç·ã䜿çšããRoundedRectangleé¢æ°ã䜿çšããŠã¹ã¯ããŒã«ããŒãæç»ããå¿ èŠããããŸãã
function roundedRectangle(x, y, width, height, radius) { drawingContext.beginPath(); drawingContext.moveTo(x + radius, y); drawingContext.lineTo(x + width - radius, y); drawingContext.quadraticCurveTo(x + width, y, x + width, y + radius); drawingContext.lineTo(x + width, y + height - radius); drawingContext.quadraticCurveTo(x + width, y + height, x + width - radius, y + height); drawingContext.lineTo(x + radius, y + height); drawingContext.quadraticCurveTo(x, y + height, x, y + height - radius); drawingContext.lineTo(x, y + radius); drawingContext.quadraticCurveTo(x, y, x + radius, y); drawingContext.closePath(); drawingContext.stroke(); drawingContext.fill(); } function drawScrollBars(effectiveTotalCardsInWidth, effectiveTotalCardsInHeight, initialOffsetX, initialOffsetY) { drawingContext.fillStyle = "rgba(255, 255, 255, 0.6)"; drawingContext.lineWidth = 2; // Vertical var totalScrollHeight = effectiveTotalCardsInHeight + mainCanvas.height; var scaleHeight = mainCanvas.height - 20; var scrollHeight = mainCanvas.height / totalScrollHeight; var scrollStartY = (-initialOffsetY + mainCanvas.height * 0.5) / totalScrollHeight; roundedRectangle(mainCanvas.width - 8, scrollStartY * scaleHeight + 10, 5, scrollHeight * scaleHeight, 4); // Horizontal var totalScrollWidth = effectiveTotalCardsInWidth + mainCanvas.width; var scaleWidth = mainCanvas.width - 20; var scrollWidth = mainCanvas.width / totalScrollWidth; var scrollStartX = (-initialOffsetX + mainCanvas.width * 0.5) / totalScrollWidth; roundedRectangle(scrollStartX * scaleWidth + 10, mainCanvas.height - 8, scrollWidth * scaleWidth, 5, 4); }
- æåŸã«ã1ç§ãããã®ãã¬ãŒã æ°ãèšç®ããå¿ èŠããããŸãã
function computeFPS() { if (previous.length > 60) { previous.splice(0, 1); } var start = (new Date).getTime(); previous.push(start); var sum = 0; for (var id = 0; id < previous.length - 1; id++) { sum += previous[id + 1] - previous[id]; } var diff = 1000.0 / (sum / previous.length); $("#cardsCount").text(diff.toFixed() + " fps. " + listOfCards.length + " cards displayed"); }
ãããã®æç»ã¯ãäž»ã«ãã©ãŠã¶ãŒã®ãã£ã³ãã¹èŠçŽ ã®ã¬ã³ããªã³ã°ãé«éåããæ©èœã«äŸåããŠããŸãã ããšãã°ãããã¯æå°ãºãŒã ã¬ãã«ïŒ0.05ïŒã®ãã·ã³ã§ã®ããã©ãŒãã³ã¹ã§ãã
ãã©ãŠã¶
| Fps
|
Internet Explorer 9 | 30 |
Firefox 5 | 30 |
Chrome 12 | 17 |
iPadïŒãºãŒã ã¬ãã«0.8ïŒ | 7 |
Windows Phone MangoïŒãºãŒã ã¬ãã«0.8ïŒ | 20ïŒ!!ïŒ |
ãã®ãµã€ãã¯ãHTML5ããµããŒãããŠããæºåž¯é»è©±ãã¿ãã¬ããã§ãåäœããŸãã
ããã§ã¯ããã«ã¹ã¯ãªãŒã³ãããã1ç§ããã30å以äžåŠçã§ããHTML5ãã©ãŠã¶ãŒã®å éšåŒ·åºŠã確èªã§ããŸãã ããã¯ããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã§å¯èœã§ãã
ããŠã¹å¶åŸ¡
ã«ãŒãã®ã³ã¬ã¯ã·ã§ã³ãé垞衚瀺ããã«ã¯ãããŠã¹ïŒãã€ãŒã«ãå«ãïŒãå¶åŸ¡ã§ããå¿ èŠããããŸãã
ã¹ã¯ããŒã«ã«ã€ããŠã¯ãonmouvemoveãonmouseupãããã³onmousedownã€ãã³ããåŠçããã ãã§ãã
onmouseupããã³onmousedownã€ãã³ãã¯ãããŠã¹ã¯ãªãã¯ã®è¿œè·¡ã«äœ¿çšãããŸãã
var mouseDown = 0; document.body.onmousedown = function (e) { mouseDown = 1; getMousePosition(e); previousX = posx; previousY = posy; }; document.body.onmouseup = function () { mouseDown = 0; };
onmousemoveã€ãã³ãã¯canvasèŠçŽ ã«æ¥ç¶ããããã¥ãŒã移åããããã«äœ¿çšãããŸãïŒ
var previousX = 0; var previousY = 0; var posx = 0; var posy = 0; function getMousePosition(eventArgs) { var e; if (!eventArgs) e = window.event; else { e = eventArgs; } if (e.offsetX || e.offsetY) { posx = e.offsetX; posy = e.offsetY; } else if (e.clientX || e.clientY) { posx = e.clientX; posy = e.clientY; } } function onMouseMove(e) { if (!mouseDown) return; getMousePosition(e); mouseMoveFunc(posx, posy, previousX, previousY); previousX = posx; previousY = posy; }
ãã®é¢æ°ïŒonMouseMoveïŒã¯çŸåšã®äœçœ®ãèšç®ãã衚瀺ãŠã£ã³ããŠã®ã·ããã移åããå Žåã¯åã®å€ãæäŸããŸãã
function Move(posx, posy, previousX, previousY) { currentAddX = (posx - previousX) / visuControl.zoom; currentAddY = (posy - previousY) / visuControl.zoom; } MouseHelper.registerMouseMove(mainCanvas, Move);
念ã®ãããjQueryã«ã¯ããŠã¹ã€ãã³ãã管çããããã®ããŒã«ãçšæãããŠããŸãã
ãã€ãŒã«ãå¶åŸ¡ããã«ã¯ããã®å Žåãã¹ãŠç°ãªãåäœããããããåãã©ãŠã¶ãŒã«åå¥ã«é©å¿ããå¿ èŠããããŸãã
function wheel(event) { var delta = 0; if (event.wheelDelta) { delta = event.wheelDelta / 120; if (window.opera) delta = -delta; } else if (event.detail) { /** Mozilla case. */ delta = -event.detail / 3; } if (delta) { wheelFunc(delta); } if (event.preventDefault) event.preventDefault(); event.returnValue = false; }
ã€ãã³ããã°æ©èœïŒ
MouseHelper.registerWheel = function (func) { wheelFunc = func; if (window.addEventListener) window.addEventListener('DOMMouseScroll', wheel, false); window.onmousewheel = document.onmousewheel = wheel; }; // MouseHelper.registerWheel(function (delta) { currentAddZoom += delta / 500.0; });
æåŸã«ãããŠã¹ã®ç§»åäžïŒãŸãã¯ãºãŒã äžïŒã«å°ãæ £æ§ãè¿œå ããŠãæ»ãããªæèŠãäžããŸãã
// var inertia = 0.92; var currentAddX = 0; var currentAddY = 0; var currentAddZoom = 0; function doInertia() { visuControl.offsetX += currentAddX; visuControl.offsetY += currentAddY; visuControl.zoom += currentAddZoom; var effectiveTotalCardsInWidth = colsCount * cardWidth; var rowsCount = Math.ceil(totalCards / colsCount); var effectiveTotalCardsInHeight = rowsCount * cardHeight var maxOffsetX = effectiveTotalCardsInWidth / 2.0; var maxOffsetY = effectiveTotalCardsInHeight / 2.0; if (visuControl.offsetX < -maxOffsetX + cardWidth) visuControl.offsetX = -maxOffsetX + cardWidth; else if (visuControl.offsetX > maxOffsetX) visuControl.offsetX = maxOffsetX; if (visuControl.offsetY < -maxOffsetY + cardHeight) visuControl.offsetY = -maxOffsetY + cardHeight; else if (visuControl.offsetY > maxOffsetY) visuControl.offsetY = maxOffsetY; if (visuControl.zoom < 0.05) visuControl.zoom = 0.05; else if (visuControl.zoom > 1) visuControl.zoom = 1; processListOfCards(); currentAddX *= inertia; currentAddY *= inertia; currentAddZoom *= inertia; // Epsilon if (Math.abs(currentAddX) < 0.001) currentAddX = 0; if (Math.abs(currentAddY) < 0.001) currentAddY = 0; }
ãã®ãããªå°ããªæ©èœãå®è£ ããããšã¯é£ãããããŸãããããŠãŒã¶ãŒãšã®äœæ¥ã®è³ªãåäžããŸãã
ç¶æ ä¿å
ãŸãã衚瀺ããã䟿å©ã«ããããã«ã衚瀺ãŠã£ã³ããŠã®äœçœ®ãšãºãŒã ãç¶æããŸãã ãããè¡ãã«ã¯ã localStorageãµãŒãã¹ã䜿çšããŸã ãããã¯ãããŒãšå€ã®ãã¢ãé·æéä¿åãïŒãã©ãŠã¶ãŒãéããåŸã«ããŒã¿ãä¿åãããŸãïŒãçŸåšã®ãŠã£ã³ããŠãªããžã§ã¯ãã§ã®ã¿äœ¿çšã§ããŸãã
function saveConfig() { if (window.localStorage == undefined) return; // Zoom window.localStorage["zoom"] = visuControl.zoom; // Offsets window.localStorage["offsetX"] = visuControl.offsetX; window.localStorage["offsetY"] = visuControl.offsetY; } // Restore data if (window.localStorage != undefined) { var storedZoom = window.localStorage["zoom"]; if (storedZoom != undefined) visuControl.zoom = parseFloat(storedZoom); var storedoffsetX = window.localStorage["offsetX"]; if (storedoffsetX != undefined) visuControl.offsetX = parseFloat(storedoffsetX); var storedoffsetY = window.localStorage["offsetY"]; if (storedoffsetY != undefined) visuControl.offsetY = parseFloat(storedoffsetY); }
ã¢ãã¡ãŒã·ã§ã³
ã¢ããªã±ãŒã·ã§ã³ã«ãã€ãããºã ãè¿œå ããããã«ããŠãŒã¶ãŒã¯å°å³ãããã«ã¯ãªãã¯ããŠãºãŒã ããçŠç¹ãåãããããšãã§ããŸãã
ã·ã¹ãã ã¯ã2ã€ã®ã€ã³ãã³ãïŒãªãã»ããïŒXãYïŒïŒãšãºãŒã ã®3ã€ã®å€ãã¢ãã¡ãŒã·ã§ã³åããå¿ èŠããããŸãã ãããè¡ãããã«ãå€æ°ããœãŒã¹ããæå®ãããæéã§æçµå€ã«ã¢ãã¡ãŒã·ã§ã³åããæ©èœã䜿çšããŸãã
var AnimationHelper = function (root, name) { var paramName = name; this.animate = function (current, to, duration) { var offset = (to - current); var ticks = Math.floor(duration / 16); var offsetPart = offset / ticks; var ticksCount = 0; var intervalID = setInterval(function () { current += offsetPart; root[paramName] = current; ticksCount++; if (ticksCount == ticks) { clearInterval(intervalID); root[paramName] = to; } }, 16); }; };
é¢æ°ã®äœ¿çšæ³ïŒ
// var zoomAnimationHelper = new AnimationHelper(visuControl, "zoom"); var offsetXAnimationHelper = new AnimationHelper(visuControl, "offsetX"); var offsetYAnimationHelper = new AnimationHelper(visuControl, "offsetY"); var speed = 1.1 - visuControl.zoom; zoomAnimationHelper.animate(visuControl.zoom, 1.0, 1000 * speed); offsetXAnimationHelper.animate(visuControl.offsetX, targetOffsetX, 1000 * speed); offsetYAnimationHelper.animate(visuControl.offsetY, targetOffsetY, 1000 * speed);
AnimationHelperã®å©ç¹ã¯ã奜ããªã ãå€ãã®ãã©ã¡ãŒã¿ãŒãã¢ãã¡ãŒã·ã§ã³åã§ããããšã§ãã
ããŸããŸãªããã€ã¹ã§äœæ¥ãã
æåŸã«ãã¿ãã¬ãããPCãããã«ã¯æºåž¯é»è©±ã§ãããŒãžã衚瀺ã§ããããã«ããŸãã
ãããè¡ãã«ã¯ãCSS 3ïŒ The media-queries propertyã䜿çšããŸãã ãã®ãã¯ãããžãŒã䜿çšãããšãç¹å®ã®ç»é¢ãµã€ãºãªã©ãããã€ãã®èŠæ±ã«å¿ããŠã¹ã¿ã€ã«ãé©çšã§ããŸãã
<link href="Content/full.css" rel="stylesheet" type="text/css" /> <link href="Content/mobile.css" rel="stylesheet" type="text/css" media="screen and (max-width: 480px)" /> <link href="Content/mobile.css" rel="stylesheet" type="text/css" media="screen and (max-device-width: 480px)" />
ããã§ãç»é¢ã®å¹ ã480ãã¯ã»ã«æªæºã®å Žåã次ã®ã¹ã¿ã€ã«ãè¿œå ãããããšãããããŸãã
#legal { font-size: 8px; } #title { font-size: 30px !important; } #waitText { font-size: 12px; } #bolasLogo { width: 48px; height: 48px; } #pictureCell { width: 48px; }
ãã®ã¹ã¿ã€ã«ã¯ããã©ãŠã¶ã®å¹ ã480ãã¯ã»ã«æªæºã®å Žåã§ãïŒããšãã°ãWindows Phoneã®å ŽåïŒãã¿ã€ãã«ã®ãµã€ãºãçž®å°ãããµã€ãã衚瀺ãããŸãŸã«ããŸãã
ãããã«
HTML5 / CSS 3 / JavaScriptããã³Visual Studio 2010ã䜿çšãããšãããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã¬ã³ããªã³ã°ãªã©ã®åªããæ©èœãåããïŒHTML5ããµããŒããããã©ãŠã¶ãŒå ã§ïŒããŒã¿ãã«ã§å¹ççãªãœãªã¥ãŒã·ã§ã³ãéçºã§ããŸãã
ãã®ã¿ã€ãã®éçºã¯ãjQueryãªã©ã®ãã¬ãŒã ã¯ãŒã¯ã䜿çšããããšã«ããç°¡çŽ åãããŸãã
çµè«ãšããŠãç§ã¯äœãã確èªããããã«ãããèšã-ããªãã¯ãããè©ŠããŠã¿ãå¿ èŠãããïŒ