javascript - 如何将指针事件沿层堆栈中的对象冒泡?
问题描述
fabric.Object.prototype.objectCaching = false;
var canvasBackground = new fabric.Canvas('backgroundcanvas');
var canvas = new fabric.Canvas('paintcanvas');
var canvas_2 = new fabric.Canvas('paintcanvas_2');
var canvas_3 = new fabric.Canvas('paintcanvas_3');
var canvas_4 = new fabric.Canvas('paintcanvas_4');
fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_01.png', function(myImg) {
var img1 = myImg.set({
top: 0,
left: 0,
scaleX: canvas.width/myImg.width,
scaleY: canvas.height/myImg.height,
selectable : false,
evented: false
});
canvas.add(img1);
});
fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
var img1 = myImg.set({
top: 20,
left: 20,
width: 300,
height: 300,
globalCompositeOperation: 'source-atop'
});
canvas.add(img1);
});
fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_02.png', function(myImg) {
var img1 = myImg.set({
top: 0,
left: 0,
scaleX: canvas.width/myImg.width,
scaleY: canvas.height/myImg.height,
selectable : false,
evented: false
});
canvas_2.add(img1);
});
fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
var img1 = myImg.set({
top: 20,
left: 420,
width: 300,
height: 300,
globalCompositeOperation: 'source-atop'
});
canvas_2.add(img1);
});
fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_03.png', function(myImg) {
var img1 = myImg.set({
top: 0,
left: 0,
scaleX: canvas.width/myImg.width,
scaleY: canvas.height/myImg.height,
selectable : false,
evented: false
});
canvas_3.add(img1);
});
fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
var img1 = myImg.set({
top: 220,
left: 220,
width: 300,
height: 300,
globalCompositeOperation: 'source-atop'
});
canvas_3.add(img1);
});
fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy_04.png', function(myImg) {
var img1 = myImg.set({
top: 0,
left: 0,
scaleX: canvas.width/myImg.width,
scaleY: canvas.height/myImg.height,
selectable : false,
evented: false
});
canvas_4.add(img1);
});
fabric.Image.fromURL('https://beautymode.fr/wp-content/uploads/2017/09/636096742373357996142416222_fashion-beauty-tips.jpg', function(myImg) {
var img1 = myImg.set({
top: 420,
left: 420,
width: 300,
height: 300,
globalCompositeOperation: 'source-atop'
});
canvas_4.add(img1);
});
fabric.Image.fromURL('https://dev.loversloc.com/media/collection/templates/confetti_easy.png', function(myImg) {
var img1 = myImg.set({
globalCompositeOperation: 'destination-over',
top: 0,
left: 0,
scaleX: canvasBackground.width/myImg.width,
scaleY: canvasBackground.height/myImg.height,
selectable : false,
evented: false
});
canvasBackground.add(img1);
});
var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');
var $con_3 = $('.paintcanvas_3');
var $con_4 = $('.paintcanvas_4');
canvas.on({
'mouse:move': function(e) {
if (e.target) {
$con_2.css('pointer-events',/*!*/'none');
} else {
$con_2.css('pointer-events',/*!*/'all');
}
},
});
canvas_2.on({
'mouse:move': function(e) {
if (e.target) {
$con_2.css('pointer-events',/*!*/'all');
} else {
$con_2.css('pointer-events',/*!*/'none');
}
}
});
canvas_3.on({
'mouse:move': function(e) {
if (e.target) {
$con_4.css('pointer-events',/*!*/'none');
} else {
$con_4.css('pointer-events',/*!*/'all');
}
}
});
canvas_4.on({
'mouse:move': function(e) {
if (e.target) {
$con_4.css('pointer-events',/*!*/'all');
} else {
$con_4.css('pointer-events',/*!*/'none');
}
}
});
.parent {
position: relative;
background: black;
}
.backgroundcanvas {
position: absolute;
left: 0;
top: 0;
}
.paintcanvas, .paintcanvas_2, .paintcanvas_3, .paintcanvas_4 {
position: absolute;
left: 0px;
top: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<div class="parent">
<script
src="https://code.jquery.com/jquery-3.4.1.min.js"
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo="
crossorigin="anonymous"></script>
<div class="backgroundcanvas">
<canvas id="backgroundcanvas" width="800" height="800"></canvas>
</div>
<div class="paintcanvas">
<canvas id="paintcanvas" width="800" height="800" ></canvas>
</div>
<div class="paintcanvas_2">
<canvas id="paintcanvas_2" width="800" height="800" ></canvas>
</div>
<div class="paintcanvas_3">
<canvas id="paintcanvas_3" width="800" height="800" ></canvas>
</div>
<div class="paintcanvas_4">
<canvas id="paintcanvas_4" width="800" height="800" ></canvas>
</div>
</div>
我设法在一堆画布中创建了几个蒙面画布元素。这些每个都带有经过globalCompositeOperation
处理的掩码,用户应该能够将照片上传到该掩码中。
现在,每个上传的图像元素都应该在每个画布中都可以移动/缩放。我尝试通过冒泡的指针事件来实现这一点。
我这样做是因为您不能在一个画布中独立屏蔽多个重叠元素(屏蔽会影响所有像素),并且由于底层设计和性能,svg 是不可能的。因为“destination-over”在这种组合中不起作用,所以背景被排除在静态画布中。
使用两层/画布可以这样解决:
var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');
canvas_1.on({
'mouse:move': function(e) {
if (e.target) {
$con_1.css('pointer-events',/*!*/'all');
} else {
$con_1.css('pointer-events',/*!*/'none');
}
}
});
canvas_2.on({
'mouse:move': function(e) {
if (e.target) {
$con_2.css('pointer-events',/*!*/'none');
} else {
$con_2.css('pointer-events',/*!*/'all');
}
}
});
但是,我需要四层,并且不明白如何将事件冒泡。
我在这里为此创建了一个小提琴(画布内容 3+4 可编辑): https ://jsfiddle.net/Metamagikum/2Lpwchzd/199/
解决方案
我是这样解决的。它正在工作,但仍在寻找更好的解决方案。
var $con_1 = $('.paintcanvas');
var $con_2 = $('.paintcanvas_2');
var $con_3 = $('.paintcanvas_3');
var $con_4 = $('.paintcanvas_4');
canvas.on({
'mouse:move': function(e) {
if (e.target) {
$con_1.css('pointer-events',/*!*/'all');
} else {
$con_2.css('pointer-events',/*!*/'all');
$con_3.css('pointer-events',/*!*/'all');
$con_4.css('pointer-events',/*!*/'all');
}
},
});
canvas_2.on({
'mouse:move': function(e) {
if (e.target) {
$con_2.css('pointer-events',/*!*/'all');
} else {
$con_2.css('pointer-events',/*!*/'none');
}
}
});
canvas_3.on({
'mouse:move': function(e) {
if (e.target) {
$con_3.css('pointer-events',/*!*/'all');
} else {
$con_3.css('pointer-events',/*!*/'none');
}
}
});
canvas_4.on({
'mouse:move': function(e) {
if (e.target) {
$con_4.css('pointer-events',/*!*/'all');
} else {
$con_4.css('pointer-events',/*!*/'none');
}
}
});
推荐阅读
- shell - How to use data of curl -v?
- react-native - 如何映射在 react-native 中进行 Api 调用时返回的数据
- javascript - Decrypt data using CryptoJs
- java - 如何将控制器中的 RequestBody 定义为列表,我收到 500 错误
- mysql - 如何从工作台 SQL 导出和导入数据库
- swagger - how to add Authorization header by using open api swagger doc
- xcode - error while trying to get build ios using xcode
- vba - Word VBA Progress Bar with Unknown Number of Steps
- python - Python 配置文件:如何获取每个单独执行的时间(无聚合)
- python - 如果键多次出现而不导入,如何更新python字典中的值?