HTML5 jisaw益智游戏瓷砖的大小

时间:2015-08-04 05:21:39

标签: javascript html html5

我正在http://www.codeproject.com/Articles/395453/Html-Jigsaw-Puzzle处查看示例代码。它使用的是paper.js,它使用text / paperscript作为脚本标记。

我正在尝试更改瓷砖的尺寸,但不是运气。如果我更改了tileWidth,则图块大小已更改但图像不适合该块!背景为空的部分区域为例:http://mifi.lt/a/4/

<!DOCTYPE html>
<html>
<head>
    <title>HTML5 Puzzle</title>
    <meta property="og:title" content="Html5 Jigsaw Puzzle">
    <meta property="og:image" content="http://dl.dropbox.com/u/5728198/html5puzzle/content/images/puzzle.jpg">
    <meta property="og:description" content="An online jigsaw puzzle by Marcelo Ricardo de Oliveira using the stunning features of the Paper JS framework">
    <link href="content/Puzzle.css" rel="stylesheet" type="text/css" />
    <script src="content/js/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script src="content/js/paper.js" type="text/javascript"></script>
    <script type="text/paperscript" canvas="canvas">
        Array.prototype.remove = function(start, end) {
            this.splice(start, end);
            return this;
        }

        view.currentScroll = new Point(0, 0);
        var scrollVector = new Point(0,0);
        var scrollMargin = 32;

        $('#puzzle-image').attr('src', 'content/images/avengers.jpg');

        var imgWidth = $('.puzzle-image').css('width').replace('px', '');
        var imgHeight = $('.puzzle-image').css('height').replace('px', '');

        var config = ({
            zoomScaleOnDrag: 1.125,
            imgName: 'puzzle-image',
            tileWidth: 64,
            tilesPerRow: 10,
            tilesPerColumn: 8,
            imgWidth: imgWidth,
            imgHeight: imgHeight,
            shadowWidth: 120
        });

        var puzzle = new Html5Puzzle(config);
        puzzle.zoom(-.3);
        var path;
        var movePath = false;

        $('.zoomIn').click(function() {
            puzzle.zoom(.1);
        });

        $('.zoomOut').click(function() {
            puzzle.zoom(-.1);
        });

        $('.help').mousedown(function() {
            if ($('.canvas').css('display') == 'none') {
                $('.canvas').show();
                $('.puzzle-image').hide();
                $('.logo').hide();
            }
            else {
                $('.canvas').hide();
                $('.puzzle-image').show();
                $('.logo').show();
            }
        });

        var charmsWidth = $('.charms').css('width').replace('px', '');
        $('.puzzle-image').css('margin', '-' + imgHeight/2 + 'px 0 0 -' + imgWidth/2 + 'px');

        function onMouseDown(event) {
            puzzle.pickTile();
        }

        function onMouseUp(event) {
            puzzle.releaseTile();
        }

        function onMouseMove(event) {
            puzzle.mouseMove(event.point, event.delta);

            if (event.point.x < scrollMargin) {
                scrollVector = new Point(scrollMargin - event.point.x, 0);
            }
            else {
                scrollVector = new Point(0, 0);
            }
        }

        function onMouseDrag(event) {
            puzzle.dragTile(event.delta);
        }

        function onKeyUp(event) {
            switch(event.key) {
                case 'z':
                    puzzle.zoom(.1);
                    break;
                case 'x':
                    puzzle.zoom(-.1);
                    break;
                }
        }

        function Html5Puzzle(config) {
            instance = this;
            this.currentZoom = 1;
            this.zoomScaleOnDrag = config.zoomScaleOnDrag;
            this.imgName = config.imgName;
            this.shadowWidth = config.shadowWidth;
            this.puzzleImage = new Raster(config.imgName);
            this.puzzleImage.position = view.center;
            this.puzzleImage.visible = false;
            this.tileWidth = 128;
            this.tilesPerRow = Math.ceil(config.imgWidth / config.tileWidth);
            this.tilesPerColumn = Math.ceil(config.imgHeight / config.tileWidth);
            this.tileMarginWidth = this.tileWidth * 0.203125;
            this.selectedTile = undefined;
            this.selectedTileIndex = undefined;
            this.selectionGroup = undefined;
            this.shadowScale = 1.5;
            this.tiles = createTiles(this.tilesPerRow, this.tilesPerColumn);

            function createTiles(xTileCount, yTileCount) {
                var tiles = new Array();
                var tileRatio = instance.tileWidth / 100.0;

                var shapeArray = getRandomShapes(xTileCount, yTileCount);
                var tileIndexes = new Array();
                for (var y = 0; y < yTileCount; y++) {
                    for (var x = 0; x < xTileCount; x++) {

                        var shape = shapeArray[y * xTileCount + x];

                        var mask = getMask(tileRatio, shape.topTab, shape.rightTab, shape.bottomTab, shape.leftTab, instance.tileWidth);
                        mask.opacity = 0.25;
                        mask.strokeColor = '#fff';

                        var cloneImg = instance.puzzleImage.clone();
                        var img = getTileRaster(
                            cloneImg, 
                            new Size(628, 628), 
                            new Point(instance.tileWidth * x, instance.tileWidth * y)
                        );

                        var border = mask.clone();
                        border.strokeColor = '#000';
                        border.strokeWidth = 2;

                        var tile = new Group(mask, border, img, border);
                        tile.clipped = true;
                        tile.opacity = 1;

                        tile.shape = shape;
                        tile.imagePosition = new Point(x, y);

                        tiles.push(tile);
                        tileIndexes.push(tileIndexes.length);
                    }
                }

                for (var y = 0; y < yTileCount; y++) {
                    for (var x = 0; x < xTileCount; x++) {

                        var index1 = Math.floor(Math.random() * tileIndexes.length);
                        var index2 = tileIndexes[index1];
                        var tile = tiles[index2];
                        tileIndexes.remove(index1, 1);

                        var position = view.center - 
                                        new Point(instance.tileWidth, instance.tileWidth / 2) + 
                                        new Point(instance.tileWidth * (x * 2 + ((y % 2))), instance.tileWidth  * y) -
                                        new Point(instance.puzzleImage.size.width, instance.puzzleImage.size.height / 2);

                        var cellPosition = new Point(
                            Math.round(position.x / instance.tileWidth) + 1,
                            Math.round(position.y / instance.tileWidth) + 1);

                        tile.position = cellPosition * instance.tileWidth;
                        tile.cellPosition = cellPosition;                        
                    }
                }

                return tiles;
            }

            function getRandomShapes(width, height) {
                var shapeArray = new Array();

                for (var y = 0; y < height; y++) {
                    for (var x = 0; x < width; x++) {

                        var topTab = undefined;
                        var rightTab = undefined;
                        var bottomTab = undefined;
                        var leftTab = undefined;

                        if (y == 0)
                            topTab = 0;

                        if (y == height - 1)
                            bottomTab = 0;

                        if (x == 0)
                            leftTab = 0;

                        if (x == width - 1)
                            rightTab = 0;

                        shapeArray.push(
                            ({
                                topTab: topTab,
                                rightTab: rightTab,
                                bottomTab: bottomTab,
                                leftTab: leftTab
                            })
                        );
                    }
                }

                for (var y = 0; y < height; y++) {
                    for (var x = 0; x < width; x++) {

                        var shape = shapeArray[y * width + x];

                        var shapeRight = (x < width - 1) ? 
                            shapeArray[y * width + (x + 1)] : 
                            undefined;

                        var shapeBottom = (y < height - 1) ? 
                            shapeArray[(y + 1) * width + x] :
                            undefined;

                        shape.rightTab = (x < width - 1) ? 
                            getRandomTabValue() :
                            shape.rightTab;

                        if (shapeRight)
                            shapeRight.leftTab = - shape.rightTab;

                        shape.bottomTab = (y < height - 1) ? 
                            getRandomTabValue() :
                            shape.bottomTab;

                        if (shapeBottom)
                            shapeBottom.topTab = - shape.bottomTab;
                    }
                }
                return shapeArray;
            }

            function getRandomTabValue() {
                return Math.pow(-1, Math.floor(Math.random() * 2));
            }

            function getMask(tileRatio, topTab, rightTab, bottomTab, leftTab, tileWidth) {

                var curvyCoords = [
                      0, 0, 35, 15, 37, 5,
                      37, 5, 40, 0, 38, -5,
                      38, -5, 20, -20, 50, -20,
                      50, -20, 80, -20, 62, -5,
                      62, -5, 60, 0, 63, 5,
                      63, 5, 65, 15, 100, 0
                ];

                var mask = new Path();
                var tileCenter = view.center;

                var topLeftEdge = new Point(-4, 4);

                mask.moveTo(topLeftEdge);

                //Top
                for (var i = 0; i < curvyCoords.length / 6; i++) {
                    var p1 = topLeftEdge + new Point(curvyCoords[i * 6 + 0] * tileRatio, topTab * curvyCoords[i * 6 + 1] * tileRatio);
                    var p2 = topLeftEdge + new Point(curvyCoords[i * 6 + 2] * tileRatio, topTab * curvyCoords[i * 6 + 3] * tileRatio);
                    var p3 = topLeftEdge + new Point(curvyCoords[i * 6 + 4] * tileRatio, topTab * curvyCoords[i * 6 + 5] * tileRatio);

                    mask.cubicCurveTo(p1, p2, p3);
                }
                //Right
                var topRightEdge = topLeftEdge + new Point(tileWidth, 0);
                for (var i = 0; i < curvyCoords.length / 6; i++) {
                    var p1 = topRightEdge + new Point(-rightTab * curvyCoords[i * 6 + 1] * tileRatio, curvyCoords[i * 6 + 0] * tileRatio);
                    var p2 = topRightEdge + new Point(-rightTab * curvyCoords[i * 6 + 3] * tileRatio, curvyCoords[i * 6 + 2] * tileRatio);
                    var p3 = topRightEdge + new Point(-rightTab * curvyCoords[i * 6 + 5] * tileRatio, curvyCoords[i * 6 + 4] * tileRatio);

                    mask.cubicCurveTo(p1, p2, p3);
                }
                //Bottom
                var bottomRightEdge = topRightEdge + new Point(0, tileWidth);
                for (var i = 0; i < curvyCoords.length / 6; i++) {
                    var p1 = bottomRightEdge - new Point(curvyCoords[i * 6 + 0] * tileRatio, bottomTab * curvyCoords[i * 6 + 1] * tileRatio);
                    var p2 = bottomRightEdge - new Point(curvyCoords[i * 6 + 2] * tileRatio, bottomTab * curvyCoords[i * 6 + 3] * tileRatio);
                    var p3 = bottomRightEdge - new Point(curvyCoords[i * 6 + 4] * tileRatio, bottomTab * curvyCoords[i * 6 + 5] * tileRatio);

                    mask.cubicCurveTo(p1, p2, p3);
                }
                //Left
                var bottomLeftEdge = bottomRightEdge - new Point(tileWidth, 0);
                for (var i = 0; i < curvyCoords.length / 6; i++) {
                    var p1 = bottomLeftEdge - new Point(-leftTab * curvyCoords[i * 6 + 1] * tileRatio, curvyCoords[i * 6 + 0] * tileRatio);
                    var p2 = bottomLeftEdge - new Point(-leftTab * curvyCoords[i * 6 + 3] * tileRatio, curvyCoords[i * 6 + 2] * tileRatio);
                    var p3 = bottomLeftEdge - new Point(-leftTab * curvyCoords[i * 6 + 5] * tileRatio, curvyCoords[i * 6 + 4] * tileRatio);

                    mask.cubicCurveTo(p1, p2, p3);
                }

                return mask;
            }

            var hitOptions = {
                segments: true,
                stroke: true,
                fill: true,
                tolerance: 5
            };

            function getTileRaster(sourceRaster, size, offset) {
                var targetRaster = new Raster('empty');
                var tileWithMarginWidth = size.width + instance.tileMarginWidth * 2;
                var data = sourceRaster.getData(new Rectangle(
                    offset.x - instance.tileMarginWidth*2, 
                    offset.y - instance.tileMarginWidth*2, 
                    tileWithMarginWidth*0.5, 
                    tileWithMarginWidth*0.5));
                targetRaster.setData(data, new Point(0, 0))
                targetRaster.position = new Point(56, 72);
                return targetRaster;
            }

            this.pickTile = function() {
                if (instance.selectedTile) {
                    if (!instance.selectedTile.lastScale) {
                        instance.selectedTile.lastScale = instance.zoomScaleOnDrag;
                        instance.selectedTile.scale(instance.selectedTile.lastScale);
                    }
                    else {
                        if (instance.selectedTile.lastScale > 1) {
                            instance.releaseTile();
                            return;
                        }
                    }

                    instance.selectedTile.cellPosition = undefined;

                    instance.selectionGroup = new Group(instance.selectedTile);

                    var pos = new Point(instance.selectedTile.position.x, instance.selectedTile.position.y);
                    instance.selectedTile.position = new Point(0, 0);

                    instance.selectionGroup.position = pos;
                }
            }

            this.releaseTile = function() {
                if (instance.selectedTile) {

                    var cellPosition = new Point(
                        Math.round(instance.selectionGroup.position.x / instance.tileWidth),
                        Math.round(instance.selectionGroup.position.y / instance.tileWidth));

                    var roundPosition = cellPosition * instance.tileWidth;

                    var hasConflict = false;

                    var alreadyPlacedTile = getTileAtCellPosition(cellPosition);

                    hasConflict = alreadyPlacedTile;

                    var topTile = getTileAtCellPosition(cellPosition + new Point(0, -1));
                    var rightTile = getTileAtCellPosition(cellPosition + new Point(1, 0));
                    var bottomTile = getTileAtCellPosition(cellPosition + new Point(0, 1));
                    var leftTile = getTileAtCellPosition(cellPosition + new Point(-1, 0));

                    if (topTile) {
                        hasConflict = hasConflict || !(topTile.shape.bottomTab + instance.selectedTile.shape.topTab == 0);
                    }

                    if (bottomTile) {
                        hasConflict = hasConflict || !(bottomTile.shape.topTab + instance.selectedTile.shape.bottomTab == 0);
                    }

                    if (rightTile) {
                        hasConflict = hasConflict || !(rightTile.shape.leftTab + instance.selectedTile.shape.rightTab == 0);
                    }

                    if (leftTile) {
                        hasConflict = hasConflict || !(leftTile.shape.rightTab + instance.selectedTile.shape.leftTab == 0);
                    }

                    if (!hasConflict) {

                        if (instance.selectedTile.lastScale) {
                            instance.selectedTile.scale(1 / instance.selectedTile.lastScale);
                            instance.selectedTile.lastScale = undefined;
                        }

                        instance.selectionGroup.remove();
                        var tile = instance.tiles[instance.selectedTileIndex];
                        tile.position = roundPosition;
                        tile.cellPosition = cellPosition;
                        instance.selectionGroup.remove();
                        instance.selectedTile =
                        instance.selectionGroup = null;
                        project.activeLayer.addChild(tile);

                        var errors = checkTiles();
                        if (errors == 0) {
                            alert('Congratulations!!!');
                        }
                    }
                }
            }

            function getTileAtCellPosition(point) {
                var width = instance.tilesPerRow;
                var height = instance.tilesPerColumn;
                var tile = undefined;
                for (var i = 0; i < instance.tiles.length; i++) {
                    if (instance.tiles[i].cellPosition == point) {
                        tile = instance.tiles[i];
                        break;
                    }
                }
                return tile;
            }

            this.dragTile = function(delta) {
                if (instance.selectedTile) {
                    instance.selectionGroup.position += delta;
                    instance.selectedTile.opacity = 1;
                }
                else {
                    var currentScroll = view.currentScroll - delta * instance.currentZoom;
                    view.scrollBy(currentScroll);
                    view.currentScroll = currentScroll;
                }
            }

            this.mouseMove = function(point, delta) {
                if (!instance.selectionGroup) {
                    project.activeLayer.selected = false;
                    if (delta.x < 8 && delta.y < 8) {
                        var tolerance = instance.tileWidth * .5;
                        var hit = false;
                        for (var index = 0; index < instance.tiles.length; index++) {
                            var tile = instance.tiles[index];
                            var row = parseInt(index / config.tilesPerRow);
                            var col = index % config.tilesPerRow;

                            var tileCenter = tile.position;

                            var deltaPoint = tileCenter - point;
                            hit = (deltaPoint.x * deltaPoint.x + 
                                        deltaPoint.y * deltaPoint.y) < tolerance * tolerance;

                            if (hit) {
                                instance.selectedTile = tile;
                                instance.selectedTileIndex = index;
                                tile.opacity = .5;
                                project.activeLayer.addChild(tile);
                                return;
                            }
                            else {
                                tile.opacity = 1;
                            }
                        }
                        if (!hit)
                            instance.selectedTile = null;
                    }
                }
                else {
                    instance.dragTile(delta);
                }
            }

            this.zoom = function(zoomDelta) {
                var newZoom = instance.currentZoom + zoomDelta;
                if (newZoom >= 0.3 && newZoom <= 1) {
                    view.zoom = 
                    instance.currentZoom = newZoom;
                }
            }

            function checkTiles() {
                var errors = 0;
                var firstTile = instance.tiles[0];
                var firstCellPosition = firstTile.cellPosition;

                for (var y = 0; y < instance.tilesPerColumn; y++) {
                    for (var x = 0; x < instance.tilesPerRow; x++) {
                        var index = y * instance.tilesPerRow + x;
                        var cellPosition = instance.tiles[index].cellPosition;

                        if (cellPosition != firstCellPosition + new Point(x, y)) {
                            errors++;
                        }
                    }
                }

                return errors;
            }
        }
    </script>
</head>
<body>
    <img width="920" height="120" src="content/images/logo.png" class="logo"/>
    <canvas id="canvas" class="canvas" resize></canvas>
    <div class="charms">
        <img width="50" height="50" src="content/images/zoomIn.png" class="zoomIn"/>
        <img width="50" height="50" src="content/images/zoomOut.png" class="zoomOut"/>
        <img width="50" height="50" src="content/images/help.png" class="help"/>
    </div>
    <img width="640" height="512" id="puzzle-image" class="puzzle-image" style="display: none;" src="content/images/avengers.jpg" />
    <img width="128" height="128" id="empty" style="display: none;" src="content/images/empty.png" />
</body>

0 个答案:

没有答案