我正在参加「初夏创意投稿大赛」详情请看:初夏创意投稿大赛
本文使用 react 作为框架。样式和布局比较简单,就不细说啦,代码放到最后。
基础布局
import { useEffect, useState } from 'react';
import './App.css';
const canvasArr = [];
for (let i = 1; i < 10; i++) {
canvasArr.push(i);
}
function App(props) {
return (
<div className="App">
<div className="left">
<div className="my-canvas">
<canvas width="300" height="300" id="mycnavas"></canvas>
</div>
<div className="new-photo">
开始切图
</div>
</div>
<div className="right">
<div className="new-canvas">
{
canvasArr.map((i) => <canvas width="100" height="100" id={`img${i}`} key={i}></canvas>)
}
</div>
<div className="download">
下载图片
</div>
</div>
</div>
);
}
export default App;
在 useEffect 的时候,初始化 canvas。
同时为右边的 canvas 添加显示的判断条件。当点击按钮的时候,才会显示出来。
但是这里为什么我们要使用 style 进行 display 的判断呢?这是因为避免后续使用右侧的 canvas 时找不到元素而报错。
// ...
function App(props) {
const [context, setContext] = useState(null);
const [show, setShow] = useState(false);
const init = () => {
const canvas = document.getElementById('mycnavas');
const cxt = canvas.getContext("2d");
setContext(cxt);
const img = new Image();
img.crossOrigin = "anonymous";
img.src = props.img;
window.onload = function () {
cxt.drawImage(img, 0, 0, 400, 300);
};
}
useEffect(() => {
init();
}, []);
return (
<div className="App">
<div className="right" style={{ 'display': show ? 'block' : 'none' }}>
<div className="new-canvas">
{
canvasArr.map((i) => <canvas width="100" height="100" id={`img${i}`} key={i}></canvas>)
}
</div>
<div className="download">
下载图片
</div>
</div>
</div>
);
}
export default App;
canvas 有两个方法:
通过 getImageData() 复制画布上指定矩形的像素数据,然后通过 putImageData() 将图像数据放回画布
示例代码:
var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.fillStyle = "red";
ctx.fillRect(10,10,50,50);
function copy() {
var imgData = ctx.getImageData(10,10,50,50);
ctx.putImageData(imgData,10,70);
}
点击开始切图的时候,调用 handleClick 方法
// ...
function App(props) {
// ...
const handleClick = () => {
let q = 1;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const data = context.getImageData(j * 100, i * 100, 400, 100);
const img = document.getElementById(`img${q}`);
const newCxt = img.getContext('2d');
newCxt.putImageData(data, 0, 0);
arr.push(img.toDataURL(`${q}.png`));
q++;
}
}
setShow(true);
}
// ...
return (
<div className="App">
<div className="left">
<div className="new-photo" onClick={handleClick}>
开始切图
</div>
</div>
</div>
);
}
export default App;
还不错吧,还差最后一步,下载图片就完成啦啦啦啦啦
// ...
function App(props) {
// ....
const handleDownLoad = () => {
for (let i = 1; i < 10; i++) {
const a = document.createElement('a');
a.download = `img${i}`;
a.href = arr[i];
document.body.appendChild(a);
a.click();
}
}
// ...
return (
<div className="App">
<div className="right" style={{ 'display': show ? 'block' : 'none' }}>
<div className="download" onClick={handleDownLoad}>
下载图片
</div>
</div>
</div>
);
}
export default App;
App.css
.App {
text-align: center;
display: flex;
}
.left {
flex: 1;
}
.right {
flex: 1;
}
canvas {
border: 1px solid;
margin: 3px;
}
.new-canvas {
width: 350px;
height: 316px;
margin: 0px auto 20px;
}
.new-photo,
.download {
width: 300px;
height: 40px;
line-height: 40px;
margin: auto;
background-color: cornflowerblue;
border-radius: 5px;
cursor: pointer;
margin: 10px auto;
color: white;
margin-top: 10px;
}
App.js
import { useEffect, useState } from 'react';
import './App.css';
const canvasArr = [];
for (let i = 1; i < 10; i++) {
canvasArr.push(i);
}
function App(props) {
const [show, setShow] = useState(false);
const [arr, setArr] = useState([]);
const [context, setContext] = useState(null);
const init = () => {
const canvas = document.getElementById('mycnavas');
const cxt = canvas.getContext("2d");
setContext(cxt);
const img = new Image();
img.crossOrigin = "anonymous";
img.src = props.img;
window.onload = function () {
cxt.drawImage(img, 0, 0, 400, 300);
};
}
const handleClick = () => {
let q = 1;
for (let i = 0; i < 3; i++) {
for (let j = 0; j < 3; j++) {
const data = context.getImageData(j * 100, i * 100, 400, 100);
const img = document.getElementById(`img${q}`);
const newCxt = img.getContext('2d');
newCxt.putImageData(data, 0, 0);
arr.push(img.toDataURL(`${q}.png`));
q++;
}
}
setShow(true);
}
const handleDownLoad = () => {
for (let i = 1; i < 10; i++) {
const a = document.createElement('a');
a.download = `img${i}`;
a.href = arr[i];
document.body.appendChild(a);
a.click();
}
}
useEffect(() => {
init();
}, []);
return (
<div className="App">
<div className="left">
<div className="my-canvas">
<canvas width="300" height="300" id="mycnavas"></canvas>
</div>
<div className="new-photo" onClick={handleClick}>
开始切图
</div>
</div>
<div className="right" style={{ 'display': show ? 'block' : 'none' }}>
<div className="new-canvas">
{
canvasArr.map((i) => <canvas width="100" height="100" id={`img${i}`} key={i}></canvas>)
}
</div>
<div className="download" onClick={handleDownLoad}>
下载图片
</div>
</div>
</div>
);
}
export default App;