失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > canvas实现图片平移 缩放的例子

canvas实现图片平移 缩放的例子

时间:2020-03-03 18:31:25

相关推荐

canvas实现图片平移 缩放的例子

最近有个水印预览的功能,需要用到canvas 绘制,canvas用的不是很熟,配合chatAI 完成功能。

效果如下

代码如下

原先配置是响应式的,提出来了就不显示操作了,模拟值都写死的 界面给大家参考阅读。

<!DOCTYPE html><html><head><title>Canvas :平移和缩放</title></head><body><div style="width:580px; height:440px"><canvas id="canvas"></canvas></div><script>class PreviewImage {el = nullctx = nullimage = nullscale = 1translateX = 0translateY = 0dragging = 0drag_sx = 0drag_sy = 0ratio = window.devicePixelRatio || 1constructor(el, options = {}) {this.el = elthis.options = optionsthis.init()}init() {const {el, w, h } = thisthis.ctx = el.getContext('2d')el.width = wel.height = hthis.createImage()this.bindEvent()}update(options) {this.options = optionsthis.createImage()}bindEvent() {const {el } = thisthis.mousedownBound = this.mousedown.bind(this)this.mousemoveBound = this.mousemove.bind(this)this.mouseupBound = this.mouseup.bind(this)this.wheelBound = this.wheel.bind(this)el.addEventListener('mousedown', this.mousedownBound, false)document.addEventListener('mouseup', this.mouseupBound, false)document.addEventListener('mousemove', this.mousemoveBound, false)el.addEventListener('wheel', this.wheelBound, false)}mousedown(evt) {const {clientX, clientY } = evtthis.drag_sx = clientXthis.drag_sy = clientYthis.dragging = 1document.body.style.cursor = 'move'document.body.style.userSelect = 'none'}mouseup() {this.dragging = 0document.body.style.cursor = 'auto'document.body.style.userSelect = 'auto'}mousemove(evt) {const {clientX, clientY } = evtconst {dragging, drag_sx, drag_sy } = thisif (!dragging) returnconst dx = clientX - drag_sxconst dy = clientY - drag_sythis.drag_sx = clientXthis.drag_sy = clientYthis.translate(dx, dy)}translate(dx, dy) {const {image } = thisconst {translateX, translateY } = thisconst {width, height } = imageconst x = translateX + dxconst y = translateY + dythis.translateX = Math.min(Math.max(x, width * 0.1 - width), width - width * 0.1)this.translateY = Math.min(Math.max(y, height * 0.1 - height), height - height * 0.1)this.draw()}wheel(evt) {evt.preventDefault()const {el } = thisconst {clientX, clientY, deltaY } = evtconst x = clientX - el.offsetLeftconst y = clientY - el.offsetTopconst dampeningFactor = 0.05const minScale = 0.3const maxScale = 1.5const scale = 1.0 + dampeningFactor * (deltaY > 0 ? -1 : 1)const currentScale = Math.min(Math.max(this.scale * scale, minScale), maxScale)this.zoom(currentScale, x, y)}zoom(s, x, y) {const {translateX, translateY } = thisif (s < 1.02 && s > 0.98) s = 1const offsetX = (x - translateX) / sconst offsetY = (y - translateY) / sthis.translateX = x - offsetX * sthis.translateY = y - offsetY * sthis.scale = sthis.draw()}get w() {return this.el.parentNode?.offsetWidth || 0}get h() {return this.el.parentNode?.offsetHeight - (30 + 45) || 0}async createImage() {const {ratio, options } = thistry {const img = await this.loadImage(options.src)img.width = options.imageWidthimg.height = options.imageHeightthis.image = imgthis.draw()} catch (error) {console.error(error)}}wheel(evt) {evt.preventDefault()const {el } = thisconst {clientX, clientY, deltaY } = evtconst x = clientX - el.offsetLeftconst y = clientY - el.offsetTopconst dampeningFactor = 0.05const minScale = 0.3const maxScale = 1.5const scale = 1.0 + dampeningFactor * (deltaY > 0 ? -1 : 1)const currentScale = Math.min(Math.max(this.scale * scale, minScale), maxScale)this.zoom(currentScale, x, y)}zoom(s, x, y) {const {translateX, translateY, options, ratio } = thisif (s < 1.02 && s > 0.98) s = 1const offsetX = (x - translateX) / sconst offsetY = (y - translateY) / sthis.translateX = x - offsetX * sthis.translateY = y - offsetY * sthis.image.width = options.imageWidth * ratio * sthis.image.height = options.imageHeight * ratio * sthis.scale = sthis.draw()}draw() {const {ctx, ratio, w, h, image, translateX, translateY, scale } = thisctx.clearRect(0, 0, w, h)this.drawBackground()ctx.save()ctx.translate(translateX, translateY)const imageX = (w - image.width * scale * ratio) / 2const imageY = (h - image.height * scale * ratio) / 2ctx.drawImage(image, imageX, imageY, image.width * scale, image.height * scale)this.drawTexts()ctx.restore()this.scaling()}drawTexts() {const {ctx, ratio, image, options, scale, w, h } = thisconst {texts, textStyles } = optionsconst {fontSize, fontFamily, fontColor, textAlign = 'center', lineX, lineY, lineAngle, textBaseline = 'top' } = textStylesctx.font = `${fontSize * ratio * scale}px ${fontFamily || 'sans-serif'}`ctx.fillStyle = fontColor || '#303133'ctx.textAlign = textAlignctx.textBaseline = textBaselineconst text = this.transformText(texts)const imageX = (w - image.width * scale * ratio) / 2const imageY = (h - image.height * scale * ratio) / 2const posx = imageX + image.width * scale * ratio * (lineX / 100)const posy = imageY + image.height * scale * ratio * (lineY / 100)const angle = (lineAngle / 180) * Math.PIctx.fillText(text, posx, posy)}scaling() {const {ctx, w, scale } = thisif (scale < 1.03 && scale > 0.97) returnctx.save()ctx.font = `12px xsans-serif`ctx.fillStyle = '#303133'ctx.textAlign = 'center'ctx.textBaseline = 'top'const text = `${(scale * 100).toFixed(0)}%`ctx.fillText(text, w - ctx.measureText(text).width + 10, 10)ctx.restore()}loadImage(url) {return new Promise((resolve, reject) => {const image = new Image()image.onload = () => {resolve(image)}image.onerror = () => {reject(new Error('无法加载图片: ' + url))}image.src = url})}drawBackground() {const {ctx, ratio, w, h } = thisconst posx = (0 / 100) * w * ratioconst posy = (0 / 100) * h * ratioconst width = (100 / 100) * w * ratioconst height = (100 / 100) * h * ratioctx.beginPath()ctx.fillStyle = '#F2F6FC'ctx.fillRect(posx, posy, width, height)}transformText(arr) {arr = Array.isArray(arr) ? arr : [arr]const keywods = {'${timestamp}': new Date().toLocaleString(),'${consumerName}': '消费者名称','${terminalIP}': '127.0.0.1',}return arr.join('-').replace(/\$\{timestamp\}|\$\{consumerName\}|\$\{terminalIP\}/g, matched => keywods[matched])}destroy() {this.el.removeEventListener('mousedown', this.mousedownBound)document.removeEventListener('mousemove', this.mousemoveBound)document.removeEventListener('mouseup', this.mouseupBound)this.el.removeEventListener('wheel', this.wheelBound)}}var dialog = {visible: false,predefine: ['#ff4500', '#ff8c00', '#ffd700', '#90ee90', '#00ced1', '#1e90ff', '#c71585', '#cd5c5c', '#000000', '#ffffff'],title: '新增',controlled_width: 800,controlled_height: 600,form: {name: '',content: ['127.0.0.1'],lineX: 50,lineY: 10,lineAngle: 0,fontSize: 25,fontColor: '#ff4500',fontFamily: '',},}var picture = {images: ['/photos/1784914/pexels-photo-1784914.jpeg?auto=compress&cs=tinysrgb&w=1600'],active: 0,}const {controlled_width, controlled_height, form } = dialogconst {fontSize, fontColor, fontFamily, lineX, lineY, lineAngle } = formconst {images, active } = pictureconst textStyles = {fontSize,fontColor,fontFamily,lineX,lineY,lineAngle,}const options = {src: images[active],imageWidth: controlled_width,imageHeight: controlled_height,texts: dialog.form.content,textStyles,}var canvas = document.getElementById('canvas')var priviewImage = new PreviewImage(canvas, options)</script></body></html>

如果觉得《canvas实现图片平移 缩放的例子》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。