canvas案例:刮刮乐

150 阅读1分钟

<div class="wrap">
	<div class="coupon-wrap">
		<div class="coupon-bd">
			<div class="coupon-canvas">
				<canvas id="J_couponCanvas" width="470" height="188"></canvas>
			</div>
		</div>
	</div>
</div>

两边锯齿状的样式是通过dotted的border样式实现的

body {
	margin: 0;
}
.wrap {
	width: 540px;
	height: 258px;
	margin: 100px auto;
}
.coupon-wrap {
	width: 540px;
	height: 258px;
	padding: 20px;
	background-color: #4090e4;
	box-sizing: border-box;
}
.coupon-wrap .coupon-bd {
	position: relative;
	width: 500px;
	height: 218px;
	padding: 15px;
	box-sizing: border-box;
	background-color: #fef7d6;
}
.coupon-wrap .coupon-bd::before,
.coupon-wrap .coupon-bd::after {
	content: '';
	position: absolute;
	top: 3px;
	width: 0;
	height: 100%;
}
.coupon-wrap .coupon-bd::before {
	left: -5px;
	border-left: 10px dotted #4090e4;
}
.coupon-wrap .coupon-bd::after {
	right: -5px;
	border-right: 10px dotted #4090e4;
}
.coupon-wrap .coupon-bd .coupon-canvas {
	width: 100%;
	height: 100%;
	/*background-color: orange;*/
}
.coupon-wrap .coupon-bd canvas {
	background-image: url('1.jpg');

}

js部分除了掌握鼠标相关事件和计算鼠标在画布的位置外,还需要知道ctx.globalCompositeOperation = 'destination-out'可以移除画布元素(透明度为0),然后计算透明度为0的像素点,超过一定值之后显示完全

;(function() {
	 var can = document.getElementById('J_couponCanvas'),
        ctx = can.getContext('2d'),
        cWidth = ctx.canvas.width,
        cHeight = ctx.canvas.height,
        x,
        y;

    var couponCover = new Image();
    couponCover.src = '10.jpg';

    var init = function() {
    	bindEvent();
    }

    function bindEvent() {
    	couponCover.addEventListener('load', drawMask, false);

    	can.addEventListener('mousedown', function(e) {
    		mouseDown(e);

    		document.addEventListener('mousemove', mouseMove, false);
            document.addEventListener('mouseup', mouseUp, false);
    	}, false);
    }

    function drawMask() {
    	ctx.drawImage(couponCover, 0, 0, cWidth, cHeight);
    }

    function mouseDown(e) {
    	_setXY(e);

    	ctx.beginPath();
        ctx.strokeStyle = 'black';
        ctx.lineCap = 'round';
        ctx.lineJoin = 'round';
        ctx.lineWidth = 20;
        ctx.moveTo(x, y);
    }

    function mouseMove(e) {
    	ctx.globalCompositeOperation = 'destination-out';

        _setXY(e);

        if (x <= 0) {
            x = 0;
        } else if (x > can.offsetWidth) {
            x = can.offsetWidth;
        }

        if (y <= 0) {
            y = 0;
        } else if (y > can.offsetHeight) {
            y = can.offsetHeight;
        }

        ctx.lineTo(x, y);
        ctx.stroke();
    }

    function mouseUp() {
    	revealImage()

        document.removeEventListener('mousemove', mouseMove, false);
        document.removeEventListener('mouseup', mouseUp, false);
    }

    // 能看出大概的样子就全部显示
    function revealImage() {
    	var res = ctx.getImageData(0, 0, cWidth, cHeight),
    		imageData = res.data,
    		len = imageData.length,
    		width = res.width,
    		height = res.height,
    		count = 0,
    		item;

    	// 透明度为0,就显示下面的图片,data每4个为一个rgba值,最后一个是透明度
    	for (var i = 0; i < len; i++) {
    		item = imageData[i];
    		if ((i + 1) % 4 == 0 && item == 0) {
    			// 计算透明度为0的像素点
    			count++;
    		}
    	}

    	if (count > width * height * 0.6) {
    		ctx.clearRect(0, 0, cWidth, cHeight);
    	}
    }

     function _setXY(e) {
        var e = e || window.event,
    		offset = can.getBoundingClientRect();//offsetLeft是相对于父元素的

    	x = e.pageX - offset.left;
    	y = e.pageY - offset.top;
    }

    init();
})();