【发布时间】:2018-10-15 13:30:01
【问题描述】:
下面是一个 KonvaJS 项目,您可以在其中向图像添加贴纸。但是,它有一个固定的宽度和一个固定的高度。
现在因为大小是固定的,所以它不会与任何响应一起工作,例如引导模式。
这是我遵循 KonvaJS 响应指南 see here. 和 guide here. 的尝试
在我的尝试中,上传图片后,我的代码无法获取模态框的新宽度,因为它返回 0,因此无法计算画布的大小。
如何使画布具有响应性?
function centreRectShape(shape) {
shape.x((stage.getWidth() - shape.getWidth()) / 2);
shape.y((stage.getHeight() - shape.getHeight()) / 2);
}
var stage = new Konva.Stage({
container: 'canvas-container',
width: 650,
height: 300
});
var layer = new Konva.Layer();
stage.add(layer);
var bgRect = new Konva.Rect({
width: stage.getWidth(),
height: stage.getHeight(),
fill: 'gold',
opacity: 0.1
});
layer.add(bgRect);
var uploadedImage = new Konva.Image({
draggable: false
});
layer.add(uploadedImage);
// make an object to keep things tidy - not strictly needed, just being tidy
function addSticker(imgUrl){
// make the sticker image object
var stickerObj = new Konva.Image({
x: 240,
y: 20,
width: 93,
height: 104,
name: 'sticker',
draggable: true
});
layer.add(stickerObj);
// make the sticker image loader html element
var stickerImage = new Image();
stickerImage.onload = function() {
stickerObj.image(stickerImage);
layer.draw();
};
stickerObj.on('transformstart', function(){
undoBefore = makeUndo(this);
})
stickerObj.on('transformend', function(){
var undoAfter = makeUndo(this);
addUndo(123, undoBefore, undoAfter)
})
// assigning the URL of the image starts the onload
stickerImage.src = imgUrl;
}
imgObj = new Image();
imgObj.onload = function() {
uploadedImage.image(imgObj);
var padding = 20;
var w = imgObj.width;
var h = imgObj.height;
var targetW = stage.getWidth() - (2 * padding);
var targetH = stage.getHeight() - (2 * padding);
var widthFit = targetW / w;
var heightFit = targetH / h;
var scale = (widthFit > heightFit) ? heightFit : widthFit;
w = parseInt(w * scale, 10);
h = parseInt(h * scale, 10);
uploadedImage.size({
width: w,
height: h
});
centreRectShape(uploadedImage);
layer.draw();
}
imgObj.src = 'https://images.pexels.com/photos/787961/pexels-photo-787961.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=750&w=1260';
$('.sticker').on('click', function() {
var theSticker = addSticker($(this).attr('src'));
toggle(true);
toggle(false);
});
var vis = false;
$('#toggler').on('click', function(){
toggle(vis);
})
function undoData(opts){
this.x = opts.x;
this.y = opts.y;
this.width = opts.w;
this.height = opts.h;
this.rotation = opts.r;
}
var undoBefore;
function makeUndo(shape){
return new undoData({x:shape.getX(), y: shape.getY(), w: shape.getWidth(), h: shape.getHeight(), r: shape.getRotation() })
}
var undoList = [];
function addUndo(shapeId, before, after){
undoList.push({id: shapeId, before: before, after: after});
console.log(undoList[undoList.length - 1])
}
function toggle(isVisible){
if (!isVisible){
var shapes = stage.find('.sticker');
shapes.each(function(shape) {
var imgRotator = new Konva.Transformer({
node: shape,
name: 'stickerTransformer',
keepRatio: true,
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
});
layer.add(imgRotator);
})
vis = true;
}
else {
var shapes = stage.find('.stickerTransformer');
shapes.each(function(shape) {
shape.remove();
})
vis=false;
}
layer.draw();
$('#toggler').html((vis ? 'Toggle Off' : 'Toggle On'));
}
html,
* {
margin: 0;
padding: 0;
}
body {
background: #eee;
}
#image-editor {
background: #fff;
border-radius: 3px;
border: 1px solid #d8d8d8;
width: 650px;
margin: 0 auto;
margin-top: 20px;
box-shadow: 0 3px 5px rgba(0, 0, 0, .2);
}
.stickers {
padding: 10px 5px;
background: #eee;
}
.stickers>img {
margin-right: 10px;
}
<div id="image-editor">
<div id="canvas-container"></div>
<div class="stickers">
<img class="sticker" src="https://craftblock.me/koa/fb-upload-clone/stickers/sticker%20(1).png" alt="Sticker" width="62px">
</div>
</div>
<script src="https://unpkg.com/konva@2.4.1/konva.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
所以让我试着再解释一下这个问题:Check out the live version of my attempt of making it responsive.
如您所见,尝试将图像加载到画布后,会弹出模式但画布无法调整大小。
这是 JS:
/**
* Image Editor
*/
var stageWidth = 1000;
var stageHeight = 1000;
var stage = new Konva.Stage({
container: 'canvas-container',
width: stageWidth,
height: stageHeight
});
var layer = new Konva.Layer();
stage.add(layer);
var bgRect = new Konva.Rect({
width: stage.getWidth(),
height: stage.getHeight(),
fill: 'gold',
opacity: 0.1
});
layer.add(bgRect);
var uploadedImage = new Konva.Image({
draggable: false
});
layer.add(uploadedImage);
imgObj.onload = function () {
uploadedImage.image(imgObj);
var padding = 20;
var w = imgObj.width;
var h = imgObj.height;
var targetW = stage.getWidth() - (2 * padding);
var targetH = stage.getHeight() - (2 * padding);
var widthFit = targetW / w;
var heightFit = targetH / h;
var scale = (widthFit > heightFit) ? heightFit : widthFit;
w = parseInt(w * scale, 10);
h = parseInt(h * scale, 10);
uploadedImage.size({
width: w,
height: h
});
centreRectShape(uploadedImage);
layer.draw();
}
$('.sticker').on('click', function () {
addSticker($(this).attr('src'));
});
fitStageIntoParentContainer();
window.addEventListener('resize', fitStageIntoParentContainer);
function centreRectShape(shape) {
shape.x((stage.getWidth() - shape.getWidth()) / 2);
shape.y((stage.getHeight() - shape.getHeight()) / 2);
}
function addSticker(imgUrl) {
var stickerObj = new Konva.Image({
x: 240,
y: 20,
width: 93,
height: 104,
draggable: true
});
var stickerImage = new Image();
stickerImage.onload = function () {
stickerObj.image(stickerImage);
centreRectShape(stickerObj);
layer.draw();
};
stickerImage.src = imgUrl;
layer.add(stickerObj);
addModifiers(stickerObj);
}
function addModifiers(obj) {
var imgRotator = new Konva.Transformer({
node: obj,
keepRatio: true,
enabledAnchors: ['top-left', 'top-right', 'bottom-left', 'bottom-right']
});
layer.add(imgRotator);
}
function fitStageIntoParentContainer() {
var container = document.querySelector("edit-image-modal");
// now we need to fit stage into parent
var containerWidth = container.offsetWidth;
// to do this we need to scale the stage
var scale = containerWidth / stageWidth;
stage.width(stageWidth * scale);
stage.height(stageHeight * scale);
stage.scale({
x: scale,
y: scale
});
stage.draw();
}
【问题讨论】:
-
您发布了太多与问题无关的代码。很快有人会提到发布该问题的Minimal Complete and Verifiable Example。不过不是我。
-
@VanquiishedWombat 是真的,但有点?我会在此处添加响应式尝试(已在帖子中链接)但由于上传脚本而无法正常工作?
-
让我直截了当地说 - 我们是在谈论 konvajs 阶段没有反应吗?还是别的什么?
-
@VanquiishedWombat 上传图片后,我需要用新的画布大小重新计算画布的大小,之前它是 0,但上传图片后它是不同的大小。在我将图像添加到 imgObj.src 后,它没有反应。
-
你能检查一下那条评论吗?我觉得这不是很有意义吗?这是关于在上传图像文件后触发调整大小吗?用于在画布上定位图像?
标签: javascript jquery html canvas konvajs