<!DOCTYPE html> <html> <head> <script src="https://unpkg.com/konva@9.3.18/konva.min.js"></script> <meta charset="utf-8" /> <title>Konva Load Complex Stage Demo</title> <style> body { margin: 0; padding: 0; overflow: hidden; background-color: #f0f0f0; } </style> </head> <body> <button id="create-yoda">Create yoda</button> <button id="create-darth">Create darth</button> <button id="undo">Undo</button> <button id="redo">Redo</button> <div id="container"></div> <script> var possibleFilters = ['', 'blur', 'invert'];
function createObject(attrs) { return Object.assign({}, attrs, { x: 0, y: 0, src: '', filter: 'blur', }); } function createYoda(attrs) { return Object.assign(createObject(attrs), { src: '/assets/yoda.jpg', }); }
function createDarth(attrs) { return Object.assign(createObject(attrs), { src: '/assets/darth-vader.jpg', }); }
var state = [createYoda({ x: 50, y: 50 })];
var appHistory = [state]; var appHistoryStep = 0;
var width = window.innerWidth; var height = window.innerHeight; var stage = new Konva.Stage({ container: 'container', width: width, height: height, });
var layer = new Konva.Layer(); stage.add(layer);
function create() { layer.destroyChildren(); state.forEach((item, index) => { var node = new Konva.Image({ draggable: true, name: 'item-' + index, scaleX: 0.5, scaleY: 0.5, }); layer.add(node); node.on('dragend', () => { state = state.slice(); state[index] = Object.assign({}, state[index], { x: node.x(), y: node.y(), }); saveStateToHistory(state); });
node.on('click', () => { var oldFilterIndex = possibleFilters.indexOf(state[index].filter); var nextIndex = (oldFilterIndex + 1) % possibleFilters.length; var filter = possibleFilters[nextIndex];
state = state.slice(); state[index] = Object.assign({}, state[index], { filter: filter, }); saveStateToHistory(state); update(state); });
var img = new window.Image(); img.onload = function () { node.image(img); update(state); }; img.src = item.src; }); update(state); }
function update() { state.forEach(function (item, index) { var node = stage.findOne('.item-' + index); node.setAttrs({ x: item.x, y: item.y, });
if (!node.image()) { return; } if (item.filter === 'blur') { node.filters([Konva.Filters.Blur]); node.blurRadius(10); node.cache(); } else if (item.filter === 'invert') { node.filters([Konva.Filters.Invert]); node.cache(); } else { node.filters([]); node.clearCache(); } }); }
function saveStateToHistory(state) { appHistory = appHistory.slice(0, appHistoryStep + 1); appHistory = appHistory.concat([state]); appHistoryStep += 1; } create(state);
document .querySelector('#create-yoda') .addEventListener('click', function () { state.push( createYoda({ x: width * Math.random(), y: height * Math.random(), }) ); create(state); });
document .querySelector('#create-darth') .addEventListener('click', function () { state.push( createDarth({ x: width * Math.random(), y: height * Math.random(), }) ); create(state); });
document.querySelector('#undo').addEventListener('click', function () { if (appHistoryStep === 0) { return; } appHistoryStep -= 1; state = appHistory[appHistoryStep]; create(state); });
document.querySelector('#redo').addEventListener('click', function () { if (appHistoryStep === appHistory.length - 1) { return; } appHistoryStep += 1; state = appHistory[appHistoryStep]; create(state); }); </script> </body> </html>
|