6 Commits

Author SHA1 Message Date
1bf1e1b389 Dodano funkcje przybliżania, oddalania i
przewijania planszy.
2025-11-18 22:14:09 +01:00
49f631f854 Update README.md 2025-11-15 12:22:53 +01:00
b1a2dac5e4 Merge remote-tracking branch 'origin/AndriiFunctionality' into AndriiFunctionality 2025-11-14 19:40:01 +01:00
44a52e0627 implementing functions 5,6,7,14 2025-11-14 19:39:48 +01:00
1459d4ab8d Update README.md 2025-11-14 19:38:34 +01:00
ff88da0079 first steps 2025-11-14 15:40:07 +01:00
4 changed files with 39962 additions and 164 deletions

View File

@@ -8,29 +8,29 @@ Funkcjonalności aplikacji koncentrują się na tworzeniu i modyfikacji kształt
## Funkcje:
### Kształty
1. Tworzenie prostokąta
2. Tworzenie rombu
3. Tworzenie elipsy
- [x] 1. Tworzenie prostokąta
- [x] 2. Tworzenie rombu
- [x] 3. Tworzenie elipsy
### Akcje na kształtach
4. Zmiana rozmiaru kształtów.
5. Przeciągnięcie kzstałtu po planszy
6. Usunięcie kształtu
7. Zaznaczenie kształtu
8. Kopiowanie kształtu
9. Wklejanie kształtu
10. Zmiana kolorów kształtów
11. Połączenie kształtów (strzałka ->)
12. Usunięcie kształtów
- [ ] 4. Zmiana rozmiaru kształtów.
- [x] 5. Przeciągnięcie kzstałtu po planszy
- [x] 6. Usunięcie kształtu
- [x] 7. Zaznaczenie kształtu
- [ ] 8. Kopiowanie kształtu
- [ ] 9. Wklejanie kształtu
- [ ] 10. Zmiana kolorów kształtów
- [ ] 11. Połączenie kształtów (strzałka ->)
- [ ] 12. Usunięcie kształtów
### Tekst
13. Dodanie tekstu
14. Usunięcie tekstu
- [x] 13. Dodanie tekstu
- [x] 14. Usunięcie tekstu
### Plansza i akcje na niej
15. Przybliżenie planszy
16. Oddalenie planszy
17. Przewijanie planszy
- [x] 15. Przybliżenie planszy
- [x] 16. Oddalenie planszy
- [x] 17. Przewijanie planszy
*P.S. Jak będzie brakować funkcjonalności:*
- Obracanie kształtu

View File

