Skip to content
This repository was archived by the owner on Dec 7, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .babelrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
"es2015"
],
"plugins": [
"transform-decorators-legacy",
"transform-object-rest-spread",
"transform-class-properties",
"transform-runtime",
"react-hot-loader/babel"
]
}
2 changes: 1 addition & 1 deletion example/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import cardImage from './card.jpg';
const settings = {
width: 640,
height: 480,
image: cardImage,
cover: "#396",
finishPercent: 50,
onComplete: () => console.log('The card is now clear!')
};
Expand Down
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "React component for displaying scratch card in your web app.",
"main": "dist/index.js",
"scripts": {
"start": "npm run start-example",
"build": "babel src -d dist",
"start-example": "webpack-dev-server --progress --profile --colors",
"build-example": "webpack --config webpack.production.config.js --progress --profile --colors"
Expand All @@ -19,6 +20,7 @@
"url": "https://github.com/aleksik/react-scratchcard.git"
},
"dependencies": {
"classnames": "^2.2.5",
"react": "^15.0.0"
},
"devDependencies": {
Expand All @@ -27,19 +29,21 @@
"babel-loader": "^6.2.5",
"babel-plugin-transform-class-properties": "^6.16.0",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-exponentiation-operator": "^6.24.1",
"babel-plugin-transform-object-rest-spread": "^6.23.0",
"babel-plugin-transform-runtime": "^6.15.0",
"babel-preset-es2015": "^6.16.0",
"babel-preset-react": "^6.16.0",
"css-loader": "^0.25.0",
"extract-text-webpack-plugin": "^1.0.1",
"file-loader": "^0.9.0",
"html-webpack-plugin": "^2.22.0",
"react-dom": "^15.0.0",
"react-hot-loader": "^3.0.0-beta.5",
"style-loader": "^0.13.1",
"url-loader": "^0.5.7",
"webpack": "^1.13.2",
"webpack-cleanup-plugin": "^0.4.0",
"webpack-dev-server": "^1.16.1",
"react-dom": "^15.0.0"
"webpack-dev-server": "^1.16.1"
}
}
99 changes: 66 additions & 33 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import React, { Component } from 'react';
import React, { PropTypes, Component } from 'react';
import classnames from "classnames"

class ScratchCard extends Component {

Expand All @@ -8,17 +9,36 @@ class ScratchCard extends Component {
}

componentDidMount() {
const { cover } = this.props
this.isDrawing = false;
this.lastPoint = null;
this.ctx = this.canvas.getContext('2d');

const image = new Image();
image.crossOrigin = "Anonymous";
image.onload = () => {
this.ctx.drawImage(image, 0, 0);
const isColorCover = this.checkColorCover(cover)

if (!isColorCover) {
const image = new Image();
image.crossOrigin = "Anonymous";
image.onload = () => {
this.ctx.drawImage(image, 0, 0);
this.setState({ loaded: true });
}
image.src = cover;
} else {
const { width, height } = this.canvas
this.ctx.save()
this.ctx.fillStyle = cover
this.ctx.beginPath()
this.ctx.rect(0, 0, width, height)
this.ctx.fill()
this.ctx.restore()
this.setState({ loaded: true });
}
image.src = this.props.image;

}

checkColorCover(cover) {
return (/^#(\d|\w){3,6}$/.test(cover) || /^rgba?\(.*\)/.test(cover))
}

getFilledInPixels(stride) {
Expand All @@ -40,13 +60,13 @@ class ScratchCard extends Component {
}

getMouse(e, canvas) {
const {top, left} = canvas.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const { top, left } = canvas.getBoundingClientRect();
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const scrollLeft = window.pageXOffset || document.documentElement.scrollLeft;

return {
x: (e.pageX || e.touches[0].clientX) - left - scrollLeft,
y: (e.pageY || e.touches[0].clientY) - top - scrollTop
x: (e.pageX || e.touches[0].clientX) - left - scrollLeft,
y: (e.pageY || e.touches[0].clientY) - top - scrollTop
}
}

Expand All @@ -70,15 +90,13 @@ class ScratchCard extends Component {
}
}

handleMouseDown(e) {
handleMouseDown = (e) => {
this.isDrawing = true;
this.lastPoint = this.getMouse(e, this.canvas);
}

handleMouseMove(e) {
if (!this.isDrawing) {
return;
}
handleMouseMove = (e) => {
if (!this.isDrawing) return;

e.preventDefault();

Expand All @@ -102,15 +120,26 @@ class ScratchCard extends Component {

}

handleMouseUp() {
handleMouseUp = () => {
this.isDrawing = false;
}

render() {
const {
width,
height,
cover,
finishPercent,
onComplete,
className,
...attr
} = this.props

const { loaded } = this.state

const containerStyle = {
width: this.props.width + 'px',
height: this.props.height + 'px',
width,
height,
position: 'relative',
WebkitUserSelect: 'none',
MozUserSelect: 'none',
Expand All @@ -125,25 +154,29 @@ class ScratchCard extends Component {
}

const resultStyle = {
visibility: this.state.loaded ? 'visible' : 'hidden'
visibility: loaded ? 'visible' : 'hidden'
}

const canvasProps = {
ref: (ref) => this.canvas = ref,
className: 'ScratchCard__Canvas',
style: canvasStyle,
width: this.props.width,
height: this.props.height,
onMouseDown: this.handleMouseDown.bind(this),
onTouchStart: this.handleMouseDown.bind(this),
onMouseMove: this.handleMouseMove.bind(this),
onTouchMove: this.handleMouseMove.bind(this),
onMouseUp: this.handleMouseUp.bind(this),
onTouchEnd: this.handleMouseUp.bind(this)
width,
height,
onMouseDown: this.handleMouseDown,
onTouchStart: this.handleMouseDown,
onMouseMove: this.handleMouseMove,
onTouchMove: this.handleMouseMove,
onMouseUp: this.handleMouseUp,
onTouchEnd: this.handleMouseUp
}

return (
<div className="ScratchCard__Container" style={containerStyle}>
<div
className={classnames("ScratchCard__Container", className)}
style={containerStyle}
{...attr}
>
<canvas {...canvasProps}></canvas>
<div className="ScratchCard__Result" style={resultStyle}>
{this.props.children}
Expand All @@ -155,11 +188,11 @@ class ScratchCard extends Component {
}

ScratchCard.propTypes = {
image: React.PropTypes.string.isRequired,
width: React.PropTypes.number.isRequired,
height: React.PropTypes.number.isRequired,
finishPercent: React.PropTypes.number.isRequired,
onComplete: React.PropTypes.func
cover: PropTypes.string.isRequired,
width: PropTypes.number.isRequired,
height: PropTypes.number.isRequired,
finishPercent: PropTypes.number.isRequired,
onComplete: PropTypes.func
}

export default ScratchCard;