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) {
}
export enum ScrollSideType {
VERTICAL,
HORIZONTAL,
}
export class ScrollView extends MySprite {
content: MySprite;
contentCanvas: any;
contentContext: any;
content: MySprite; // 内容节点
contentCanvas: any; // 离屏渲染canvas
contentContext: any; // 离屏渲染ctx
scrollSide = ScrollSideType.VERTICAL;
constructor(ctx = null) {
super(ctx);
}
......@@ -1684,32 +1690,124 @@ export class ScrollView extends MySprite {
init(imgObj = null, anchorX: number = 0.5, anchorY: number = 0.5) {
super.init(imgObj, anchorX, anchorY);
this.content = new MySprite();
this.content.init(imgObj, 0, 0);
this.contentCanvas = document.createElement("canvas");
this.contentCanvas.id = uuidv4();
let contentCanvas = document.createElement("canvas");
contentCanvas.id = uuidv4();
this.contentCanvas = contentCanvas;
this.contentContext = this.contentCanvas.getContext("2d");
const contentContext = contentCanvas.getContext("2d");
this.contentContext = contentContext;
this.content = new MySprite();
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");
scrollViewDiv.appendChild(contentCanvas);
scrollViewDiv.appendChild(this.contentCanvas);
}
addContent(sprite: Sprite) {
addContent(sprite: MySprite) {
this.content.addChild(sprite);
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() {
const rect = this.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 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 --------------------
......
<div class="game-container" #wrap>
<canvas id="canvas" #canvas></canvas>
</div>
<div id="scroll_view_div">
<div id="scroll_view_div" style="visibility: hidden; position: fixed;">
</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 {
Label,
MySprite, ScrollView, tweenChange,
MySprite, ScrollSideType, ScrollView, tweenChange,
} from './Unit';
import {res, resAudio} from './resources';
import { res, resAudio } from './resources';
import {Subject} from 'rxjs';
import {debounceTime} from 'rxjs/operators';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import TWEEN from '@tweenjs/tween.js';
......@@ -22,8 +22,8 @@ import TWEEN from '@tweenjs/tween.js';
})
export class PlayComponent implements OnInit, OnDestroy {
@ViewChild('canvas', {static: true }) canvas: ElementRef;
@ViewChild('wrap', {static: true }) wrap: ElementRef;
@ViewChild('canvas', { static: true }) canvas: ElementRef;
@ViewChild('wrap', { static: true }) wrap: ElementRef;
// 数据
data;
......@@ -80,7 +80,7 @@ export class PlayComponent implements OnInit, OnDestroy {
this.data = {};
// 获取数据
const getData = (<any> window).courseware.getData;
const getData = (<any>window).courseware.getData;
getData((data) => {
if (data && typeof data == 'object') {
......@@ -267,6 +267,15 @@ export class PlayComponent implements OnInit, OnDestroy {
addMouseListener();
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 {
/**
* 初始化试图
*/
scrollViewNode;
initView() {
const scrollView = new ScrollView();
scrollView.init(this.images.get('white'));
scrollView.init(this.images.get('blue'));
scrollView.scaleX = (400 / scrollView.width);
scrollView.scaleY = (300 / scrollView.height);
scrollView.x = this.canvasWidth / 2;
scrollView.y = this.canvasHeight / 2;
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) {
......@@ -491,18 +522,26 @@ export class PlayComponent implements OnInit, OnDestroy {
return;
}
// if ( this.checkClickTarget(this.btnLeft) ) {
// this.btnLeftClicked();
// return;
// }
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onTouchStart(this.mx, this.my);
return;
}
}
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) {
if (this.checkClickTarget(this.scrollViewNode)) {
this.scrollViewNode.onTouchEnd(this.mx, this.my);
return;
}
}
......
const res = [
['opacity', "assets/play/opacity.png"],
['blue', "assets/play/blue.png"],
['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