html部分
<body>
<div class="container">
<div class="source">
<img id="nc" src="./assets/btbg.jpg" alt="" srcset="">
<!-- <img id="nc" src="./assets/奶茶.webp" alt="" srcset=""> -->
</div>
<div class="cc">
<canvas class="copy" width="1080" height="1920"></canvas>
</div>
<div class="rc">
<canvas class="rotate" width="1080" height="1920"></canvas>
</div>
</div>
</body>
style部分
由于只是一个测试的demo,这部分写的比较随意,选择器记得给名字
<style>
html,
body {
height: 100%;
width: 100%;
margin: 0;
box-sizing: border-box;
font-family: Helvetica;
}
.container {
width: 100%;
height: 100%;
display: flex;
}
.container>div {
width: 33%;
min-width: 360px;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
}
div>canvas {
display: flex;
justify-content: center;
width: 100%;
height: auto;
}
div>img {
max-width: 100%;
max-height: 100%;
height: auto;
width: auto;
}
</style>
js部分
const c1 = document.querySelector('.copy')
const c2 = document.querySelector('.rotate')
const c1c = document.querySelector('.cc')
const c2c = document.querySelector('.rc')
const ctx1 = c1.getContext('2d')
const ctx2 = c2.getContext('2d')
const img = document.querySelector('#nc')
img.onload = res => {
// 图片宽高
let iw = img.width
let ih = img.height
// canvas宽高
let cw = c1.width
let ch = c1.height
let { rw, rh, points } = getXY(cw, ch, iw, ih)
ctx1.drawImage(img, points[0], points[1], rw, rh)
// 见图1
const opt = getXY(cw, cw, ih, iw)
console.log(opt);
ctx2.translate(0, opt.rh + opt.points[1])
ctx2.rotate(-Math.PI / 2)
ctx2.drawImage(img, opt.points[1], opt.points[0], opt.rh, opt.rw)
ctx2.translate(0, -(opt.rh + opt.points[1]))
ctx2.rotate(Math.PI / 2)
// 将有效部分图片截取
let frame = ctx2.getImageData(0, 0, opt.rw, opt.rh)
// 将canvas保持与图片大小相同
c2.height = opt.rh
// 清除画布
ctx2.clearRect(0,0,opt.rw,opt.rh)
// 重新绘制
ctx2.putImageData(frame, 0, 0)
}
保存的方法网上有很多,这是抄得一段
function saveAsImage(canvas) {
var image = canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"); // here is the most important part because if you dont replace you will get a DOM 18 exception.
//save as download without name and extension
//window.location.href = image;
// 这里需要一个id为link的a标签,用createElement也行
var link = document.getElementById('link');
link.setAttribute('download', 'my.png');
link.setAttribute('href', canvas.toDataURL("image/png").replace("image/png", "image/octet-stream"));
link.click();
}
图1
简单说下,旋转90度后,由第四象限位移到第一象限,我这里canvas比例大概为3/5,高比宽大,于是最大高度变为宽度,能显示的部分就上图那么大
计算位置函数
/**
* @description:
* @param {*} cw canvas宽度
* @param {*} ch canvas高度
* @param {*} iw img宽度
* @param {*} ih img高度
* @return {*}
*/
function getXY(cw, ch, iw, ih) {
// 比较宽高比例,大的一边撑满
let icw = iw / cw
let ich = ih / ch
let li = iw / ih
let lc = cw / ch
console.log('图片宽高比', li, 'canvas宽高比', lc);
// 需要绘制的宽高起点
let points = [0, 0]
let rw, rh
let wall = false // 是否宽度占满
if (li > lc) {
// 宽度100%,等比缩放
rw = cw
rh = rw / li
points[0] = 0
points[1] = (ch - rh) / 2
wall = true
} else {
rh = ch
rw = rh * li
points[0] = (cw - rw) / 2
points[1] = 0
wall = false
}
rw = Math.floor(rw)
rh = Math.floor(rh)
console.log('canvas', cw, ch, 'img', iw, ih, '绘制', rw, rh);
return {
points,
rw,
rh
}
}
效果图
左边是原图,第二张是canvas绘制原图,第三张是canvas旋转90度之后的图