@@ -11,13 +11,18 @@
<body>
<div class="toolbar">
<p>Kształty</p>
<p>Kształty - przeciągnij i upuść</p>
<div class="shape-wrapper toolbar-wrapper">
<div id="shape-rectangle" class="shape" data-type="rectangle"></div>
<div id="shape-ellipse" class="shape" data-type="ellipse"></div>
<div id="shape-diamond" class="shape" data-type="diamond"></div>
<div id="shape-text" class="shape" data-type="text">Tekst</div>
</div>
<p>Zoom</p>
<div class="zoom-wrapper toolbar-wrapper">
<button id="zoom-in">+</button>
<button id="zoom-out">-</button>
</div>
</div>
<div class="canvas-container">
<div id="paper"></div>
@@ -25,154 +30,273 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.2/jquery-ui.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@joint/core@4.0.1/dist/joint.js"></script>
<script src="joint.js"></script>
<script>
$(document).ready(function () {
//init paper - Start
const graph = new joint.dia.Graph();
const paper = new joint.dia.Paper({
el: $('#paper'),
model: graph,
width: window.innerWidth,
height: window.innerHeight,
gridSize: 20,
});
//init paper - END
let selectedElement = null;
let activeElementView = null;
//create shape - START
function createRectangle(paperX, paperY) {
const rect = new joint.shapes.standard.Rectangle({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
}
function createDiamond(paperX, paperY) {
const rect = new joint.shapes.standard.Rectangle({
position: { x: paperX - 24, y: paperY - 24 },
size: { width: 48, height: 48 },
angle: 45,
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
}
function createEllipse(paperX, paperY) {
const rect = new joint.shapes.standard.Ellipse({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
}
function createText(paperX, paperY) {
const textBlock = new joint.shapes.standard.TextBlock({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1,
strokeDasharray: '5,5'
},
label: {
text: 'Tekst...',
fill: '#000000'
}
}
});
graph.addCell(textBlock);
}
//create shape - END
//init draggalble - START
$('.shape').draggable({
helper: function () {
const $clone = $(this).clone();
$clone.css({
opacity: 0.8,
cursor: 'grabbing',
borderColor: '#000',
color: '#000',
});
return $clone;
},
cursor: 'move',
revert: 'invalid',
appendTo: 'body',
zIndex: 1000
});
$('#paper').droppable({
accept: '.shape',
drop: function (event, ui) {
const shapeType = ui.helper.data('type');
const containerOffset = $(this).offset();
const x = event.pageX - containerOffset.left;
const y = event.pageY - containerOffset.top;
const scale = paper.scale();
const translate = paper.translate();
const paperX = (x - translate.tx) / scale.sx;
const paperY = (y - translate.ty) / scale.sy;
if (shapeType === 'rectangle') {
createRectangle(paperX, paperY);
} else if (shapeType === 'ellipse') {
createEllipse(paperX, paperY);
} else if (shapeType === 'diamond') {
createDiamond(paperX, paperY);
} else if (shapeType === 'text') {
createText(paperX, paperY);
}
}
});
//init draggable - END
//add text to text block - START
paper.on('element:pointerdblclick', function (elementView) {
if (elementView.model.attributes.type === 'standard.TextBlock') {
const currentText = elementView.model.attr('label/text');
const newText = prompt('Edytuj tekst:', currentText);
if (newText != null) {
elementView.model.attr('label/text', newText);
}
}
});
//add text to text block - END
$(document).ready(function () {
//init paper - Start
const graph = new joint.dia.Graph();
const paper = new joint.dia.Paper({
el: $('#paper'),
model: graph,
width: window.innerWidth,
height: window.innerHeight,
gridSize: 20,
});
//init paper - END
// obwódka i znaczek usuwanie
function createToolsView() {
return new joint.dia.ToolsView({
tools: [
new joint.elementTools.Boundary({
padding: 10,
}),
new joint.elementTools.Remove({
focusOpacity: 0.5,
})
]
});
}
//create shape - START
function createRectangle(paperX, paperY) {
const rect = new joint.shapes.standard.Rectangle({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
const elementView = rect.findView(paper);
elementView.addTools(createToolsView());
}
function createDiamond(paperX, paperY) {
const rect = new joint.shapes.standard.Rectangle({
position: { x: paperX - 24, y: paperY - 24 },
size: { width: 48, height: 48 },
angle: 45,
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
const elementView = rect.findView(paper);
elementView.addTools(createToolsView());
}
function createEllipse(paperX, paperY) {
const rect = new joint.shapes.standard.Ellipse({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1
},
label: {
text: ''
}
}
});
graph.addCell(rect);
const elementView = rect.findView(paper);
elementView.addTools(createToolsView());
}
function createText(paperX, paperY) {
const textBlock = new joint.shapes.standard.TextBlock({
position: { x: paperX - 40, y: paperY - 24 },
size: { width: 80, height: 48 },
attrs: {
body: {
fill: 'transparent',
stroke: '#000000',
strokeWidth: 1,
strokeDasharray: '5,5'
},
label: {
text: 'Tekst...',
fill: '#000000'
}
}
});
graph.addCell(textBlock);
const elementView = textBlock.findView(paper);
elementView.addTools(createToolsView());
}
//create shape - END
//init draggalble - START
$('.shape').draggable({
helper: function () {
const $clone = $(this).clone();
$clone.css({
opacity: 0.8,
cursor: 'grabbing',
borderColor: '#000',
color: '#000',
});
return $clone;
},
cursor: 'move',
revert: 'invalid',
appendTo: 'body',
zIndex: 1000
});
$('#paper').droppable({
accept: '.shape',
drop: function (event, ui) {
const shapeType = ui.helper.data('type');
const containerOffset = $(this).offset();
const x = event.pageX - containerOffset.left;
const y = event.pageY - containerOffset.top;
const scale = paper.scale();
const translate = paper.translate();
const paperX = (x - translate.tx) / scale.sx;
const paperY = (y - translate.ty) / scale.sy;
activeElementView = null;
selectedElement = null;
if (shapeType === 'rectangle') {
createRectangle(paperX, paperY);
} else if (shapeType === 'ellipse') {
createEllipse(paperX, paperY);
} else if (shapeType === 'diamond') {
createDiamond(paperX, paperY);
} else if (shapeType === 'text') {
createText(paperX, paperY);
}
const cells = graph.getCells();
if (cells.length > 0) {
const lastCell = cells[cells.length - 1];
const lastView = lastCell.findView(paper);
if (lastView && typeof lastView.hideTools === 'function') {
lastView.hideTools();
}
}
}
});
//init draggable - END
paper.on('element:pointerclick', function (elementView) {
if (activeElementView && activeElementView !== elementView) {
activeElementView.hideTools();
}
elementView.showTools();
activeElementView = elementView;
selectedElement = elementView.model;
});
let panStart = null;
paper.on('blank:pointerdown', function (evt) {
if (activeElementView) {
if (typeof activeElementView.hideTools === 'function') {
activeElementView.hideTools();
}
if (typeof activeElementView.unhighlight === 'function') {
activeElementView.unhighlight();
}
activeElementView = null;
}
selectedElement = null;
//ruszanie caloscia
panStart = {
x: evt.clientX,
y: evt.clientY,
tx: paper.translate().tx,
ty: paper.translate().ty
};
paper.$el.css('cursor', 'grabbing');
});
$(document).on('mousemove', function (evt) {
if (panStart) {
const dx = evt.clientX - panStart.x;
const dy = evt.clientY - panStart.y;
paper.translate(panStart.tx + dx, panStart.ty + dy);
}
});
$(document).on('mouseup', function () {
if (panStart) {
panStart = null;
paper.$el.css('cursor', 'default');
}
});
//add text to text block - START
paper.on('element:pointerdblclick', function (elementView) {
if (elementView.model.attributes.type === 'standard.TextBlock') {
const currentText = elementView.model.attr('label/text');
const newText = prompt('Edytuj tekst:', currentText);
if (newText != null) {
elementView.model.attr('label/text', newText);
}
}
});
$(document).on('keydown', function (e) {
if (e.key === 'Delete' && selectedElement) {
// if (selectedElement.attributes.type === 'standard.TextBlock') {
selectedElement.remove();
selectedElement = null;
// }
}
});
//add text to text block - END
// Zoom
const zoomStep = 0.2;
const minScale = 0.2;
const maxScale = 3.0;
$('#zoom-in').click(function () {
const currentScale = paper.scale().sx;
const newScale = Math.min(maxScale, currentScale + zoomStep);
paper.scale(newScale, newScale);
});
$('#zoom-out').click(function () {
const currentScale = paper.scale().sx;
const newScale = Math.max(minScale, currentScale - zoomStep);
paper.scale(newScale, newScale);
});
// Zoom za pomoca kolka myszy
paper.on('blank:mousewheel cell:mousewheel', function (evt, x, y, delta) {
evt.preventDefault();
const oldScale = paper.scale().sx;
const zoomFactor = 0.2;
let newScale = oldScale * (1 + delta * zoomFactor);
newScale = Math.max(minScale, Math.min(maxScale, newScale));
paper.scale(newScale, newScale, x, y);
});
});
</script>
</body>

39629
joint.js Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -44,6 +44,7 @@
.shape {
background: transparent;
border: 1px solid white;
cursor: pointer;
}
.toolbar {
@@ -68,4 +69,48 @@
.toolbar-wrapper {
padding-bottom: 30px;
padding: 20px;
}
}
.zoom-wrapper {
display: flex;
justify-content: center;
gap: 15px;
padding: 10px 20px !important;
}
.zoom-wrapper button {
background: white;
color: #3498db;
border: none;
border-radius: 50%;
width: 50px;
height: 50px;
font-size: 24px;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
box-shadow: 0 4px 10px rgba(0, 0, 0, 0.15);
transition: all 0.3s ease;
outline: none;
}
.zoom-wrapper button:hover {
background: #2980b9;
color: white;
transform: scale(1.1);
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.25);
}
.zoom-wrapper button:active {
transform: scale(0.95);
}
/* Fajny efekt przy najechaniu */
.zoom-wrapper button i {
transition: transform 0.3s ease;
}
.zoom-wrapper button:hover i {
transform: scale(1.2);
}