Commit 3df3f038 authored by 范雪寒's avatar 范雪寒

feat: ScrollView

parent 3be0e888
...@@ -1673,10 +1673,16 @@ export function shake(item, time = 0.5, callback = null, rate = 1) { ...@@ -1673,10 +1673,16 @@ export function shake(item, time = 0.5, callback = null, rate = 1) {
} }
export enum ScrollSideType {
VERTICAL,
HORIZONTAL,
}
export class ScrollView extends MySprite { export class ScrollView extends MySprite {
content: MySprite; content: MySprite; // 内容节点
contentCanvas: any; contentCanvas: any; // 离屏渲染canvas
contentContext: any; contentContext: any; // 离屏渲染ctx
scrollSide = ScrollSideType.VERTICAL;
constructor(ctx = null) { constructor(ctx = null) {
super(ctx); super(ctx);
} }
...@@ -1684,32 +1690,124 @@ export class ScrollView extends MySprite { ...@@ -1684,32 +1690,124 @@ export class ScrollView extends MySprite {
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) { init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
super.init(imgObj, anchorX, anchorY); super.init(imgObj, anchorX, anchorY);
this.content = new MySprite(); this.contentCanvas = document.createElement("canvas");
this.content.init(imgObj, 0, 0); this.contentCanvas.id = uuidv4();
let contentCanvas = document.createElement("canvas"); this.contentContext = this.contentCanvas.getContext("2d");
contentCanvas.id = uuidv4();
this.contentCanvas = contentCanvas;
const contentContext = contentCanvas.getContext("2d"); this.content = new MySprite();
this.contentContext = contentContext; this.content.init(imgObj, 0, 0);
this.content.ctx = this.contentContext;
this.content.width = 0;
this.content.height = 0;
let scrollViewDiv = document.getElementById("scroll_view_div"); let scrollViewDiv = document.getElementById("scroll_view_div");
scrollViewDiv.appendChild(contentCanvas); scrollViewDiv.appendChild(this.contentCanvas);
} }
addContent(sprite: Sprite) { addContent(sprite: MySprite) {
this.content.addChild(sprite); this.content.addChild(sprite);
sprite.ctx = this.contentContext; sprite.ctx = this.contentContext;
sprite.anchorX = 0;
sprite.anchorY = 0;
const viewRect = this.getBoundingBox();
if (this.scrollSide == ScrollSideType.VERTICAL) {
// sprite.setScaleXY(viewRect.width / sprite.width);
} else {
// sprite.setScaleXY(viewRect.height / sprite.height);
}
if (this.scrollSide == ScrollSideType.VERTICAL) {
sprite.y = this.content.height;
} else {
sprite.x = this.content.width;
}
this.content.width = Math.max(this.content.width, this.content.width + sprite.width * sprite.scaleX);
this.content.height = Math.max(this.content.height, this.content.height + sprite.height * sprite.scaleY);
} }
drawSelf() { drawSelf() {
const rect = this.getBoundingBox();
const contentRect = this.content.getBoundingBox(); const contentRect = this.content.getBoundingBox();
const imgData = this.contentContext.getImageData(0, 0, rect.width, rect.height);
if (this.img) {
this.ctx.drawImage(this.img, this._offX, this._offY);
}
this.ctx.putImageData(imgData, rect.x, rect.y);
this.contentCanvas.width = contentRect.width;
this.contentCanvas.height = contentRect.height;
}
touchStartPos;
touchStartContentPos;
onTouchStart(x, y) {
this.touchStartPos = { x, y };
this.touchStartContentPos = { x: this.content.x, y: this.content.y };
}
onTouchMove(x, y) {
if (!this.touchStartPos) {
return;
}
if (!this.touchStartContentPos) {
return;
}
const rect = this.getBoundingBox(); const rect = this.getBoundingBox();
const imgData = this.contentContext.getImageData(contentRect.x, contentRect.y, rect.width, rect.height); if (!checkPointInRect(x, y, rect)) {
this.onTouchEnd(x, y);
return;
}
this.ctx.putImageData(imgData, this._offX, this._offY); const offsetX = x - this.touchStartPos.x;
const offsetY = y - this.touchStartPos.y;
if (this.scrollSide == ScrollSideType.VERTICAL) {
this.content.y = between(this.touchStartContentPos.y + offsetY, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.touchStartContentPos.x + offsetX, 0, this.getBoundingBox().width - this.content.width);
}
}
onTouchEnd(x, y) {
this.touchStartPos = null;
this.touchStartContentPos = null;
} }
onWheelUp(offsetY) {
if (this.scrollSide == ScrollSideType.VERTICAL) {
this.content.y = between(this.content.y + 40, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.content.x + 40, 0, this.getBoundingBox().width - this.content.width);
}
}
onWheelDown(offsetY) {
if (this.scrollSide == ScrollSideType.VERTICAL) {
this.content.y = between(this.content.y - 40, 0, this.getBoundingBox().height - this.content.height);
} else {
this.content.x = between(this.content.x - 40, 0, this.getBoundingBox().width - this.content.width);
}
}
}
export function checkPointInRect(x, y, rect) {
if (x >= rect.x && x <= rect.x + rect.width) {
if (y >= rect.y && y <= rect.y + rect.height) {
return true;
}
}
return false;
}
export function between(a, b, c) {
return [a, b, c].sort((x, y) => x - y)[1];
} }
// --------------- custom class -------------------- // --------------- custom class --------------------
......
<div class="game-container" #wrap> <div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas> <canvas id="canvas" #canvas></canvas>
</div> </div>
<div id="scroll_view_div"> <div id="scroll_view_div" style="visibility: hidden; position: fixed;">
</div> </div>
<!-- <div id="scroll_view_div">
</div> -->
\ No newline at end of file
import {Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener} from '@angular/core'; import { Component, ElementRef, ViewChild, OnInit, Input, OnDestroy, HostListener } from '@angular/core';
import { import {
Label, Label,
MySprite, ScrollView, tweenChange, MySprite, ScrollSideType, ScrollView, tweenChange,
} from './Unit'; } from './Unit';
import {res, resAudio} from './resources'; import { res, resAudio } from './resources';
import {Subject} from 'rxjs'; import { Subject } from 'rxjs';
import {debounceTime} from 'rxjs/operators'; import { debounceTime } from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js'; import TWEEN from '@tweenjs/tween.js';
...@@ -22,8 +22,8 @@ import TWEEN from '@tweenjs/tween.js'; ...@@ -22,8 +22,8 @@ import TWEEN from '@tweenjs/tween.js';
}) })
export class PlayComponent implements OnInit, OnDestroy { export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas', {static: true }) canvas: ElementRef; @ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef; @ViewChild('wrap', { static: true }) wrap: ElementRef;
// 数据 // 数据
data; data;
...@@ -80,7 +80,7 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -80,7 +80,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.data = {}; this.data = {};
// 获取数据 // 获取数据
const getData = (<any> window).courseware.getData; const getData = (<any>window).courseware.getData;
getData((data) => { getData((data) => {
if (data && typeof data == 'object') { if (data && typeof data == 'object') {
...@@ -267,6 +267,15 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -267,6 +267,15 @@ export class PlayComponent implements OnInit, OnDestroy {
addMouseListener(); addMouseListener();
addTouchListener(); addTouchListener();
element.addEventListener('mousewheel', (event) => {
setMxMyByMouse(event);
if (event.deltaY > 0) {
this.wheelDown(event);
} else {
this.wheelUp(event);
}
});
} }
...@@ -472,18 +481,40 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -472,18 +481,40 @@ export class PlayComponent implements OnInit, OnDestroy {
/** scrollViewNode;
* 初始化试图
*/
initView() { initView() {
const scrollView = new ScrollView(); const scrollView = new ScrollView();
scrollView.init(this.images.get('white')); scrollView.init(this.images.get('blue'));
scrollView.scaleX = (400 / scrollView.width); scrollView.scaleX = (400 / scrollView.width);
scrollView.scaleY = (300 / scrollView.height); scrollView.scaleY = (300 / scrollView.height);
scrollView.x = this.canvasWidth / 2;
scrollView.y = this.canvasHeight / 2;
this.renderArr.push(scrollView); this.renderArr.push(scrollView);
this.renderArr.push(scrollView.content);
// scrollView.scrollSide = ScrollSideType.HORIZONTAL;
const img = new MySprite();
img.init(this.images.get('img'));
scrollView.addContent(img);
const img2 = new MySprite();
img2.init(this.images.get('img2'));
scrollView.addContent(img2);
this.scrollViewNode = scrollView;
}
wheelUp(event: any) {
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onWheelUp(event.deltaY);
}
}
wheelDown(event: any) {
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onWheelDown(event.deltaY);
}
} }
mapDown(event) { mapDown(event) {
...@@ -491,18 +522,26 @@ export class PlayComponent implements OnInit, OnDestroy { ...@@ -491,18 +522,26 @@ export class PlayComponent implements OnInit, OnDestroy {
return; return;
} }
// if ( this.checkClickTarget(this.btnLeft) ) { if (this.checkClickTarget(this.scrollViewNode)) {
// this.btnLeftClicked(); this.scrollViewNode.onTouchStart(this.mx, this.my);
// return; return;
// } }
} }
mapMove(event) { mapMove(event) {
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onTouchMove(this.mx, this.my);
return;
} else {
this.scrollViewNode.onTouchEnd(this.mx, this.my);
}
} }
mapUp(event) { mapUp(event) {
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onTouchEnd(this.mx, this.my);
return;
}
} }
......
const res = [ const res = [
['opacity', "assets/play/opacity.png"], ['opacity', "assets/play/opacity.png"],
['blue', "assets/play/blue.png"],
['white', "assets/play/white.jpg"], ['white', "assets/play/white.jpg"],
['img', "assets/play/img.jpg"],
['img2', "assets/play/img2.jpg"],
]; ];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment